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