]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhf14b.c
Merge branch 'master' of https://github.com/Proxmark/proxmark3
[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 "proxmark3.h"
18 #include "data.h"
19 #include "graph.h"
20 #include "util.h"
21 #include "ui.h"
22 #include "cmdparser.h"
23 #include "cmdhf14b.h"
24 #include "cmdmain.h"
25 #include "cmdhf14a.h"
26
27 static int CmdHelp(const char *Cmd);
28
29 int CmdHF14BList(const char *Cmd)
30 {
31 PrintAndLog("Deprecated command, use 'hf list 14b' instead");
32
33 return 0;
34 }
35
36 int CmdHF14BSim(const char *Cmd)
37 {
38 UsbCommand c={CMD_SIMULATE_TAG_ISO_14443B};
39 SendCommand(&c);
40 return 0;
41 }
42
43 int CmdHF14BSnoop(const char *Cmd)
44 {
45 UsbCommand c = {CMD_SNOOP_ISO_14443B};
46 SendCommand(&c);
47 return 0;
48 }
49
50 /* New command to read the contents of a SRI512 tag
51 * SRI512 tags are ISO14443-B modulated memory tags,
52 * this command just dumps the contents of the memory
53 */
54 int CmdSri512Read(const char *Cmd)
55 {
56 UsbCommand c = {CMD_READ_SRI512_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
57 clearCommandBuffer();
58 SendCommand(&c);
59 return 0;
60 }
61
62 /* New command to read the contents of a SRIX4K tag
63 * SRIX4K tags are ISO14443-B modulated memory tags,
64 * this command just dumps the contents of the memory/
65 */
66 int CmdSrix4kRead(const char *Cmd)
67 {
68 UsbCommand c = {CMD_READ_SRIX4K_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
69 clearCommandBuffer();
70 SendCommand(&c);
71 return 0;
72 }
73
74 int rawClose(void){
75 UsbCommand resp;
76 UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}};
77 clearCommandBuffer();
78 SendCommand(&c);
79 if (!WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
80 return 0;
81 }
82 return 0;
83 }
84
85 int HF14BCmdRaw(bool reply, bool *crc, bool power, uint8_t *data, uint8_t *datalen, bool verbose){
86 UsbCommand resp;
87 UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}}; // len,recv,power
88 if(*crc)
89 {
90 uint8_t first, second;
91 ComputeCrc14443(CRC_14443_B, data, *datalen, &first, &second);
92 data[*datalen] = first;
93 data[*datalen + 1] = second;
94 *datalen += 2;
95 }
96
97 c.arg[0] = *datalen;
98 c.arg[1] = reply;
99 c.arg[2] = power;
100 memcpy(c.d.asBytes,data,*datalen);
101 clearCommandBuffer();
102 SendCommand(&c);
103
104 if (!reply) return 1;
105
106 if (!WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
107 if (verbose) PrintAndLog("timeout while waiting for reply.");
108 return 0;
109 }
110 *datalen = resp.arg[0];
111 if (verbose) PrintAndLog("received %u octets", *datalen);
112 if(*datalen<2) return 0;
113
114 memcpy(data, resp.d.asBytes, *datalen);
115 if (verbose) PrintAndLog("%s", sprint_hex(data, *datalen));
116
117 uint8_t first, second;
118 ComputeCrc14443(CRC_14443_B, data, *datalen-2, &first, &second);
119 if(data[*datalen-2] == first && data[*datalen-1] == second) {
120 if (verbose) PrintAndLog("CRC OK");
121 *crc = true;
122 } else {
123 if (verbose) PrintAndLog("CRC failed");
124 *crc = false;
125 }
126 return 1;
127 }
128
129 int CmdHF14BCmdRaw (const char *Cmd) {
130 bool reply = true;
131 bool crc = false;
132 bool power = false;
133 char buf[5]="";
134 uint8_t data[100] = {0x00};
135 uint8_t datalen = 0;
136 unsigned int temp;
137 int i = 0;
138 if (strlen(Cmd)<3) {
139 PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] <0A 0B 0C ... hex>");
140 PrintAndLog(" -r do not read response");
141 PrintAndLog(" -c calculate and append CRC");
142 PrintAndLog(" -p leave the field on after receive");
143 return 0;
144 }
145
146 // strip
147 while (*Cmd==' ' || *Cmd=='\t') Cmd++;
148
149 while (Cmd[i]!='\0') {
150 if (Cmd[i]==' ' || Cmd[i]=='\t') { i++; continue; }
151 if (Cmd[i]=='-') {
152 switch (Cmd[i+1]) {
153 case 'r':
154 case 'R':
155 reply = false;
156 break;
157 case 'c':
158 case 'C':
159 crc = true;
160 break;
161 case 'p':
162 case 'P':
163 power = true;
164 break;
165 default:
166 PrintAndLog("Invalid option");
167 return 0;
168 }
169 i+=2;
170 continue;
171 }
172 if ((Cmd[i]>='0' && Cmd[i]<='9') ||
173 (Cmd[i]>='a' && Cmd[i]<='f') ||
174 (Cmd[i]>='A' && Cmd[i]<='F') ) {
175 buf[strlen(buf)+1]=0;
176 buf[strlen(buf)]=Cmd[i];
177 i++;
178
179 if (strlen(buf)>=2) {
180 sscanf(buf,"%x",&temp);
181 data[datalen++]=(uint8_t)(temp & 0xff);
182 *buf=0;
183 }
184 continue;
185 }
186 PrintAndLog("Invalid char on input");
187 return 1;
188 }
189 if (datalen == 0)
190 {
191 PrintAndLog("Missing data input");
192 return 0;
193 }
194
195 return HF14BCmdRaw(reply, &crc, power, data, &datalen, true);
196 }
197
198 static void print_atqb_resp(uint8_t *data){
199 PrintAndLog (" UID: %s", sprint_hex(data+1,4));
200 PrintAndLog (" App Data: %s", sprint_hex(data+5,4));
201 PrintAndLog (" Protocol: %s", sprint_hex(data+9,3));
202 uint8_t BitRate = data[9];
203 if (!BitRate) PrintAndLog (" Bit Rate: 106 kbit/s only PICC <-> PCD");
204 if (BitRate & 0x10) PrintAndLog (" Bit Rate: 212 kbit/s PICC -> PCD supported");
205 if (BitRate & 0x20) PrintAndLog (" Bit Rate: 424 kbit/s PICC -> PCD supported");
206 if (BitRate & 0x40) PrintAndLog (" Bit Rate: 847 kbit/s PICC -> PCD supported");
207 if (BitRate & 0x01) PrintAndLog (" Bit Rate: 212 kbit/s PICC <- PCD supported");
208 if (BitRate & 0x02) PrintAndLog (" Bit Rate: 424 kbit/s PICC <- PCD supported");
209 if (BitRate & 0x04) PrintAndLog (" Bit Rate: 847 kbit/s PICC <- PCD supported");
210 if (BitRate & 0x80) PrintAndLog (" Same bit rate <-> required");
211
212 uint16_t maxFrame = data[10]>>4;
213 if (maxFrame < 5) maxFrame = 8 * maxFrame + 16;
214 else if (maxFrame == 5) maxFrame = 64;
215 else if (maxFrame == 6) maxFrame = 96;
216 else if (maxFrame == 7) maxFrame = 128;
217 else if (maxFrame == 8) maxFrame = 256;
218 else maxFrame = 257;
219
220 PrintAndLog ("Max Frame Size: %d%s", maxFrame, (maxFrame == 257) ? "+ RFU" : "");
221
222 uint8_t protocolT = data[10] & 0xF;
223 PrintAndLog (" Protocol Type: Protocol is %scompliant with ISO/IEC 14443-4",(protocolT) ? "" : "not " );
224 PrintAndLog ("Frame Wait Int: %d", data[11]>>4);
225 PrintAndLog (" App Data Code: Application is %s",(data[11]&4) ? "Standard" : "Proprietary");
226 PrintAndLog (" Frame Options: NAD is %ssupported",(data[11]&2) ? "" : "not ");
227 PrintAndLog (" Frame Options: CID is %ssupported",(data[11]&1) ? "" : "not ");
228
229 return;
230 }
231
232 char *get_ST_Chip_Model(uint8_t data){
233 static char model[20];
234 char *retStr = model;
235 memset(model,0, sizeof(model));
236
237 switch (data) {
238 case 0x0: sprintf(retStr, "SRIX4K (Special)"); break;
239 case 0x2: sprintf(retStr, "SR176"); break;
240 case 0x3: sprintf(retStr, "SRIX4K"); break;
241 case 0x4: sprintf(retStr, "SRIX512"); break;
242 case 0x6: sprintf(retStr, "SRI512"); break;
243 case 0x7: sprintf(retStr, "SRI4K"); break;
244 case 0xC: sprintf(retStr, "SRT512"); break;
245 default: sprintf(retStr, "Unknown"); break;
246 }
247
248 c.arg[0] = datalen;
249 c.arg[1] = reply;
250 c.arg[2] = power;
251 memcpy(c.d.asBytes,data,datalen);
252
253 SendCommand(&c);
254
255 if (reply) {
256 if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
257 recv = resp.d.asBytes;
258 PrintAndLog("received %i octets",resp.arg[0]);
259 if(resp.arg[0] == 0)
260 return 0;
261 hexout = (char *)malloc(resp.arg[0] * 3 + 1);
262 if (hexout != NULL) {
263 uint8_t first, second;
264 for (int i = 0; i < resp.arg[0]; i++) { // data in hex
265 sprintf(&hexout[i * 3], "%02X ", recv[i]);
266 }
267 PrintAndLog("%s", hexout);
268 free(hexout);
269 if (resp.arg[0] > 2) {
270 ComputeCrc14443(CRC_14443_B, recv, resp.arg[0]-2, &first, &second);
271 if(recv[resp.arg[0]-2]==first && recv[resp.arg[0]-1]==second) {
272 PrintAndLog("CRC OK");
273 } else {
274 PrintAndLog("CRC failed");
275 }
276 }
277 } else {
278 PrintAndLog("malloc failed your client has low memory?");
279 }
280
281 crc = false;
282 *datalen = 1;
283 data[0] = 0x0a;
284
285 if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
286 if (*datalen > 0) {
287 PrintAndLog ("\n14443-3b tag found:");
288 PrintAndLog ("Unknown tag type answered to a 0x0A command ans:");
289 PrintAndLog ("%s",sprint_hex(data,*datalen));
290 return 1;
291 }
292 }
293
294 crc = false;
295 *datalen = 1;
296 data[0] = 0x0c;
297
298 if (HF14BCmdRaw(true, &crc, false, data, datalen, false)!=0) {
299 if (*datalen > 0) {
300 PrintAndLog ("\n14443-3b tag found:");
301 PrintAndLog ("Unknown tag type answered to a 0x0C command ans:");
302 PrintAndLog ("%s",sprint_hex(data,*datalen));
303 return 1;
304 }
305 }
306
307 return 0;
308
309 }
310
311 int HF14BReader(bool verbose){
312 uint8_t data[100];
313 uint8_t datalen = 5;
314
315 // try std 14b (atqb)
316 if (HF14BStdReader(data, &datalen)) return 1;
317
318 // try st 14b
319 if (HF14B_ST_Reader(data, &datalen)) return 1;
320
321 // try unknown 14b read commands (to be identified later)
322 // could be read of calypso, CEPAS, moneo, or pico pass.
323 if (HF14B_Other_Reader(data, &datalen)) return 1;
324
325 if (verbose) PrintAndLog("no 14443B tag found");
326 return 0;
327 }
328
329 int CmdHF14BReader(const char *Cmd){
330 return HF14BReader(true);
331 }
332
333 int CmdHF14BWrite( const char *Cmd){
334 /*
335 * For SRIX4K blocks 00 - 7F
336 * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
337 *
338 * For SR512 blocks 00 - 0F
339 * hf 14b raw -c -p 09 $sr512wblock $sr512wdata
340 *
341 * Special block FF = otp_lock_reg block.
342 * Data len 4 bytes-
343 */
344 char cmdp = param_getchar(Cmd, 0);
345 uint8_t blockno = -1;
346 uint8_t data[4] = {0x00};
347 bool isSrix4k = true;
348 char str[20];
349
350 if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
351 PrintAndLog("Usage: hf 14b write <1|2> <BLOCK> <DATA>");
352 PrintAndLog(" [1 = SRIX4K]");
353 PrintAndLog(" [2 = SRI512]");
354 PrintAndLog(" [BLOCK number depends on tag, special block == FF]");
355 PrintAndLog(" sample: hf 14b write 1 7F 11223344");
356 PrintAndLog(" : hf 14b write 1 FF 11223344");
357 PrintAndLog(" : hf 14b write 2 15 11223344");
358 PrintAndLog(" : hf 14b write 2 FF 11223344");
359 return 0;
360 }
361
362 if ( cmdp == '2' )
363 isSrix4k = false;
364
365 //blockno = param_get8(Cmd, 1);
366
367 if ( param_gethex(Cmd,1, &blockno, 2) ) {
368 PrintAndLog("Block number must include 2 HEX symbols");
369 return 0;
370 }
371
372 if ( isSrix4k ){
373 if ( blockno > 0x7f && blockno != 0xff ){
374 PrintAndLog("Block number out of range");
375 return 0;
376 }
377 } else {
378 if ( blockno > 0x0f && blockno != 0xff ){
379 PrintAndLog("Block number out of range");
380 return 0;
381 }
382 }
383
384 if (param_gethex(Cmd, 2, data, 8)) {
385 PrintAndLog("Data must include 8 HEX symbols");
386 return 0;
387 }
388
389 if ( blockno == 0xff)
390 PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512" , blockno, sprint_hex(data,4) );
391 else
392 PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno, sprint_hex(data,4) );
393
394 sprintf(str, "-c 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
395
396 CmdHF14BCmdRaw(str);
397 return 0;
398 }
399
400 static command_t CommandTable[] =
401 {
402 {"help", CmdHelp, 1, "This help"},
403 {"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"},
404 {"sim", CmdHF14BSim, 0, "Fake ISO 14443B tag"},
405 {"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443B"},
406 {"sri512read", CmdSri512Read, 0, "Read contents of a SRI512 tag"},
407 {"srix4kread", CmdSrix4kRead, 0, "Read contents of a SRIX4K tag"},
408 {"raw", CmdHF14BCmdRaw, 0, "Send raw hex data to tag"},
409 {"write", CmdHF14BWrite, 0, "Write data to a SRI512 | SRIX4K tag"},
410 {NULL, NULL, 0, NULL}
411 };
412
413 int CmdHF14B(const char *Cmd)
414 {
415 CmdsParse(CommandTable, Cmd);
416 return 0;
417 }
418
419 int CmdHelp(const char *Cmd)
420 {
421 CmdsHelp(CommandTable);
422 return 0;
423 }
Impressum, Datenschutz