]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhf14b.c
ADD: pwpiwi 's FPGA compress
[proxmark3-svn] / client / cmdhf14b.c
CommitLineData
a553f267 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
7fe9b0b7 11#include <stdio.h>
12#include <stdlib.h>
13#include <stdbool.h>
14#include <string.h>
15#include <stdint.h>
16#include "iso14443crc.h"
902cb3c0 17#include "proxmark3.h"
7fe9b0b7 18#include "data.h"
19#include "graph.h"
3fe4ff4f 20#include "util.h"
7fe9b0b7 21#include "ui.h"
22#include "cmdparser.h"
23#include "cmdhf14b.h"
7cf3ef20 24#include "cmdmain.h"
d71d59db 25#include "cmdhf14a.h"
7fe9b0b7 26
27static int CmdHelp(const char *Cmd);
28
7fe9b0b7 29int CmdHF14BList(const char *Cmd)
30{
388c92bd 31 PrintAndLog("Deprecated command, use 'hf list 14b' instead");
7fe9b0b7 32
388c92bd 33 return 0;
7fe9b0b7 34}
7fe9b0b7 35
22e24700 36int CmdHF14BSim(const char *Cmd)
7fe9b0b7 37{
132a0217 38 UsbCommand c={CMD_SIMULATE_TAG_ISO_14443B};
22e24700 39 SendCommand(&c);
40 return 0;
7fe9b0b7 41}
42
43int CmdHF14BSnoop(const char *Cmd)
44{
132a0217 45 UsbCommand c = {CMD_SNOOP_ISO_14443B};
22e24700 46 SendCommand(&c);
47 return 0;
7fe9b0b7 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 */
54int CmdSri512Read(const char *Cmd)
55{
22e24700 56 UsbCommand c = {CMD_READ_SRI512_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
abb21530 57 clearCommandBuffer();
22e24700 58 SendCommand(&c);
59 return 0;
7fe9b0b7 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 */
66int CmdSrix4kRead(const char *Cmd)
67{
22e24700 68 UsbCommand c = {CMD_READ_SRIX4K_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
abb21530 69 clearCommandBuffer();
22e24700 70 SendCommand(&c);
71 return 0;
7fe9b0b7 72}
73
d71d59db 74int rawClose(void){
22e24700 75 UsbCommand resp;
d71d59db 76 UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}};
abb21530 77 clearCommandBuffer();
d71d59db 78 SendCommand(&c);
79 if (!WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
80 return 0;
81 }
82 return 0;
83}
84
22e24700 85int HF14BCmdRaw(bool reply, bool *crc, bool power, uint8_t *data, uint8_t *datalen, bool verbose){
d71d59db 86 UsbCommand resp;
22e24700 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);
abb21530 101 clearCommandBuffer();
22e24700 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;
1299c798 127}
128
129int CmdHF14BCmdRaw (const char *Cmd) {
130 bool reply = true;
131 bool crc = false;
22e24700 132 bool power = false;
7cf3ef20 133 char buf[5]="";
5ee70129 134 uint8_t data[100] = {0x00};
1299c798 135 uint8_t datalen = 0;
136 unsigned int temp;
137 int i = 0;
138 if (strlen(Cmd)<3) {
7cf3ef20 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
1299c798 147 while (*Cmd==' ' || *Cmd=='\t') Cmd++;
7cf3ef20 148
1299c798 149 while (Cmd[i]!='\0') {
150 if (Cmd[i]==' ' || Cmd[i]=='\t') { i++; continue; }
151 if (Cmd[i]=='-') {
152 switch (Cmd[i+1]) {
7cf3ef20 153 case 'r':
154 case 'R':
1299c798 155 reply = false;
7cf3ef20 156 break;
157 case 'c':
158 case 'C':
1299c798 159 crc = true;
7cf3ef20 160 break;
161 case 'p':
162 case 'P':
22e24700 163 power = true;
7cf3ef20 164 break;
165 default:
166 PrintAndLog("Invalid option");
167 return 0;
168 }
169 i+=2;
170 continue;
171 }
1299c798 172 if ((Cmd[i]>='0' && Cmd[i]<='9') ||
173 (Cmd[i]>='a' && Cmd[i]<='f') ||
174 (Cmd[i]>='A' && Cmd[i]<='F') ) {
7cf3ef20 175 buf[strlen(buf)+1]=0;
1299c798 176 buf[strlen(buf)]=Cmd[i];
7cf3ef20 177 i++;
178
179 if (strlen(buf)>=2) {
180 sscanf(buf,"%x",&temp);
1299c798 181 data[datalen++]=(uint8_t)(temp & 0xff);
7cf3ef20 182 *buf=0;
183 }
184 continue;
185 }
186 PrintAndLog("Invalid char on input");
5ee70129 187 return 1;
7cf3ef20 188 }
06b82e6a 189 if (datalen == 0)
190 {
191 PrintAndLog("Missing data input");
192 return 0;
193 }
1299c798 194
22e24700 195 return HF14BCmdRaw(reply, &crc, power, data, &datalen, true);
1299c798 196}
197
d71d59db 198static void print_atqb_resp(uint8_t *data){
22e24700 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;
1299c798 230}
231
d71d59db 232char *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 }
7cf3ef20 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]);
51d4f6f1 259 if(resp.arg[0] == 0)
7cf3ef20 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
7bb9d33e 265 sprintf(&hexout[i * 3], "%02X ", recv[i]);
22e24700 266 }
7cf3ef20 267 PrintAndLog("%s", hexout);
268 free(hexout);
51d4f6f1 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 }
7cf3ef20 276 }
277 } else {
278 PrintAndLog("malloc failed your client has low memory?");
22e24700 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
1299c798 309}
310
d71d59db 311int HF14BReader(bool verbose){
22e24700 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;
1299c798 320
22e24700 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;
abb21530 324
d71d59db 325 if (verbose) PrintAndLog("no 14443B tag found");
326 return 0;
d71d59db 327}
328
abb21530 329int CmdHF14BReader(const char *Cmd){
d71d59db 330 return HF14BReader(true);
7cf3ef20 331}
332
abb21530 333int CmdHF14BWrite( const char *Cmd){
3fe4ff4f 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
b5be31f9 350 if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
3fe4ff4f 351 PrintAndLog("Usage: hf 14b write <1|2> <BLOCK> <DATA>");
b5be31f9 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");
3fe4ff4f 359 return 0;
360 }
361
b5be31f9 362 if ( cmdp == '2' )
3fe4ff4f 363 isSrix4k = false;
364
b5be31f9 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 }
3fe4ff4f 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)
b5be31f9 390 PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512" , blockno, sprint_hex(data,4) );
3fe4ff4f 391 else
b5be31f9 392 PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno, sprint_hex(data,4) );
3fe4ff4f 393
fe5b3a44 394 sprintf(str, "-c 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
b5be31f9 395
3fe4ff4f 396 CmdHF14BCmdRaw(str);
397 return 0;
398}
399
7fe9b0b7 400static command_t CommandTable[] =
401{
22e24700 402 {"help", CmdHelp, 1, "This help"},
403 {"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"},
132a0217 404 {"sim", CmdHF14BSim, 0, "Fake ISO 14443B tag"},
405 {"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443B"},
22e24700 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}
7fe9b0b7 411};
412
413int CmdHF14B(const char *Cmd)
414{
22e24700 415 CmdsParse(CommandTable, Cmd);
416 return 0;
7fe9b0b7 417}
418
419int CmdHelp(const char *Cmd)
420{
22e24700 421 CmdsHelp(CommandTable);
422 return 0;
7fe9b0b7 423}
Impressum, Datenschutz