]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdsmartcard.c
c6f08aa4f9f1c816f7b16c67844d1873d09cbe8f
[proxmark3-svn] / client / cmdsmartcard.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2018 iceman
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 // Proxmark3 RDV40 Smartcard module commands
9 //-----------------------------------------------------------------------------
10 #include "cmdsmartcard.h"
11
12 #include <ctype.h>
13
14 #include "ui.h"
15 #include "cmdparser.h"
16 #include "util.h"
17 #include "smartcard.h"
18 #include "comms.h"
19 #include "protocols.h"
20 #include "cmdhf.h" // CmdHFlist
21 #include "emv/apduinfo.h" // APDUcode description
22 #include "emv/emvcore.h" // decodeTVL
23 #include "emv/dump.h" // dump_buffer
24
25
26 static int CmdHelp(const char *Cmd);
27
28 static int usage_sm_raw(void) {
29 PrintAndLogEx(NORMAL, "Usage: sc raw [h|r|c] d <0A 0B 0C ... hex>");
30 PrintAndLogEx(NORMAL, " h : this help");
31 PrintAndLogEx(NORMAL, " r : do not read response");
32 PrintAndLogEx(NORMAL, " a : active smartcard without select");
33 PrintAndLogEx(NORMAL, " s : active smartcard with select");
34 PrintAndLogEx(NORMAL, " t : executes TLV decoder if it possible");
35 PrintAndLogEx(NORMAL, " d <bytes> : bytes to send");
36 PrintAndLogEx(NORMAL, "");
37 PrintAndLogEx(NORMAL, "Examples:");
38 PrintAndLogEx(NORMAL, " sc raw d 00a404000e315041592e5359532e444446303100 - `1PAY.SYS.DDF01` PPSE directory");
39 PrintAndLogEx(NORMAL, " sc raw d 00a404000e325041592e5359532e444446303100 - `2PAY.SYS.DDF01` PPSE directory");
40 return 0;
41 }
42
43 static int usage_sm_reader(void) {
44 PrintAndLogEx(NORMAL, "Usage: sc reader [h|s]");
45 PrintAndLogEx(NORMAL, " h : this help");
46 PrintAndLogEx(NORMAL, " s : silent (no messages)");
47 PrintAndLogEx(NORMAL, "");
48 PrintAndLogEx(NORMAL, "Examples:");
49 PrintAndLogEx(NORMAL, " sc reader");
50 return 0;
51 }
52
53 static int usage_sm_info(void) {
54 PrintAndLogEx(NORMAL, "Usage: s info [h|s]");
55 PrintAndLogEx(NORMAL, " h : this help");
56 PrintAndLogEx(NORMAL, " s : silent (no messages)");
57 PrintAndLogEx(NORMAL, "");
58 PrintAndLogEx(NORMAL, "Examples:");
59 PrintAndLogEx(NORMAL, " sc info");
60 return 0;
61 }
62
63 static int usage_sm_upgrade(void) {
64 PrintAndLogEx(NORMAL, "Upgrade firmware");
65 PrintAndLogEx(NORMAL, "Usage: sc upgrade f <file name>");
66 PrintAndLogEx(NORMAL, " h : this help");
67 PrintAndLogEx(NORMAL, " f <filename> : firmware file name");
68 PrintAndLogEx(NORMAL, "");
69 PrintAndLogEx(NORMAL, "Examples:");
70 PrintAndLogEx(NORMAL, " sc upgrade f myfile");
71 return 0;
72 }
73
74 static int usage_sm_setclock(void) {
75 PrintAndLogEx(NORMAL, "Usage: sc setclock [h] c <clockspeed>");
76 PrintAndLogEx(NORMAL, " h : this help");
77 PrintAndLogEx(NORMAL, " c <> : clockspeed (0 = 16mhz, 1=8mhz, 2=4mhz) ");
78 PrintAndLogEx(NORMAL, "");
79 PrintAndLogEx(NORMAL, "Examples:");
80 PrintAndLogEx(NORMAL, " sc setclock c 2");
81 return 0;
82 }
83
84 static int usage_sm_brute(void) {
85 PrintAndLogEx(NORMAL, "Tries to bruteforce SFI, ");
86 PrintAndLogEx(NORMAL, "Usage: sc brute [h]");
87 PrintAndLogEx(NORMAL, " h : this help");
88 PrintAndLogEx(NORMAL, "");
89 PrintAndLogEx(NORMAL, "Examples:");
90 PrintAndLogEx(NORMAL, " sc brute");
91 return 0;
92 }
93
94 uint8_t GetATRTA1(uint8_t *atr, size_t atrlen) {
95 if (atrlen > 2) {
96 uint8_t T0 = atr[1];
97 if (T0 & 0x10)
98 return atr[2];
99 }
100
101 return 0x11; // default value is 0x11, corresponding to fmax=5 MHz, Fi=372, Di=1.
102 }
103
104 int DiArray[] = {
105 0, // b0000 RFU
106 1, // b0001
107 2,
108 4,
109 8,
110 16,
111 32, // b0110
112 64, // b0111. This was RFU in ISO/IEC 7816-3:1997 and former. Some card readers or drivers may erroneously reject cards using this value
113 12,
114 20,
115 0, // b1010 RFU
116 0,
117 0, // ...
118 0,
119 0,
120 0 // b1111 RFU
121 };
122
123 int FiArray[] = {
124 372, // b0000 Historical note: in ISO/IEC 7816-3:1989, this was assigned to cards with internal clock
125 372, // b0001
126 558, // b0010
127 744, // b0011
128 1116, // b0100
129 1488, // b0101
130 1860, // b0110
131 0, // b0111 RFU
132 0, // b1000 RFU
133 512, // b1001
134 768, // b1010
135 1024, // b1011
136 1536, // b1100
137 2048, // b1101
138 0, // b1110 RFU
139 0 // b1111 RFU
140 };
141
142 float FArray[] = {
143 4, // b0000 Historical note: in ISO/IEC 7816-3:1989, this was assigned to cards with internal clock
144 5, // b0001
145 6, // b0010
146 8, // b0011
147 12, // b0100
148 16, // b0101
149 20, // b0110
150 0, // b0111 RFU
151 0, // b1000 RFU
152 5, // b1001
153 7.5, // b1010
154 10, // b1011
155 15, // b1100
156 20, // b1101
157 0, // b1110 RFU
158 0 // b1111 RFU
159 };
160
161 int GetATRDi(uint8_t *atr, size_t atrlen) {
162 uint8_t TA1 = GetATRTA1(atr, atrlen);
163
164 return DiArray[TA1 & 0x0f]; // The 4 low-order bits of TA1 (4th MSbit to 1st LSbit) encode Di
165 }
166
167 int GetATRFi(uint8_t *atr, size_t atrlen) {
168 uint8_t TA1 = GetATRTA1(atr, atrlen);
169
170 return FiArray[TA1 >> 4]; // The 4 high-order bits of TA1 (8th MSbit to 5th LSbit) encode fmax and Fi
171 }
172
173 float GetATRF(uint8_t *atr, size_t atrlen) {
174 uint8_t TA1 = GetATRTA1(atr, atrlen);
175
176 return FArray[TA1 >> 4]; // The 4 high-order bits of TA1 (8th MSbit to 5th LSbit) encode fmax and Fi
177 }
178
179 static int PrintATR(uint8_t *atr, size_t atrlen) {
180 uint8_t vxor = 0;
181 for (int i = 1; i < atrlen; i++)
182 vxor ^= atr[i];
183
184 if (vxor)
185 PrintAndLogEx(WARNING, "Check summ error. Must be 0 but: 0x%02x", vxor);
186 else
187 PrintAndLogEx(INFO, "Check summ OK.");
188
189 if (atr[0] != 0x3b)
190 PrintAndLogEx(WARNING, "Not a direct convention: 0x%02x", atr[0]);
191
192 uint8_t T0 = atr[1];
193 uint8_t K = T0 & 0x0F;
194 uint8_t TD1 = 0;
195
196 uint8_t T1len = 0;
197 uint8_t TD1len = 0;
198 uint8_t TDilen = 0;
199
200 if (T0 & 0x10) {
201 PrintAndLog("TA1 (Maximum clock frequency, proposed bit duration): 0x%02x", atr[2 + T1len]);
202 T1len++;
203 }
204 if (T0 & 0x20) {
205 PrintAndLog("TB1 (Deprecated: VPP requirements): 0x%02x", atr[2 + T1len]);
206 T1len++;
207 }
208 if (T0 & 0x40) {
209 PrintAndLog("TC1 (Extra delay between bytes required by card): 0x%02x", atr[2 + T1len]);
210 T1len++;
211 }
212 if (T0 & 0x80) {
213 TD1 = atr[2 + T1len];
214 PrintAndLog("TD1 (First offered transmission protocol, presence of TA2..TD2): 0x%02x. Protocol T=%d", TD1, TD1 & 0x0f);
215 T1len++;
216
217 if (TD1 & 0x10) {
218 PrintAndLog("TA2 (Specific protocol and parameters to be used after the ATR): 0x%02x", atr[2 + T1len + TD1len]);
219 TD1len++;
220 }
221 if (TD1 & 0x20) {
222 PrintAndLog("TB2 (Deprecated: VPP precise voltage requirement): 0x%02x", atr[2 + T1len + TD1len]);
223 TD1len++;
224 }
225 if (TD1 & 0x40) {
226 PrintAndLog("TC2 (Maximum waiting time for protocol T=0): 0x%02x", atr[2 + T1len + TD1len]);
227 TD1len++;
228 }
229 if (TD1 & 0x80) {
230 uint8_t TDi = atr[2 + T1len + TD1len];
231 PrintAndLog("TD2 (A supported protocol or more global parameters, presence of TA3..TD3): 0x%02x. Protocol T=%d", TDi, TDi & 0x0f);
232 TD1len++;
233
234 bool nextCycle = true;
235 uint8_t vi = 3;
236 while (nextCycle) {
237 nextCycle = false;
238 if (TDi & 0x10) {
239 PrintAndLog("TA%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]);
240 TDilen++;
241 }
242 if (TDi & 0x20) {
243 PrintAndLog("TB%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]);
244 TDilen++;
245 }
246 if (TDi & 0x40) {
247 PrintAndLog("TC%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]);
248 TDilen++;
249 }
250 if (TDi & 0x80) {
251 TDi = atr[2 + T1len + TD1len + TDilen];
252 PrintAndLog("TD%d: 0x%02x. Protocol T=%d", vi, TDi, TDi & 0x0f);
253 TDilen++;
254
255 nextCycle = true;
256 vi++;
257 }
258 }
259 }
260 }
261
262 uint8_t calen = 2 + T1len + TD1len + TDilen + K;
263
264 if (atrlen != calen && atrlen != calen + 1) // may be CRC
265 PrintAndLogEx(ERR, "ATR length error. len: %d, T1len: %d, TD1len: %d, TDilen: %d, K: %d", atrlen, T1len, TD1len, TDilen, K);
266 else
267 PrintAndLogEx(INFO, "ATR length OK.");
268
269 PrintAndLog("Historical bytes len: 0x%02x", K);
270 if (K > 0)
271 PrintAndLog("The format of historical bytes: %02x", atr[2 + T1len + TD1len + TDilen]);
272 if (K > 1) {
273 PrintAndLog("Historical bytes:");
274 dump_buffer(&atr[2 + T1len + TD1len + TDilen], K, NULL, 1);
275 }
276
277 return 0;
278 }
279
280
281 static bool smart_select(bool silent) {
282 UsbCommand c = {CMD_SMART_ATR, {0, 0, 0}};
283 clearCommandBuffer();
284 SendCommand(&c);
285 UsbCommand resp;
286 if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) {
287 if (!silent) PrintAndLogEx(WARNING, "smart card select failed");
288 return false;
289 }
290
291 uint8_t isok = resp.arg[0] & 0xFF;
292 if (!isok) {
293 if (!silent) PrintAndLogEx(WARNING, "smart card select failed");
294 return false;
295 }
296
297 if (!silent) {
298 smart_card_atr_t card;
299 memcpy(&card, (smart_card_atr_t *)resp.d.asBytes, sizeof(smart_card_atr_t));
300
301 PrintAndLogEx(INFO, "ISO7816-3 ATR : %s", sprint_hex(card.atr, card.atr_len));
302 }
303
304 return true;
305 }
306
307 static int smart_wait(uint8_t *data) {
308 UsbCommand resp;
309 if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
310 PrintAndLogEx(WARNING, "smart card response failed");
311 return -1;
312 }
313
314 uint32_t len = resp.arg[0];
315 if ( !len ) {
316 PrintAndLogEx(WARNING, "smart card response failed");
317 return -2;
318 }
319 memcpy(data, resp.d.asBytes, len);
320 PrintAndLogEx(SUCCESS, " %d | %s", len, sprint_hex_inrow_ex(data, len, 32));
321
322 if (len >= 2) {
323 PrintAndLogEx(SUCCESS, "%02X%02X | %s", data[len - 2], data[len - 1], GetAPDUCodeDescription(data[len - 2], data[len - 1]));
324 }
325 return len;
326 }
327
328 static int smart_response(uint8_t apduINS, uint8_t *data) {
329
330 int datalen = smart_wait(data);
331 bool needGetData = false;
332
333 if (datalen < 2 ) {
334 goto out;
335 }
336
337 if (datalen > 2 && data[0] != apduINS) {
338 PrintAndLogEx(ERR, "Card ACK error. len=0x%x data[0]=%02x", datalen, data[0]);
339 datalen = 0;
340 goto out;
341 }
342
343 if ( data[datalen - 2] == 0x61 || data[datalen - 2] == 0x9F ) {
344 needGetData = true;
345 }
346
347 if (needGetData) {
348 int len = data[datalen - 1];
349 PrintAndLogEx(INFO, "Requesting response. len=0x%x", len);
350 uint8_t getstatus[] = {ISO7816_GETSTATUS, 0x00, 0x00, len};
351 UsbCommand cStatus = {CMD_SMART_RAW, {SC_RAW, sizeof(getstatus), 0}};
352 memcpy(cStatus.d.asBytes, getstatus, sizeof(getstatus) );
353 clearCommandBuffer();
354 SendCommand(&cStatus);
355
356 datalen = smart_wait(data);
357
358 if (datalen < 2 ) {
359 goto out;
360 }
361 if (datalen > 2 && data[0] != ISO7816_GETSTATUS) {
362 PrintAndLogEx(ERR, "GetResponse ACK error. len=0x%x data[0]=%02x", len, data[0]);
363 datalen = 0;
364 goto out;
365 }
366
367 if (datalen != len + 2 + 1) { // 2 - response, 1 - ACK
368 PrintAndLogEx(WARNING, "GetResponse wrong length. Must be: 0x%02x but: 0x%02x", len, datalen - 3);
369 }
370 }
371
372 if (datalen > 2) {
373 datalen--;
374 memmove(data, &data[1], datalen);
375 }
376 out:
377 return datalen;
378 }
379
380 int CmdSmartRaw(const char *Cmd) {
381
382 int hexlen = 0;
383 bool active = false;
384 bool active_select = false;
385 uint8_t cmdp = 0;
386 bool errors = false, reply = true, decodeTLV = false, breakloop = false;
387 uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
388
389 while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
390 switch (tolower(param_getchar(Cmd, cmdp))) {
391 case 'h': return usage_sm_raw();
392 case 'r':
393 reply = false;
394 cmdp++;
395 break;
396 case 'a':
397 active = true;
398 cmdp++;
399 break;
400 case 's':
401 active_select = true;
402 cmdp++;
403 break;
404 case 't':
405 decodeTLV = true;
406 cmdp++;
407 break;
408 case 'd': {
409 switch (param_gethex_to_eol(Cmd, cmdp+1, data, sizeof(data), &hexlen)) {
410 case 1:
411 PrintAndLogEx(WARNING, "Invalid HEX value.");
412 return 1;
413 case 2:
414 PrintAndLogEx(WARNING, "Too many bytes. Max %d bytes", sizeof(data));
415 return 1;
416 case 3:
417 PrintAndLogEx(WARNING, "Hex must have even number of digits.");
418 return 1;
419 }
420 cmdp++;
421 breakloop = true;
422 break;
423 }
424 default:
425 PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
426 errors = true;
427 break;
428 }
429
430 if ( breakloop )
431 break;
432 }
433
434 //Validations
435 if (errors || cmdp == 0 ) return usage_sm_raw();
436
437 // arg0 = RFU flags
438 // arg1 = length
439 UsbCommand c = {CMD_SMART_RAW, {0, hexlen, 0}};
440
441 if (active || active_select) {
442 c.arg[0] |= SC_CONNECT;
443 if (active_select)
444 c.arg[0] |= SC_SELECT;
445 }
446
447 if (hexlen > 0) {
448 c.arg[0] |= SC_RAW;
449 }
450
451 memcpy(c.d.asBytes, data, hexlen );
452 clearCommandBuffer();
453 SendCommand(&c);
454
455 // reading response from smart card
456 if ( reply ) {
457
458 uint8_t* buf = calloc(USB_CMD_DATA_SIZE, sizeof(uint8_t));
459 if ( !buf )
460 return 1;
461
462 int len = smart_response(data[1], buf);
463 if ( len < 0 ) {
464 free(buf);
465 return 2;
466 }
467
468 if ( buf[0] == 0x6C ) {
469 data[4] = buf[1];
470
471 memcpy(c.d.asBytes, data, sizeof(data) );
472 clearCommandBuffer();
473 SendCommand(&c);
474 len = smart_response(data[1], buf);
475
476 data[4] = 0;
477 }
478
479 if (decodeTLV && len > 4)
480 TLVPrintFromBuffer(buf+1, len-3);
481
482 free(buf);
483 }
484 return 0;
485 }
486
487 int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) {
488 *dataoutlen = 0;
489
490 if (activateCard)
491 smart_select(false);
492 printf("* APDU SC\n");
493
494 UsbCommand c = {CMD_SMART_RAW, {SC_RAW | SC_CONNECT, datainlen, 0}};
495 if (activateCard) {
496 c.arg[0] |= SC_SELECT;
497 }
498 memcpy(c.d.asBytes, datain, datainlen);
499 clearCommandBuffer();
500 SendCommand(&c);
501
502 int len = smart_response(datain[1], dataout);
503
504 if ( len < 0 ) {
505 return 2;
506 }
507
508
509 // retry
510 if (len > 1 && dataout[len - 2] == 0x6c && datainlen > 4) {
511 UsbCommand c2 = {CMD_SMART_RAW, {SC_RAW, datainlen, 0}};
512 memcpy(c2.d.asBytes, datain, datainlen);
513
514 int vlen = 5 + datain[4];
515 if (datainlen == vlen)
516 datainlen++;
517
518 c2.d.asBytes[vlen] = dataout[len - 1];
519
520 clearCommandBuffer();
521 SendCommand(&c2);
522
523 len = smart_response(datain[1], dataout);
524 }
525 *dataoutlen = len;
526
527 return 0;
528 }
529
530
531 int CmdSmartUpgrade(const char *Cmd) {
532
533 PrintAndLogEx(WARNING, "WARNING - Smartcard socket firmware upgrade.");
534 PrintAndLogEx(WARNING, "A dangerous command, do wrong and you will brick the smart card socket");
535
536 FILE *f;
537 char filename[FILE_PATH_SIZE] = {0};
538 uint8_t cmdp = 0;
539 bool errors = false;
540
541 while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
542 switch (tolower(param_getchar(Cmd, cmdp))) {
543 case 'f':
544 //File handling and reading
545 if ( param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE ) {
546 PrintAndLogEx(FAILED, "Filename too long");
547 errors = true;
548 break;
549 }
550 cmdp += 2;
551 break;
552 case 'h':
553 return usage_sm_upgrade();
554 default:
555 PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
556 errors = true;
557 break;
558 }
559 }
560
561 //Validations
562 if (errors || cmdp == 0 ) return usage_sm_upgrade();
563
564 // load file
565 f = fopen(filename, "rb");
566 if ( !f ){
567 PrintAndLogEx(FAILED, "File: %s: not found or locked.", filename);
568 return 1;
569 }
570
571 // get filesize in order to malloc memory
572 fseek(f, 0, SEEK_END);
573 long fsize = ftell(f);
574 fseek(f, 0, SEEK_SET);
575
576 if (fsize < 0) {
577 PrintAndLogEx(WARNING, "error, when getting filesize");
578 fclose(f);
579 return 1;
580 }
581
582 uint8_t *dump = calloc(fsize, sizeof(uint8_t));
583 if (!dump) {
584 PrintAndLogEx(WARNING, "error, cannot allocate memory ");
585 fclose(f);
586 return 1;
587 }
588
589 size_t bytes_read = fread(dump, 1, fsize, f);
590 if (f)
591 fclose(f);
592
593 PrintAndLogEx(SUCCESS, "Smartcard socket firmware uploading to PM3");
594 //Send to device
595 uint32_t index = 0;
596 uint32_t bytes_sent = 0;
597 uint32_t bytes_remaining = bytes_read;
598
599 while (bytes_remaining > 0){
600 uint32_t bytes_in_packet = MIN(USB_CMD_DATA_SIZE, bytes_remaining);
601 UsbCommand c = {CMD_SMART_UPLOAD, {index + bytes_sent, bytes_in_packet, 0}};
602
603 // Fill usb bytes with 0xFF
604 memset(c.d.asBytes, 0xFF, USB_CMD_DATA_SIZE);
605 memcpy(c.d.asBytes, dump + bytes_sent, bytes_in_packet);
606 clearCommandBuffer();
607 SendCommand(&c);
608 if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2000) ) {
609 PrintAndLogEx(WARNING, "timeout while waiting for reply.");
610 free(dump);
611 return 1;
612 }
613
614 bytes_remaining -= bytes_in_packet;
615 bytes_sent += bytes_in_packet;
616 printf("."); fflush(stdout);
617 }
618 free(dump);
619 printf("\n");
620 PrintAndLogEx(SUCCESS, "Smartcard socket firmware updating, don\'t turn off your PM3!");
621
622 // trigger the firmware upgrade
623 UsbCommand c = {CMD_SMART_UPGRADE, {bytes_read, 0, 0}};
624 clearCommandBuffer();
625 SendCommand(&c);
626 UsbCommand resp;
627 if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) {
628 PrintAndLogEx(WARNING, "timeout while waiting for reply.");
629 return 1;
630 }
631 if ( (resp.arg[0] & 0xFF ) )
632 PrintAndLogEx(SUCCESS, "Smartcard socket firmware upgraded successful");
633 else
634 PrintAndLogEx(FAILED, "Smartcard socket firmware updating failed");
635 return 0;
636 }
637
638 int CmdSmartInfo(const char *Cmd){
639 uint8_t cmdp = 0;
640 bool errors = false, silent = false;
641
642 while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
643 switch (tolower(param_getchar(Cmd, cmdp))) {
644 case 'h': return usage_sm_info();
645 case 's':
646 silent = true;
647 break;
648 default:
649 PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
650 errors = true;
651 break;
652 }
653 cmdp++;
654 }
655
656 //Validations
657 if (errors ) return usage_sm_info();
658
659 UsbCommand c = {CMD_SMART_ATR, {0, 0, 0}};
660 clearCommandBuffer();
661 SendCommand(&c);
662 UsbCommand resp;
663 if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) {
664 if (!silent) PrintAndLogEx(WARNING, "smart card select failed");
665 return 1;
666 }
667
668 uint8_t isok = resp.arg[0] & 0xFF;
669 if (!isok) {
670 if (!silent) PrintAndLogEx(WARNING, "smart card select failed");
671 return 1;
672 }
673
674 smart_card_atr_t card;
675 memcpy(&card, (smart_card_atr_t *)resp.d.asBytes, sizeof(smart_card_atr_t));
676
677 // print header
678 PrintAndLogEx(INFO, "\n--- Smartcard Information ---------");
679 PrintAndLogEx(INFO, "-------------------------------------------------------------");
680 PrintAndLogEx(INFO, "ISO76183 ATR : %s", sprint_hex(card.atr, card.atr_len));
681 PrintAndLogEx(INFO, "look up ATR");
682 PrintAndLogEx(INFO, "http://smartcard-atr.appspot.com/parse?ATR=%s", sprint_hex_inrow(card.atr, card.atr_len) );
683
684 // print ATR
685 PrintAndLogEx(NORMAL, "");
686 PrintAndLogEx(NORMAL, "* ATR:");
687 PrintATR(card.atr, card.atr_len);
688
689 // print D/F (brom byte TA1 or defaults)
690 PrintAndLogEx(NORMAL, "");
691 PrintAndLogEx(NORMAL, "* D/F (TA1):");
692 int Di = GetATRDi(card.atr, card.atr_len);
693 int Fi = GetATRFi(card.atr, card.atr_len);
694 float F = GetATRF(card.atr, card.atr_len);
695 if (GetATRTA1(card.atr, card.atr_len) == 0x11)
696 PrintAndLogEx(INFO, "Using default values...");
697
698 PrintAndLogEx(NORMAL, "Di=%d", Di);
699 PrintAndLogEx(NORMAL, "Fi=%d", Fi);
700 PrintAndLogEx(NORMAL, "F=%.1f MHz", F);
701 PrintAndLogEx(NORMAL, "Cycles/ETU=%d", Fi/Di);
702 PrintAndLogEx(NORMAL, "%.1f bits/sec at 4MHz", (float)4000000 / (Fi/Di));
703 PrintAndLogEx(NORMAL, "%.1f bits/sec at Fmax=%.1fMHz", (F * 1000000) / (Fi/Di), F);
704
705 return 0;
706 }
707
708 int CmdSmartReader(const char *Cmd){
709 uint8_t cmdp = 0;
710 bool errors = false, silent = false;
711
712 while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
713 switch (tolower(param_getchar(Cmd, cmdp))) {
714 case 'h': return usage_sm_reader();
715 case 's':
716 silent = true;
717 break;
718 default:
719 PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
720 errors = true;
721 break;
722 }
723 cmdp++;
724 }
725
726 //Validations
727 if (errors ) return usage_sm_reader();
728
729 UsbCommand c = {CMD_SMART_ATR, {0, 0, 0}};
730 clearCommandBuffer();
731 SendCommand(&c);
732 UsbCommand resp;
733 if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) {
734 if (!silent) PrintAndLogEx(WARNING, "smart card select failed");
735 return 1;
736 }
737
738 uint8_t isok = resp.arg[0] & 0xFF;
739 if (!isok) {
740 if (!silent) PrintAndLogEx(WARNING, "smart card select failed");
741 return 1;
742 }
743 smart_card_atr_t card;
744 memcpy(&card, (smart_card_atr_t *)resp.d.asBytes, sizeof(smart_card_atr_t));
745
746 PrintAndLogEx(INFO, "ISO7816-3 ATR : %s", sprint_hex(card.atr, card.atr_len));
747 return 0;
748 }
749
750 int CmdSmartSetClock(const char *Cmd){
751 uint8_t cmdp = 0;
752 bool errors = false;
753 uint8_t clock = 0;
754 while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
755 switch (tolower(param_getchar(Cmd, cmdp))) {
756 case 'h': return usage_sm_setclock();
757 case 'c':
758 clock = param_get8ex(Cmd, cmdp+1, 2, 10);
759 if ( clock > 2)
760 errors = true;
761
762 cmdp += 2;
763 break;
764 default:
765 PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
766 errors = true;
767 break;
768 }
769 }
770
771 //Validations
772 if (errors || cmdp == 0) return usage_sm_setclock();
773
774 UsbCommand c = {CMD_SMART_SETCLOCK, {clock, 0, 0}};
775 clearCommandBuffer();
776 SendCommand(&c);
777 UsbCommand resp;
778 if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) {
779 PrintAndLogEx(WARNING, "smart card select failed");
780 return 1;
781 }
782
783 uint8_t isok = resp.arg[0] & 0xFF;
784 if (!isok) {
785 PrintAndLogEx(WARNING, "smart card set clock failed");
786 return 1;
787 }
788
789 switch (clock) {
790 case 0:
791 PrintAndLogEx(SUCCESS, "Clock changed to 16mhz giving 10800 baudrate");
792 break;
793 case 1:
794 PrintAndLogEx(SUCCESS, "Clock changed to 8mhz giving 21600 baudrate");
795 break;
796 case 2:
797 PrintAndLogEx(SUCCESS, "Clock changed to 4mhz giving 86400 baudrate");
798 break;
799 default:
800 break;
801 }
802 return 0;
803 }
804
805 int CmdSmartList(const char *Cmd) {
806 CmdHFList("7816");
807 return 0;
808 }
809
810 int CmdSmartBruteforceSFI(const char *Cmd) {
811
812 char ctmp = tolower(param_getchar(Cmd, 0));
813 if (ctmp == 'h') return usage_sm_brute();
814
815 uint8_t data[5] = {0x00, 0xB2, 0x00, 0x00, 0x00};
816
817 PrintAndLogEx(INFO, "Selecting card");
818 if ( !smart_select(false) ) {
819 return 1;
820 }
821
822 PrintAndLogEx(INFO, "Selecting PPSE aid");
823 CmdSmartRaw("d 00a404000e325041592e5359532e444446303100");
824 CmdSmartRaw("d 00a4040007a000000004101000");
825
826 PrintAndLogEx(INFO, "starting");
827
828 UsbCommand c = {CMD_SMART_RAW, {SC_RAW, sizeof(data), 0}};
829 uint8_t* buf = malloc(USB_CMD_DATA_SIZE);
830 if ( !buf )
831 return 1;
832
833 for (uint8_t i=1; i < 4; i++) {
834 for (int p1=1; p1 < 5; p1++) {
835
836 data[2] = p1;
837 data[3] = (i << 3) + 4;
838
839 memcpy(c.d.asBytes, data, sizeof(data) );
840 clearCommandBuffer();
841 SendCommand(&c);
842
843 smart_response(data[1], buf);
844
845 // if 0x6C
846 if ( buf[0] == 0x6C ) {
847 data[4] = buf[1];
848
849 memcpy(c.d.asBytes, data, sizeof(data) );
850 clearCommandBuffer();
851 SendCommand(&c);
852 uint8_t len = smart_response(data[1], buf);
853
854 // TLV decoder
855 if (len > 4)
856 TLVPrintFromBuffer(buf+1, len-3);
857
858 data[4] = 0;
859 }
860 memset(buf, 0x00, USB_CMD_DATA_SIZE);
861 }
862 }
863 free(buf);
864 return 0;
865 }
866
867 static command_t CommandTable[] = {
868 {"help", CmdHelp, 1, "This help"},
869 {"list", CmdSmartList, 0, "List ISO 7816 history"},
870 {"info", CmdSmartInfo, 1, "Tag information"},
871 {"reader", CmdSmartReader, 1, "Act like an IS07816 reader"},
872 {"raw", CmdSmartRaw, 1, "Send raw hex data to tag"},
873 {"upgrade", CmdSmartUpgrade, 1, "Upgrade firmware"},
874 {"setclock", CmdSmartSetClock, 1, "Set clock speed"},
875 {"brute", CmdSmartBruteforceSFI, 1, "Bruteforce SFI"},
876 {NULL, NULL, 0, NULL}
877 };
878
879 int CmdSmartcard(const char *Cmd) {
880 clearCommandBuffer();
881 CmdsParse(CommandTable, Cmd);
882 return 0;
883 }
884
885 int CmdHelp(const char *Cmd) {
886 CmdsHelp(CommandTable);
887 return 0;
888 }
Impressum, Datenschutz