1 //-----------------------------------------------------------------------------
2 // Copyright (C) lnv42 2024
3 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // See LICENSE.txt for the text of the license.
16 //-----------------------------------------------------------------------------
17 // Main code for standalone HF/iso15693 Simulation
18 // This code is trying to dump an iso15 tag, then simulate it
19 // It doesn't support any password protected/authenticated features
20 //-----------------------------------------------------------------------------
22 #include "standalone.h" // standalone definitions
23 #include "proxmark3_arm.h"
24 #include "fpgaloader.h"
27 #include "protocols.h"
28 #include "iso15693tools.h"
37 #define AddCrc15(data, len) compute_crc(CRC_15693, (data), (len), (data)+(len), (data)+(len)+1)
38 //#define CalculateCrc15(data, len) Crc16ex(CRC_15693, (data), (len) + 2);
39 #define CheckCrc15(data, len) check_crc(CRC_15693, (data), (len))
41 #define ISO15693_READER_TIMEOUT 330 // 330/212kHz = 1558us
42 #define HF_15693SIM_LOGFILE "hf_15693sim.trace"
44 static void DownloadTraceInstructions(void) {
47 Dbprintf("To get the trace from flash and display it:");
48 Dbprintf("1. mem spiffs dump -s "HF_15693SIM_LOGFILE
" -d hf_15693sim.trace");
49 Dbprintf("2. trace load -f hf_15693sim.trace");
50 Dbprintf("3. trace list -t 15 -1");
52 Dbprintf("To get the trace from PM3 memory:");
53 Dbprintf("trace list -t 15");
58 DbpString(" HF 15693 SIM, a ISO15693 simulator - lnv42");
59 DownloadTraceInstructions();
65 Dbprintf(_YELLOW_("HF 15693 SIM started"));
67 rdv40_spiffs_lazy_mount();
70 FpgaDownloadAndGo(FPGA_BITSTREAM_HF_15
);
72 iso15_tag_t
*tag
= (iso15_tag_t
*) BigBuf_get_EM_addr();
73 if (tag
== NULL
) return;
79 uint32_t eof_time
= 0, start_time
;
81 cmd
[0] = ISO15_REQ_DATARATE_HIGH
;
82 cmd
[1] = ISO15693_GET_SYSTEM_INFO
;
88 Dbprintf("Wait for a dumpable tag");
93 if (BUTTON_HELD(500) > 0) {
98 start_time
= 0;//eof_time;
99 res
= SendDataTag(cmd
, 4, true, true, recv
, sizeof(recv
), start_time
, ISO15693_READER_TIMEOUT
, &eof_time
, &recvLen
);
102 if (recvLen
< 10) { // error: recv too short
103 Dbprintf("recvLen<10");
106 if (!CheckCrc15(recv
, recvLen
)) { // error crc not valid
107 Dbprintf("crc failed");
110 if (recv
[0] & ISO15_RES_ERROR
) { // received error from tag
111 Dbprintf("error received");
115 Dbprintf("Start dumping tag");
117 memset(tag
, 0, sizeof(iso15_tag_t
));
118 memcpy(tag
->uid
, &recv
[2], 8);
122 tag
->dsfid
= recv
[i
++];
124 tag
->afi
= recv
[i
++];
125 if (recv
[1] & 0x04) {
126 tag
->pagesCount
= recv
[i
++] + 1;
127 tag
->bytesPerPage
= recv
[i
++] + 1;
129 // Set default tag values (if can't be readed in SYSINFO)
130 tag
->bytesPerPage
= 4;
131 tag
->pagesCount
= 128;
138 cmd
[0] = ISO15_REQ_DATARATE_HIGH
| ISO15_REQ_OPTION
;
139 cmd
[1] = ISO15693_READBLOCK
;
141 uint8_t blocknum
= 0;
144 for (retry
= 0; retry
< 8; retry
++) {
145 if (blocknum
>= tag
->pagesCount
)
151 start_time
= eof_time
;
152 res
= SendDataTag(cmd
, 5, false, true, recv
, sizeof(recv
), start_time
, ISO15693_READER_TIMEOUT
, &eof_time
, &recvLen
);
158 if (recvLen
< 4 + tag
->bytesPerPage
) { // error: recv too short
159 Dbprintf("recvLen < 4 + tag->bytesPerPage");
162 if (!CheckCrc15(recv
, recvLen
)) { // error crc not valid
163 Dbprintf("crc failed");
166 if (recv
[0] & ISO15_RES_ERROR
) { // received error from tag
167 Dbprintf("error received");
171 tag
->locks
[blocknum
] = recv
[1];
172 memcpy(&tag
->data
[blocknum
* tag
->bytesPerPage
], recv
+ 2, tag
->bytesPerPage
);
179 Dbprintf("Max retry attemps exeeded");
180 Dbprintf("-=[ exit ]=-");
184 Dbprintf("Tag dumped");
185 Dbprintf("Start simulation");
187 SimTagIso15693(NULL
, 0);
189 Dbprintf("Simulation stopped");
192 uint32_t trace_len
= BigBuf_get_traceLen();
194 // Keep stuff in BigBuf for USB/BT dumping
196 Dbprintf("[!] Trace length (bytes) = %u", trace_len
);
198 // Write stuff to spiffs logfile
200 Dbprintf("[!] Trace length (bytes) = %u", trace_len
);
202 uint8_t *trace_buffer
= BigBuf_get_addr();
203 if (!exists_in_spiffs(HF_15693SIM_LOGFILE
)) {
208 RDV40_SPIFFS_SAFETY_SAFE
210 Dbprintf("[!] Wrote trace to "HF_15693SIM_LOGFILE
);
213 HF_15693SIM_LOGFILE
, trace_buffer
, trace_len
, RDV40_SPIFFS_SAFETY_SAFE
);
214 Dbprintf("[!] Appended trace to "HF_15693SIM_LOGFILE
);
217 Dbprintf("[!] Trace buffer is empty, nothing to write!");
221 rdv40_spiffs_lazy_unmount();
224 SpinErr(LED_A
, 200, 5);
228 Dbprintf("-=[ exit ]=-");
230 DownloadTraceInstructions();