diff --git a/armsrc/Makefile b/armsrc/Makefile index 3c2219b96..5625507e5 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -81,6 +81,12 @@ else SRC_LCD = endif +ifneq (,$(findstring WITH_ZX8211,$(APP_CFLAGS))) + SRC_ZX = lfxz.c +else + SRC_ZX = +endif + # Generic standalone Mode injection of source code include Standalone/Makefile.inc @@ -122,6 +128,7 @@ THUMBSRC = start.c \ $(SRC_CRC) \ $(SRC_FELICA) \ $(SRC_STANDALONE) \ + $(SRC_ZX) \ appmain.c \ printf.c \ dbprint.c \ diff --git a/armsrc/appmain.c b/armsrc/appmain.c index f27b4a2fa..71254684b 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -48,6 +48,7 @@ #include "ticks.h" #include "commonutil.h" #include "crc16.h" +#include "zx8211.h" #ifdef WITH_LCD @@ -541,6 +542,13 @@ static void SendCapabilities(void) { #else capabilities.compiled_with_lcd = false; #endif + +#ifdef WITH_ZX8211 + capabilities.compiled_with_zx8211 = true; +#else + capabilities.compiled_with_zx8211 = false; +#endif + reply_ng(CMD_CAPABILITIES, PM3_SUCCESS, (uint8_t *)&capabilities, sizeof(capabilities)); } @@ -1196,6 +1204,17 @@ static void PacketReceived(PacketCommandNG *packet) { } #endif +#ifdef WITH_ZX8211 + case CMD_LF_ZX_READ: { + zx8211_read((zx8211_data_t *)packet->data.asBytes, true); + break; + } + case CMD_LF_ZX_WRITE: { + zx8211_write((zx8211_data_t *)packet->data.asBytes, true); + break; + } +#endif + #ifdef WITH_ISO15693 case CMD_HF_ISO15693_ACQ_RAW_ADC: { AcquireRawAdcSamplesIso15693(); diff --git a/armsrc/lfzx.c b/armsrc/lfzx.c new file mode 100644 index 000000000..79f336e4f --- /dev/null +++ b/armsrc/lfzx.c @@ -0,0 +1,24 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2021 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. +//----------------------------------------------------------------------------- +// Low frequency ZX8211 funtions +//----------------------------------------------------------------------------- +#ifndef __LFOPS_H +#define __LFOPS_H + +#include "lfzx.h" +#include "pm3_cmd.h" // struct + +int zx8211_read(zx8211_data_t *zxd, bool ledcontrol) { + return PM3_SUCCESS; +} + +int zx8211_write(zx8211_data_t *zxd, bool ledcontrol) { + return PM3_SUCCESS; +} + +#endif \ No newline at end of file diff --git a/armsrc/lfzx.h b/armsrc/lfzx.h new file mode 100644 index 000000000..d7c4c94f9 --- /dev/null +++ b/armsrc/lfzx.h @@ -0,0 +1,20 @@ +//----------------------------------------------------------------------------- +// Copyright (C) 2021 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. +//----------------------------------------------------------------------------- +// Low frequency ZX8211 funtions +//----------------------------------------------------------------------------- +#ifndef __LFOPS_H +#define __LFOPS_H + +#include "common.h" +#include "pm3_cmd.h" // struct + + +int zx8211_read(zx8211_data_t *zxd, bool ledcontrol); +int zx8211_write(zx8211_data_t *zxd, bool ledcontrol); + +#endif \ No newline at end of file diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index ec11a3c04..32dcff5d0 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -304,6 +304,7 @@ set (TARGET_SOURCES ${PM3_ROOT}/client/src/cmdlfti.c ${PM3_ROOT}/client/src/cmdlfviking.c ${PM3_ROOT}/client/src/cmdlfvisa2000.c + ${PM3_ROOT}/client/src/cmdlfzx8211.c ${PM3_ROOT}/client/src/cmdmain.c ${PM3_ROOT}/client/src/cmdnfc.c ${PM3_ROOT}/client/src/cmdparser.c diff --git a/client/Makefile b/client/Makefile index 28b0721b8..94b5afdae 100644 --- a/client/Makefile +++ b/client/Makefile @@ -556,6 +556,7 @@ SRCS = mifare/aiddesfire.c \ cmdlfti.c \ cmdlfviking.c \ cmdlfvisa2000.c \ + cmdlfzx8211.c \ cmdmain.c \ cmdnfc.c \ cmdparser.c \ diff --git a/client/src/cmdlf.c b/client/src/cmdlf.c index 8da5e5dcd..36c98c6f0 100644 --- a/client/src/cmdlf.c +++ b/client/src/cmdlf.c @@ -58,6 +58,7 @@ #include "cmdlfti.h" // for ti menu #include "cmdlfviking.h" // for viking menu #include "cmdlfvisa2000.h" // for VISA2000 menu +#include "cmdlfzx8211.h" // for ZX8211 menu #include "crc.h" #include "pm3_cmd.h" // for LF_CMDREAD_MAX_EXTRA_SYMBOLS @@ -1825,6 +1826,7 @@ static command_t CommandTable[] = { {"t55xx", CmdLFT55XX, AlwaysAvailable, "{ T55xx CHIPs... }"}, {"viking", CmdLFViking, AlwaysAvailable, "{ Viking RFIDs... }"}, {"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"}, + {"zx", CmdLFZx8211, AlwaysAvailable, "{ ZX8211 RFIDs... }"}, {"-----------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"}, {"config", CmdLFConfig, IfPm3Lf, "Get/Set config for LF sampling, bit/sample, decimation, frequency"}, {"cmdread", CmdLFCommandRead, IfPm3Lf, "Modulate LF reader field to send command before read"}, diff --git a/client/src/cmdlfzx8211.c b/client/src/cmdlfzx8211.c new file mode 100644 index 000000000..bd1af996f --- /dev/null +++ b/client/src/cmdlfzx8211.c @@ -0,0 +1,154 @@ +//----------------------------------------------------------------------------- +// +// 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 ZX8211 tag commands +// by iceman, doegox +//----------------------------------------------------------------------------- + +#include "cmdlfzx8211.h" +#include +#include +#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 +#include "cmdlfem4x05.h" // +#include "cliparser.h" + +static int CmdHelp(const char *Cmd); + +//see ASKDemod for what args are accepted +int demodzx(bool verbose) { + (void) verbose; // unused so far + save_restoreGB(GRAPH_SAVE); + + //CmdAskEdgeDetect(""); + + //ASK / Manchester + bool st = true; + if (ASKDemod_ext(64, 0, 0, 0, false, false, false, 1, &st) != PM3_SUCCESS) { + PrintAndLogEx(DEBUG, "DEBUG: Error - ZX: ASK/Manchester Demod failed"); + save_restoreGB(GRAPH_RESTORE); + return PM3_ESOFT; + } + size_t size = g_DemodBufferLen; + int ans = detectzx(g_DemodBuffer, &size); + if (ans < 0) { + if (ans == -1) + PrintAndLogEx(DEBUG, "DEBUG: Error - ZX: too few bits found"); + else if (ans == -2) + PrintAndLogEx(DEBUG, "DEBUG: Error - ZX: preamble not found"); + else if (ans == -3) + PrintAndLogEx(DEBUG, "DEBUG: Error - ZX: Size not correct: %zu", size); + else + PrintAndLogEx(DEBUG, "DEBUG: Error - ZX: ans: %d", ans); + + save_restoreGB(GRAPH_RESTORE); + return PM3_ESOFT; + } + setDemodBuff(g_DemodBuffer, 96, ans); + setClockGrid(g_DemodClock, g_DemodStartIdx + (ans * g_DemodClock)); + + //got a good demod + uint32_t raw1 = bytebits_to_byte(g_DemodBuffer, 32); + + // chksum + + // test checksums + + PrintAndLogEx(SUCCESS, "ZX8211 - Card " _GREEN_("%u") ", Raw: %08X", raw1); + return PM3_SUCCESS; +} + +static int lf_Zx_read(void) { + return PM3_SUCCESS; +} + +static int CmdZxDemod(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf zx demod", + "Try to find zx8211 preamble, if found decode / descramble data", + "lf zx demod" + ); + + void *argtable[] = { + arg_param_begin, + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + CLIParserFree(ctx); + return demodzx(true); +} + +static int CmdzxReader(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "lf zx reader", + "read a zx tag", + "lf zx reader -@ -> continuous reader mode" + ); + + void *argtable[] = { + arg_param_begin, + arg_lit0("@", NULL, "optional - continuous reader mode"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); + bool cm = arg_get_lit(ctx, 1); + CLIParserFree(ctx); + + if (cm) { + PrintAndLogEx(INFO, "Press " _GREEN_("") " to exit"); + } + + do { + lf_Zx_read(); + demodzx(!cm); + } while (cm && !kbd_enter_pressed()); + return PM3_SUCCESS; +} + + +static command_t CommandTable[] = { + {"help", CmdHelp, AlwaysAvailable, "This help"}, + {"demod", CmdZxDemod, AlwaysAvailable, "demodulate an ZX 8211 tag from the GraphBuffer"}, + {"reader", CmdzxReader, IfPm3Lf, "attempt to read and extract tag data"}, + {NULL, NULL, NULL, NULL} +}; + +static int CmdHelp(const char *Cmd) { + (void)Cmd; // Cmd is not used so far + CmdsHelp(CommandTable); + return PM3_SUCCESS; +} + +int CmdLFZx8211(const char *Cmd) { + clearCommandBuffer(); + return CmdsParse(CommandTable, Cmd); +} + +// find Visa2000 preamble in already demoded data +int detectzx(uint8_t *dest, size_t *size) { + if (*size < 96) return -1; //make sure buffer has data + size_t startIdx = 0; + uint8_t preamble[] = {0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 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; +} + + diff --git a/client/src/cmdlfzx8211.h b/client/src/cmdlfzx8211.h new file mode 100644 index 000000000..4160de267 --- /dev/null +++ b/client/src/cmdlfzx8211.h @@ -0,0 +1,20 @@ +//----------------------------------------------------------------------------- +// +// 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 ZX8211 commands +//----------------------------------------------------------------------------- +#ifndef CMDLFZX8211_H__ +#define CMDLFZX8211_H__ + +#include "common.h" + +int CmdLFZx8211(const char *Cmd); + +int demodzx(bool verbose); +int detectzx(uint8_t *dest, size_t *size); + +#endif + diff --git a/common_arm/Makefile.hal b/common_arm/Makefile.hal index d18615278..15dd78686 100644 --- a/common_arm/Makefile.hal +++ b/common_arm/Makefile.hal @@ -122,6 +122,9 @@ endif ifneq ($(SKIP_EM4x70),1) PLATFORM_DEFS += -DWITH_EM4x70 endif +ifneq ($(SKIP_ZX8211),1) + PLATFORM_DEFS += -DWITH_ZX8211 +endif # common HF support ifneq ($(SKIP_ISO15693),1) diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index 8026b0b7f..d7711ea62 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -181,6 +181,7 @@ typedef struct { bool compiled_with_hitag : 1; bool compiled_with_em4x50 : 1; bool compiled_with_em4x70 : 1; + bool compiled_with_xc8211 : 1; // hf bool compiled_with_hfsniff : 1; bool compiled_with_hfplot : 1; @@ -198,7 +199,7 @@ typedef struct { bool hw_available_flash : 1; bool hw_available_smartcard : 1; } PACKED capabilities_t; -#define CAPABILITIES_VERSION 5 +#define CAPABILITIES_VERSION 6 extern capabilities_t g_pm3_capabilities; // For CMD_LF_T55XX_WRITEBL