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