]> git.zerfleddert.de Git - proxmark3-svn/blame_incremental - client/cmdhf14b.c
Split str* and mem* into string.[ch]
[proxmark3-svn] / client / cmdhf14b.c
... / ...
CommitLineData
1#include <stdio.h>
2#include <stdlib.h>
3#include <stdbool.h>
4#include <string.h>
5#include <stdint.h>
6#include "iso14443crc.h"
7#include "proxusb.h"
8#include "data.h"
9#include "graph.h"
10#include "ui.h"
11#include "cmdparser.h"
12#include "cmdhf14b.h"
13
14static int CmdHelp(const char *Cmd);
15
16int CmdHF14BDemod(const char *Cmd)
17{
18 int i, j, iold;
19 int isum, qsum;
20 int outOfWeakAt;
21 bool negateI, negateQ;
22
23 uint8_t data[256];
24 int dataLen = 0;
25
26 // As received, the samples are pairs, correlations against I and Q
27 // square waves. So estimate angle of initial carrier (or just
28 // quadrant, actually), and then do the demod.
29
30 // First, estimate where the tag starts modulating.
31 for (i = 0; i < GraphTraceLen; i += 2) {
32 if (abs(GraphBuffer[i]) + abs(GraphBuffer[i + 1]) > 40) {
33 break;
34 }
35 }
36 if (i >= GraphTraceLen) {
37 PrintAndLog("too weak to sync");
38 return 0;
39 }
40 PrintAndLog("out of weak at %d", i);
41 outOfWeakAt = i;
42
43 // Now, estimate the phase in the initial modulation of the tag
44 isum = 0;
45 qsum = 0;
46 for (; i < (outOfWeakAt + 16); i += 2) {
47 isum += GraphBuffer[i + 0];
48 qsum += GraphBuffer[i + 1];
49 }
50 negateI = (isum < 0);
51 negateQ = (qsum < 0);
52
53 // Turn the correlation pairs into soft decisions on the bit.
54 j = 0;
55 for (i = 0; i < GraphTraceLen / 2; i++) {
56 int si = GraphBuffer[j];
57 int sq = GraphBuffer[j + 1];
58 if (negateI) si = -si;
59 if (negateQ) sq = -sq;
60 GraphBuffer[i] = si + sq;
61 j += 2;
62 }
63 GraphTraceLen = i;
64
65 i = outOfWeakAt / 2;
66 while (GraphBuffer[i] > 0 && i < GraphTraceLen)
67 i++;
68 if (i >= GraphTraceLen) goto demodError;
69
70 iold = i;
71 while (GraphBuffer[i] < 0 && i < GraphTraceLen)
72 i++;
73 if (i >= GraphTraceLen) goto demodError;
74 if ((i - iold) > 23) goto demodError;
75
76 PrintAndLog("make it to demod loop");
77
78 for (;;) {
79 iold = i;
80 while (GraphBuffer[i] >= 0 && i < GraphTraceLen)
81 i++;
82 if (i >= GraphTraceLen) goto demodError;
83 if ((i - iold) > 6) goto demodError;
84
85 uint16_t shiftReg = 0;
86 if (i + 20 >= GraphTraceLen) goto demodError;
87
88 for (j = 0; j < 10; j++) {
89 int soft = GraphBuffer[i] + GraphBuffer[i + 1];
90
91 if (abs(soft) < (abs(isum) + abs(qsum)) / 20) {
92 PrintAndLog("weak bit");
93 }
94
95 shiftReg >>= 1;
96 if(GraphBuffer[i] + GraphBuffer[i+1] >= 0) {
97 shiftReg |= 0x200;
98 }
99
100 i+= 2;
101 }
102
103 if ((shiftReg & 0x200) && !(shiftReg & 0x001))
104 {
105 // valid data byte, start and stop bits okay
106 PrintAndLog(" %02x", (shiftReg >> 1) & 0xff);
107 data[dataLen++] = (shiftReg >> 1) & 0xff;
108 if (dataLen >= sizeof(data)) {
109 return 0;
110 }
111 } else if (shiftReg == 0x000) {
112 // this is EOF
113 break;
114 } else {
115 goto demodError;
116 }
117 }
118
119 uint8_t first, second;
120 ComputeCrc14443(CRC_14443_B, data, dataLen-2, &first, &second);
121 PrintAndLog("CRC: %02x %02x (%s)\n", first, second,
122 (first == data[dataLen-2] && second == data[dataLen-1]) ?
123 "ok" : "****FAIL****");
124
125 RepaintGraphWindow();
126 return 0;
127
128demodError:
129 PrintAndLog("demod error");
130 RepaintGraphWindow();
131 return 0;
132}
133
134int CmdHF14BList(const char *Cmd)
135{
136 uint8_t got[960];
137 GetFromBigBuf(got, sizeof(got));
138
139 PrintAndLog("recorded activity:");
140 PrintAndLog(" time :rssi: who bytes");
141 PrintAndLog("---------+----+----+-----------");
142
143 int i = 0;
144 int prev = -1;
145
146 for(;;) {
147 if(i >= 900) {
148 break;
149 }
150
151 bool isResponse;
152 int timestamp = *((uint32_t *)(got+i));
153 if(timestamp & 0x80000000) {
154 timestamp &= 0x7fffffff;
155 isResponse = 1;
156 } else {
157 isResponse = 0;
158 }
159 int metric = *((uint32_t *)(got+i+4));
160
161 int len = got[i+8];
162
163 if(len > 100) {
164 break;
165 }
166 if(i + len >= 900) {
167 break;
168 }
169
170 uint8_t *frame = (got+i+9);
171
172 char line[1000] = "";
173 int j;
174 for(j = 0; j < len; j++) {
175 sprintf(line+(j*3), "%02x ", frame[j]);
176 }
177
178 char *crc;
179 if(len > 2) {
180 uint8_t b1, b2;
181 ComputeCrc14443(CRC_14443_B, frame, len-2, &b1, &b2);
182 if(b1 != frame[len-2] || b2 != frame[len-1]) {
183 crc = "**FAIL CRC**";
184 } else {
185 crc = "";
186 }
187 } else {
188 crc = "(SHORT)";
189 }
190
191 char metricString[100];
192 if(isResponse) {
193 sprintf(metricString, "%3d", metric);
194 } else {
195 strcpy(metricString, " ");
196 }
197
198 PrintAndLog(" +%7d: %s: %s %s %s",
199 (prev < 0 ? 0 : timestamp - prev),
200 metricString,
201 (isResponse ? "TAG" : " "), line, crc);
202
203 prev = timestamp;
204 i += (len + 9);
205 }
206 return 0;
207}
208
209int CmdHF14BRead(const char *Cmd)
210{
211 UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443, {strtol(Cmd, NULL, 0), 0, 0}};
212 SendCommand(&c);
213 return 0;
214}
215
216int CmdHF14Sim(const char *Cmd)
217{
218 UsbCommand c={CMD_SIMULATE_TAG_ISO_14443};
219 SendCommand(&c);
220 return 0;
221}
222
223int CmdHFSimlisten(const char *Cmd)
224{
225 UsbCommand c = {CMD_SIMULATE_TAG_HF_LISTEN};
226 SendCommand(&c);
227 return 0;
228}
229
230int CmdHF14BSnoop(const char *Cmd)
231{
232 UsbCommand c = {CMD_SNOOP_ISO_14443};
233 SendCommand(&c);
234 return 0;
235}
236
237/* New command to read the contents of a SRI512 tag
238 * SRI512 tags are ISO14443-B modulated memory tags,
239 * this command just dumps the contents of the memory
240 */
241int CmdSri512Read(const char *Cmd)
242{
243 UsbCommand c = {CMD_READ_SRI512_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
244 SendCommand(&c);
245 return 0;
246}
247
248/* New command to read the contents of a SRIX4K tag
249 * SRIX4K tags are ISO14443-B modulated memory tags,
250 * this command just dumps the contents of the memory/
251 */
252int CmdSrix4kRead(const char *Cmd)
253{
254 UsbCommand c = {CMD_READ_SRIX4K_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
255 SendCommand(&c);
256 return 0;
257}
258
259static command_t CommandTable[] =
260{
261 {"help", CmdHelp, 1, "This help"},
262 {"demod", CmdHF14BDemod, 1, "Demodulate ISO14443 Type B from tag"},
263 {"list", CmdHF14BList, 0, "List ISO 14443 history"},
264 {"read", CmdHF14BRead, 0, "Read HF tag (ISO 14443)"},
265 {"sim", CmdHF14Sim, 0, "Fake ISO 14443 tag"},
266 {"simlisten", CmdHFSimlisten, 0, "Get HF samples as fake tag"},
267 {"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443"},
268 {"sri512read", CmdSri512Read, 0, "<int> -- Read contents of a SRI512 tag"},
269 {"srix4kread", CmdSrix4kRead, 0, "<int> -- Read contents of a SRIX4K tag"},
270 {NULL, NULL, 0, NULL}
271};
272
273int CmdHF14B(const char *Cmd)
274{
275 CmdsParse(CommandTable, Cmd);
276 return 0;
277}
278
279int CmdHelp(const char *Cmd)
280{
281 CmdsHelp(CommandTable);
282 return 0;
283}
Impressum, Datenschutz