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