From f8514f48d7ab88fb5a4a1cc52b1daf66da674415 Mon Sep 17 00:00:00 2001 From: Yann GASCUEL <34003959+lnv42@users.noreply.github.com> Date: Thu, 18 Jan 2024 11:28:27 +0100 Subject: [PATCH] standalone: add HF_15SIM Standalone mode code source Also add it into documentation and build_all_firmwares.sh (standalone mode was added in Standalone Makefiles in a previous commit) --- armsrc/Standalone/hf_15sim.c | 203 ++++++++++++++++++ .../4_Advanced-compilation-parameters.md | 1 + tools/build_all_firmwares.sh | 2 +- 3 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 armsrc/Standalone/hf_15sim.c diff --git a/armsrc/Standalone/hf_15sim.c b/armsrc/Standalone/hf_15sim.c new file mode 100644 index 000000000..46debe0e0 --- /dev/null +++ b/armsrc/Standalone/hf_15sim.c @@ -0,0 +1,203 @@ +//----------------------------------------------------------------------------- +// Copyright (C) lnv42 2024 +// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. +// +// 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 3 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. +// +// See LICENSE.txt for the text of the license. +//----------------------------------------------------------------------------- +// Main code for standalone HF/iso15693 Simulation +// This code is trying to dump an iso15 tag, then simulate it +// It doesn't support any password protected/authenticated features +//----------------------------------------------------------------------------- + +#include "standalone.h" // standalone definitions +#include "proxmark3_arm.h" +#include "fpgaloader.h" +#include "iso15693.h" +#include "iso15.h" +#include "protocols.h" +#include "iso15693tools.h" +#include "util.h" +#include "spiffs.h" +#include "appmain.h" +#include "dbprint.h" +#include "ticks.h" +#include "BigBuf.h" +#include "crc16.h" + +#define AddCrc15(data, len) compute_crc(CRC_15693, (data), (len), (data)+(len), (data)+(len)+1) +//#define CalculateCrc15(data, len) Crc16ex(CRC_15693, (data), (len) + 2); +#define CheckCrc15(data, len) check_crc(CRC_15693, (data), (len)) + +#define ISO15693_READER_TIMEOUT 330 // 330/212kHz = 1558us +#define HF_15693SIM_LOGFILE "hf_15693sim.trace" + +static void DownloadTraceInstructions(void) { + Dbprintf(""); + Dbprintf("To get the trace from flash and display it:"); + Dbprintf("1. mem spiffs dump -s "HF_15693SIM_LOGFILE" -d hf_15693sim.trace"); + Dbprintf("2. trace load -f hf_15693sim.trace"); + Dbprintf("3. trace list -t 15 -1"); +} + +void ModInfo(void) { + DbpString(" HF 15693 SIM, a ISO15693 simulator - lnv42"); + DownloadTraceInstructions(); +} + +void RunMod(void) { + StandAloneMode(); + + Dbprintf(_YELLOW_("HF 15693 SIM started")); +#ifdef WITH_FLASH + rdv40_spiffs_lazy_mount(); +#endif + + iso15693_tag *tag = (iso15693_tag*) BigBuf_get_EM_addr(); + if (tag == NULL) return; + + uint8_t cmd[8] = {0}; + int res; + uint16_t recvLen; + uint8_t recv[32]; + uint32_t eof_time = 0, start_time; + + cmd[0] = ISO15_REQ_DATARATE_HIGH; + cmd[1] = ISO15693_GET_SYSTEM_INFO; + AddCrc15(cmd, 2); + uint8_t i; + + LED_B_ON(); + + Dbprintf("Start dumping tag"); + + while (1) { + SpinDelay(200); + LED_B_OFF(); + if (BUTTON_HELD(500) > 0) + { + LEDsoff(); + return; + } + start_time = 0;//eof_time; + res = SendDataTag(cmd, 4, true, 1, recv, sizeof(recv), start_time, ISO15693_READER_TIMEOUT, &eof_time, &recvLen); + if (res < 0) + continue; + if (recvLen<10) // error: recv too short + continue; + if (CheckCrc15(recv,recvLen)) // error crc not valid + continue; + if (recv[0] & ISO15_RES_ERROR) // received error from tag + continue; + + memset(tag, 0, sizeof(iso15693_tag)); + memcpy(tag->uid, &recv[2], 8); + + i=10; + if (recv[1] & 0x01) + tag->dsfid = recv[i++]; + if (recv[1] & 0x02) + tag->afi = recv[i++]; + if (recv[1] & 0x04) + { + tag->pagesCount = recv[i++]+1; + tag->bytesPerPage = recv[i++]+1; + } + else + { // Set default tag values (if can't be readed in SYSINFO) + tag->bytesPerPage = 4; + tag->pagesCount = 128; + } + if (recv[1] & 0x08) + tag->ic = recv[i++]; + break; + } + + cmd[0] = ISO15_REQ_DATARATE_HIGH | ISO15_REQ_OPTION; + cmd[1] = ISO15693_READBLOCK; + + uint8_t blocknum = 0; + int retry; + + for (retry = 0; retry < 8; retry++) { + if (blocknum >= tag->pagesCount) + break; + + cmd[2] = blocknum; + AddCrc15(cmd, 3); + + start_time = eof_time; + res = SendDataTag(cmd, 5, false, 1, recv, sizeof(recv), start_time, ISO15693_READER_TIMEOUT, &eof_time, &recvLen); + + if (res < 0) + continue; + if (recvLen < 4 + tag->bytesPerPage) // error: recv too short + continue; + if (CheckCrc15(recv,recvLen)) // error crc not valid + continue; + if (recv[0] & ISO15_RES_ERROR) // received error from tag + continue; + + tag->locks[blocknum] = recv[1]; + memcpy(&tag->data[blocknum * tag->bytesPerPage], recv + 2, tag->bytesPerPage); + retry = 0; + blocknum++; + } + + LEDsoff(); + if (retry >= 8) + return; + + Dbprintf("Tag dumpped"); + Dbprintf("Start simulation"); + + SimTagIso15693(0, 0); + + Dbprintf("Simulation stopped"); + SpinDelay(200); + + uint32_t trace_len = BigBuf_get_traceLen(); +#ifndef WITH_FLASH + // Keep stuff in BigBuf for USB/BT dumping + if (trace_len > 0) + Dbprintf("[!] Trace length (bytes) = %u", trace_len); +#else + // Write stuff to spiffs logfile + if (trace_len > 0) { + Dbprintf("[!] Trace length (bytes) = %u", trace_len); + + uint8_t *trace_buffer = BigBuf_get_addr(); + if (!exists_in_spiffs(HF_15693SSIM_LOGFILE)) { + rdv40_spiffs_write( + HF_15693SIM_LOGFILE, trace_buffer, trace_len, RDV40_SPIFFS_SAFETY_SAFE); + Dbprintf("[!] Wrote trace to "HF_15693SIM_LOGFILE); + } else { + rdv40_spiffs_append( + HF_15693SIM_LOGFILE, trace_buffer, trace_len, RDV40_SPIFFS_SAFETY_SAFE); + Dbprintf("[!] Appended trace to "HF_15693SIM_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); +#endif + + Dbprintf("-=[ exit ]=-"); + LEDsoff(); + DownloadTraceInstructions(); +} 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 406a7bcec..3e85e1369 100644 --- a/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md +++ b/doc/md/Use_of_Proxmark/4_Advanced-compilation-parameters.md @@ -127,6 +127,7 @@ Here are the supported values you can assign to `STANDALONE` in `Makefile.platfo | HF_14ASNIFF | 14a sniff storing to flashmem - Micolous | HF_14BSNIFF | 14b sniff - jacopo-j | HF_15SNIFF | 15693 sniff storing to flashmem - Glaser +| HF_15SNIFF | 15693 simulator - lnv42 | HF_AVEFUL | MIFARE Ultralight read/simulation - Ave Ozkal | HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth storing in flashmem - Bogito | HF_CARDHOPPER | Long distance (over IP) relay of 14a protocols - Sam Haskins diff --git a/tools/build_all_firmwares.sh b/tools/build_all_firmwares.sh index 22a3ee60f..2740d7150 100755 --- a/tools/build_all_firmwares.sh +++ b/tools/build_all_firmwares.sh @@ -32,7 +32,7 @@ mv bootrom/obj/bootrom.elf "$DEST/PM3BOOTROM.elf" # cf armsrc/Standalone/Makefile.hal STANDALONE_MODES=(LF_SKELETON) STANDALONE_MODES+=(LF_EM4100EMUL LF_EM4100RSWB LF_EM4100RSWW LF_EM4100RWC LF_HIDBRUTE LF_HIDFCBRUTE LF_ICEHID LF_MULTIHID LF_NEDAP_SIM LF_NEXID LF_PROXBRUTE LF_PROX2BRUTE LF_SAMYRUN LF_THAREXDE) -STANDALONE_MODES+=(HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_AVEFUL HF_BOG HF_CARDHOPPER HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_REBLAY HF_TCPRST HF_TMUDFORD HF_UNISNIFF HF_YOUNG) +STANDALONE_MODES+=(HF_14ASNIFF HF_14BSNIFF HF_15SNIFF HF_15SIM HF_AVEFUL HF_BOG HF_CARDHOPPER HF_COLIN HF_CRAFTBYTE HF_ICECLASS HF_LEGIC HF_LEGICSIM HF_MATTYRUN HF_MFCSIM HF_MSDSAL HF_REBLAY HF_TCPRST HF_TMUDFORD HF_UNISNIFF HF_YOUNG) STANDALONE_MODES+=(DANKARMULTI) STANDALONE_MODES_REQ_BT=(HF_CARDHOPPER HF_REBLAY) STANDALONE_MODES_REQ_SMARTCARD=()