1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2018 iceman
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
7 //-----------------------------------------------------------------------------
8 // Proxmark3 RDV40 Smartcard module commands
9 //-----------------------------------------------------------------------------
10 #include "cmdsmartcard.h"
16 #include "cmdparser.h"
17 #include "proxmark3.h"
19 #include "smartcard.h"
21 #include "protocols.h"
23 #include "cmdhflist.h"
24 #include "emv/apduinfo.h" // APDUcode description
25 #include "emv/emvcore.h" // decodeTVL
26 #include "crypto/libpcrypto.h" // sha512hash
27 #include "emv/dump.h" // dump_buffer
30 #define SC_UPGRADE_FILES_DIRECTORY "sc_upgrade_firmware/"
32 static bool UseAlternativeSmartcardReader
= false; // default: use PM3 RDV40 Smartcard Slot (if available)
34 static int CmdHelp(const char *Cmd
);
36 static int usage_sm_raw(void) {
37 PrintAndLogEx(NORMAL
, "Usage: sc raw [h|r|c] d <0A 0B 0C ... hex>");
38 PrintAndLogEx(NORMAL
, " h : this help");
39 PrintAndLogEx(NORMAL
, " r : do not read response");
40 PrintAndLogEx(NORMAL
, " a : active smartcard without select (reset sc module)");
41 PrintAndLogEx(NORMAL
, " s : active smartcard with select (get ATR)");
42 PrintAndLogEx(NORMAL
, " t : executes TLV decoder if it possible");
43 PrintAndLogEx(NORMAL
, " 0 : use protocol T=0");
44 PrintAndLogEx(NORMAL
, " d <bytes> : bytes to send");
45 PrintAndLogEx(NORMAL
, "");
46 PrintAndLogEx(NORMAL
, "Examples:");
47 PrintAndLogEx(NORMAL
, " sc raw s 0 d 00a404000e315041592e5359532e4444463031 - `1PAY.SYS.DDF01` PSE directory with get ATR");
51 static int usage_sm_select(void) {
52 PrintAndLogEx(NORMAL
, "Usage: sc select [h|<reader name>] ");
53 PrintAndLogEx(NORMAL
, " h : this help");
54 PrintAndLogEx(NORMAL
, " <reader name> : a card reader's name, wildcards allowed, leave empty to pick from available readers");
55 PrintAndLogEx(NORMAL
, "");
56 PrintAndLogEx(NORMAL
, "Examples:");
57 PrintAndLogEx(NORMAL
, " sc select : list available card readers and pick");
58 PrintAndLogEx(NORMAL
, " sc select Gemalto* : select a connected Gemalto card reader" );
62 static int usage_sm_reader(void) {
63 PrintAndLogEx(NORMAL
, "Usage: sc reader [h|s]");
64 PrintAndLogEx(NORMAL
, " h : this help");
65 PrintAndLogEx(NORMAL
, " s : silent (no messages)");
66 PrintAndLogEx(NORMAL
, "");
67 PrintAndLogEx(NORMAL
, "Examples:");
68 PrintAndLogEx(NORMAL
, " sc reader");
72 static int usage_sm_info(void) {
73 PrintAndLogEx(NORMAL
, "Usage: s info [h|s]");
74 PrintAndLogEx(NORMAL
, " h : this help");
75 PrintAndLogEx(NORMAL
, " s : silent (no messages)");
76 PrintAndLogEx(NORMAL
, "");
77 PrintAndLogEx(NORMAL
, "Examples:");
78 PrintAndLogEx(NORMAL
, " sc info");
82 static int usage_sm_upgrade(void) {
83 PrintAndLogEx(NORMAL
, "Upgrade RDV4.0 Smartcard Socket Firmware");
84 PrintAndLogEx(NORMAL
, "Usage: sc upgrade f <file name>");
85 PrintAndLogEx(NORMAL
, " h : this help");
86 PrintAndLogEx(NORMAL
, " f <filename> : firmware file name");
87 PrintAndLogEx(NORMAL
, "");
88 PrintAndLogEx(NORMAL
, "Examples:");
89 PrintAndLogEx(NORMAL
, " sc upgrade f SIM010.BIN");
93 static int usage_sm_setclock(void) {
94 PrintAndLogEx(NORMAL
, "Usage: sc setclock [h] c <clockspeed>");
95 PrintAndLogEx(NORMAL
, " h : this help");
96 PrintAndLogEx(NORMAL
, " c <> : clockspeed (0 = 16mhz, 1=8mhz, 2=4mhz) ");
97 PrintAndLogEx(NORMAL
, "");
98 PrintAndLogEx(NORMAL
, "Examples:");
99 PrintAndLogEx(NORMAL
, " sc setclock c 2");
103 static int usage_sm_brute(void) {
104 PrintAndLogEx(NORMAL
, "Tries to bruteforce SFI, ");
105 PrintAndLogEx(NORMAL
, "Usage: sc brute [h]");
106 PrintAndLogEx(NORMAL
, " h : this help");
107 PrintAndLogEx(NORMAL
, "");
108 PrintAndLogEx(NORMAL
, "Examples:");
109 PrintAndLogEx(NORMAL
, " sc brute");
113 uint8_t GetATRTA1(uint8_t *atr
, size_t atrlen
) {
120 return 0x11; // default value is 0x11, corresponding to fmax=5 MHz, Fi=372, Di=1.
131 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
143 372, // b0000 Historical note: in ISO/IEC 7816-3:1989, this was assigned to cards with internal clock
162 4, // b0000 Historical note: in ISO/IEC 7816-3:1989, this was assigned to cards with internal clock
180 static int GetATRDi(uint8_t *atr
, size_t atrlen
) {
181 uint8_t TA1
= GetATRTA1(atr
, atrlen
);
183 return DiArray
[TA1
& 0x0f]; // The 4 low-order bits of TA1 (4th MSbit to 1st LSbit) encode Di
186 static int GetATRFi(uint8_t *atr
, size_t atrlen
) {
187 uint8_t TA1
= GetATRTA1(atr
, atrlen
);
189 return FiArray
[TA1
>> 4]; // The 4 high-order bits of TA1 (8th MSbit to 5th LSbit) encode fmax and Fi
192 static float GetATRF(uint8_t *atr
, size_t atrlen
) {
193 uint8_t TA1
= GetATRTA1(atr
, atrlen
);
195 return FArray
[TA1
>> 4]; // The 4 high-order bits of TA1 (8th MSbit to 5th LSbit) encode fmax and Fi
198 static int PrintATR(uint8_t *atr
, size_t atrlen
) {
201 uint8_t K
= T0
& 0x0F;
202 uint8_t TD1
= 0, T1len
= 0, TD1len
= 0, TDilen
= 0;
203 bool protocol_T0_present
= true;
204 bool protocol_T15_present
= false;
207 PrintAndLog("\t- TA1 (Maximum clock frequency, proposed bit duration) [ 0x%02x ]", atr
[2 + T1len
]);
212 PrintAndLog("\t- TB1 (Deprecated: VPP requirements) [ 0x%02x ]", atr
[2 + T1len
]);
217 PrintAndLog("\t- TC1 (Extra delay between bytes required by card) [ 0x%02x ]", atr
[2 + T1len
]);
222 TD1
= atr
[2 + T1len
];
223 PrintAndLog("\t- TD1 (First offered transmission protocol, presence of TA2..TD2) [ 0x%02x ] Protocol T%d", TD1
, TD1
& 0x0f);
224 protocol_T0_present
= false;
225 if ((TD1
& 0x0f) == 0) {
226 protocol_T0_present
= true;
228 if ((TD1
& 0x0f) == 15) {
229 protocol_T15_present
= true;
235 PrintAndLog("\t- TA2 (Specific protocol and parameters to be used after the ATR) [ 0x%02x ]", atr
[2 + T1len
+ TD1len
]);
239 PrintAndLog("\t- TB2 (Deprecated: VPP precise voltage requirement) [ 0x%02x ]", atr
[2 + T1len
+ TD1len
]);
243 PrintAndLog("\t- TC2 (Maximum waiting time for protocol T=0) [ 0x%02x ]", atr
[2 + T1len
+ TD1len
]);
247 uint8_t TDi
= atr
[2 + T1len
+ TD1len
];
248 PrintAndLog("\t- TD2 (A supported protocol or more global parameters, presence of TA3..TD3) [ 0x%02x ] Protocol T%d", TDi
, TDi
& 0x0f);
249 if ((TDi
& 0x0f) == 0) {
250 protocol_T0_present
= true;
252 if ((TDi
& 0x0f) == 15) {
253 protocol_T15_present
= true;
257 bool nextCycle
= true;
262 PrintAndLog("\t- TA%d: 0x%02x", vi
, atr
[2 + T1len
+ TD1len
+ TDilen
]);
266 PrintAndLog("\t- TB%d: 0x%02x", vi
, atr
[2 + T1len
+ TD1len
+ TDilen
]);
270 PrintAndLog("\t- TC%d: 0x%02x", vi
, atr
[2 + T1len
+ TD1len
+ TDilen
]);
274 TDi
= atr
[2 + T1len
+ TD1len
+ TDilen
];
275 PrintAndLog("\t- TD%d [ 0x%02x ] Protocol T%d", vi
, TDi
, TDi
& 0x0f);
285 if (!protocol_T0_present
|| protocol_T15_present
) { // there is CRC Check Byte TCK
287 for (int i
= 1; i
< atrlen
; i
++)
291 PrintAndLogEx(WARNING
, "Check sum error. Must be 0 got 0x%02X", vxor
);
293 PrintAndLogEx(INFO
, "Check sum OK.");
297 PrintAndLogEx(WARNING
, "Not a direct convention [ 0x%02x ]", atr
[0]);
299 uint8_t calen
= 2 + T1len
+ TD1len
+ TDilen
+ K
;
301 if (atrlen
!= calen
&& atrlen
!= calen
+ 1) // may be CRC
302 PrintAndLogEx(ERR
, "ATR length error. len: %d, T1len: %d, TD1len: %d, TDilen: %d, K: %d", atrlen
, T1len
, TD1len
, TDilen
, K
);
305 PrintAndLogEx(INFO
, "\nHistorical bytes | len %02d | format %02x", K
, atr
[2 + T1len
+ TD1len
+ TDilen
]);
308 PrintAndLogEx(INFO
, "\tHistorical bytes");
309 dump_buffer(&atr
[2 + T1len
+ TD1len
+ TDilen
], K
, NULL
, 1);
315 bool smart_getATR(smart_card_atr_t
*card
)
317 if (UseAlternativeSmartcardReader
) {
318 return pcscGetATR(card
);
320 UsbCommand c
= {CMD_SMART_ATR
, {0, 0, 0}};
324 if ( !WaitForResponseTimeout(CMD_ACK
, &resp
, 2500) ) {
328 if (resp
.arg
[0] & 0xff) {
329 return resp
.arg
[0] & 0xFF;
332 memcpy(card
, (smart_card_atr_t
*)resp
.d
.asBytes
, sizeof(smart_card_atr_t
));
338 static bool smart_select(bool silent
) {
340 smart_card_atr_t card
;
341 if (!smart_getATR(&card
)) {
342 if (!silent
) PrintAndLogEx(WARNING
, "smart card select failed");
347 PrintAndLogEx(INFO
, "ISO7816-3 ATR : %s", sprint_hex(card
.atr
, card
.atr_len
));
354 static void smart_transmit(uint8_t *data
, uint32_t data_len
, uint32_t flags
, uint8_t *response
, int *response_len
, uint32_t max_response_len
)
356 // PrintAndLogEx(SUCCESS, "C-TPDU>>>> %s", sprint_hex(data, data_len));
357 if (UseAlternativeSmartcardReader
) {
358 *response_len
= max_response_len
;
359 pcscTransmit(data
, data_len
, flags
, response
, response_len
);
361 UsbCommand c
= {CMD_SMART_RAW
, {flags
, data_len
, 0}};
362 memcpy(c
.d
.asBytes
, data
, data_len
);
365 if (!WaitForResponseTimeout(CMD_ACK
, &c
, 2500)) {
366 PrintAndLogEx(WARNING
, "smart card response timeout");
371 *response_len
= c
.arg
[0];
372 if (*response_len
> 0) {
373 memcpy(response
, c
.d
.asBytes
, *response_len
);
377 if (*response_len
<= 0) {
378 PrintAndLogEx(WARNING
, "smart card response failed");
383 if (*response_len
< 2) {
384 // PrintAndLogEx(SUCCESS, "R-TPDU %02X | ", response[0]);
388 // PrintAndLogEx(SUCCESS, "R-TPDU<<<< %s", sprint_hex(response, *response_len));
389 // PrintAndLogEx(SUCCESS, "R-TPDU SW %02X%02X | %s", response[*response_len-2], response[*response_len-1], GetAPDUCodeDescription(response[*response_len-2], response[*response_len-1]));
393 static int CmdSmartSelect(const char *Cmd
)
395 const char *readername
;
397 if (tolower(param_getchar(Cmd
, 0)) == 'h') {
398 return usage_sm_select();
401 if (!PM3hasSmartcardSlot() && !pcscCheckForCardReaders()) {
402 PrintAndLogEx(WARNING
, "No Smartcard Readers available");
403 UseAlternativeSmartcardReader
= false;
408 if (param_getptr(Cmd
, &bg
, &en
, 0)) {
409 UseAlternativeSmartcardReader
= pcscSelectAlternativeCardReader(NULL
);
411 readername
= Cmd
+ bg
;
412 UseAlternativeSmartcardReader
= pcscSelectAlternativeCardReader(readername
);
419 static int CmdSmartRaw(const char *Cmd
) {
423 bool active_select
= false;
426 bool errors
= false, reply
= true, decodeTLV
= false, breakloop
= false;
427 uint8_t data
[ISO7816_MAX_FRAME_SIZE
] = {0x00};
429 while (param_getchar(Cmd
, cmdp
) != 0x00 && !errors
) {
430 switch (tolower(param_getchar(Cmd
, cmdp
))) {
431 case 'h': return usage_sm_raw();
441 active_select
= true;
453 switch (param_gethex_to_eol(Cmd
, cmdp
+1, data
, sizeof(data
), &hexlen
)) {
455 PrintAndLogEx(WARNING
, "Invalid HEX value.");
458 PrintAndLogEx(WARNING
, "Too many bytes. Max %d bytes", sizeof(data
));
461 PrintAndLogEx(WARNING
, "Hex must have even number of digits.");
469 PrintAndLogEx(WARNING
, "Unknown parameter '%c'", param_getchar(Cmd
, cmdp
));
479 if (errors
|| cmdp
== 0 ) return usage_sm_raw();
482 uint32_t protocol
= 0;
483 if (active
|| active_select
) {
490 protocol
= SC_RAW_T0
;
495 int response_len
= 0;
496 uint8_t *response
= NULL
;
498 response
= calloc(ISO7816_MAX_FRAME_SIZE
, sizeof(uint8_t));
503 smart_transmit(data
, hexlen
, flags
|protocol
, response
, &response_len
, ISO7816_MAX_FRAME_SIZE
);
505 // reading response from smart card
507 if ( response_len
< 0 ) {
512 if ( response
[0] == 0x6C ) {
513 data
[4] = response
[1];
514 smart_transmit(data
, hexlen
, protocol
, response
, &response_len
, ISO7816_MAX_FRAME_SIZE
);
518 if (decodeTLV
&& response_len
> 4)
519 TLVPrintFromBuffer(response
, response_len
-2);
527 int ExchangeAPDUSC(uint8_t *APDU
, int APDUlen
, bool activateCard
, bool leaveSignalON
, uint8_t *response
, int maxresponselen
, int *responselen
)
529 uint8_t TPDU
[ISO7816_MAX_FRAME_SIZE
];
536 uint32_t flags
= SC_RAW_T0
;
538 flags
|= SC_SELECT
| SC_CONNECT
;
541 if (APDUlen
== 4) { // Case 1
542 memcpy(TPDU
, APDU
, 4);
544 smart_transmit(TPDU
, 5, flags
, response
, responselen
, maxresponselen
);
545 } else if (APDUlen
== 5) { // Case 2 Short
546 smart_transmit(APDU
, 5, flags
, response
, responselen
, maxresponselen
);
547 if (response
[0] == 0x6C) { // wrong Le
548 uint16_t Le
= APDU
[4] ? APDU
[4] : 256;
549 uint8_t La
= response
[1];
550 memcpy(TPDU
, APDU
, 5);
552 smart_transmit(TPDU
, 5, SC_RAW_T0
, response
, responselen
, maxresponselen
);
553 if (Le
< La
&& *responselen
>= 0) {
554 response
[Le
] = response
[*responselen
-2];
555 response
[Le
+1] = response
[*responselen
-1];
556 *responselen
= Le
+ 2;
559 } else if (APDU
[4] != 0 && APDUlen
== 5 + APDU
[4]) { // Case 3 Short
560 smart_transmit(APDU
, APDUlen
, flags
, response
, responselen
, maxresponselen
);
561 } else if (APDU
[4] != 0 && APDUlen
== 5 + APDU
[4] + 1) { // Case 4 Short
562 smart_transmit(APDU
, APDUlen
-1, flags
, response
, responselen
, maxresponselen
);
563 if (response
[0] == 0x90 && response
[1] == 0x00) {
564 uint8_t Le
= APDU
[APDUlen
-1];
565 uint8_t get_response
[5] = {0x00, ISO7816_GET_RESPONSE
, 0x00, 0x00, Le
};
566 return ExchangeAPDUSC(get_response
, 5, false, leaveSignalON
, response
, maxresponselen
, responselen
);
568 } else { // Long Cases not yet implemented
569 PrintAndLogEx(ERR
, "Long APDUs not yet implemented");
573 if (*responselen
< 0 ) {
581 static int CmdSmartUpgrade(const char *Cmd
) {
583 PrintAndLogEx(NORMAL
, "");
584 PrintAndLogEx(WARNING
, "WARNING - RDV4.0 Smartcard Socket Firmware upgrade.");
585 PrintAndLogEx(WARNING
, "A dangerous command, do wrong and you will brick the smart card socket");
586 PrintAndLogEx(NORMAL
, "");
589 char filename
[FILE_PATH_SIZE
] = {0};
593 while (param_getchar(Cmd
, cmdp
) != 0x00 && !errors
) {
594 switch (tolower(param_getchar(Cmd
, cmdp
))) {
596 //File handling and reading
597 if ( param_getstr(Cmd
, cmdp
+1, filename
, FILE_PATH_SIZE
) >= FILE_PATH_SIZE
) {
598 PrintAndLogEx(FAILED
, "Filename too long");
605 return usage_sm_upgrade();
607 PrintAndLogEx(WARNING
, "Unknown parameter '%c'", param_getchar(Cmd
, cmdp
));
614 if (errors
|| cmdp
== 0 ) return usage_sm_upgrade();
616 if (strchr(filename
, '\\') || strchr(filename
, '/')) {
617 PrintAndLogEx(FAILED
, "Filename must not contain \\ or /. Firmware file will be found in client/sc_upgrade_firmware directory.");
621 char sc_upgrade_file_path
[strlen(get_my_executable_directory()) + strlen(SC_UPGRADE_FILES_DIRECTORY
) + strlen(filename
) + 1];
622 strcpy(sc_upgrade_file_path
, get_my_executable_directory());
623 strcat(sc_upgrade_file_path
, SC_UPGRADE_FILES_DIRECTORY
);
624 strcat(sc_upgrade_file_path
, filename
);
625 if (strlen(sc_upgrade_file_path
) >= FILE_PATH_SIZE
) {
626 PrintAndLogEx(FAILED
, "Filename too long");
630 char sha512filename
[FILE_PATH_SIZE
] = {'\0'};
631 char *bin_extension
= filename
;
632 char *dot_position
= NULL
;
633 while ((dot_position
= strchr(bin_extension
, '.')) != NULL
) {
634 bin_extension
= dot_position
+ 1;
636 if (!strcmp(bin_extension
, "BIN")
638 || !strcmp(bin_extension
, "bin")
641 memcpy(sha512filename
, filename
, strlen(filename
) - strlen("bin"));
642 strcat(sha512filename
, "sha512.txt");
644 PrintAndLogEx(FAILED
, "Filename extension of Firmware Upgrade File must be .BIN");
648 PrintAndLogEx(INFO
, "Checking integrity using SHA512 File %s ...", sha512filename
);
649 char sc_upgrade_sha512file_path
[strlen(get_my_executable_directory()) + strlen(SC_UPGRADE_FILES_DIRECTORY
) + strlen(sha512filename
) + 1];
650 strcpy(sc_upgrade_sha512file_path
, get_my_executable_directory());
651 strcat(sc_upgrade_sha512file_path
, SC_UPGRADE_FILES_DIRECTORY
);
652 strcat(sc_upgrade_sha512file_path
, sha512filename
);
653 if (strlen(sc_upgrade_sha512file_path
) >= FILE_PATH_SIZE
) {
654 PrintAndLogEx(FAILED
, "Filename too long");
658 // load firmware file
659 f
= fopen(sc_upgrade_file_path
, "rb");
661 PrintAndLogEx(FAILED
, "Firmware file not found or locked.");
665 // get filesize in order to malloc memory
666 fseek(f
, 0, SEEK_END
);
667 size_t fsize
= ftell(f
);
668 fseek(f
, 0, SEEK_SET
);
671 PrintAndLogEx(FAILED
, "Could not determine size of firmware file");
676 uint8_t *dump
= calloc(fsize
, sizeof(uint8_t));
678 PrintAndLogEx(FAILED
, "Could not allocate memory for firmware");
683 size_t firmware_size
= fread(dump
, 1, fsize
, f
);
688 f
= fopen(sc_upgrade_sha512file_path
, "rb");
690 PrintAndLogEx(FAILED
, "SHA-512 file not found or locked.");
694 // get filesize in order to malloc memory
695 fseek(f
, 0, SEEK_END
);
697 fseek(f
, 0, SEEK_SET
);
700 PrintAndLogEx(FAILED
, "Could not determine size of SHA-512 file");
706 PrintAndLogEx(FAILED
, "SHA-512 file too short");
711 char hashstring
[129];
712 size_t bytes_read
= fread(hashstring
, 1, 128, f
);
713 hashstring
[128] = '\0';
719 if (bytes_read
!= 128 || param_gethex(hashstring
, 0, hash1
, 128)) {
720 PrintAndLogEx(FAILED
, "Couldn't read SHA-512 file");
725 if (sha512hash(dump
, firmware_size
, hash2
)) {
726 PrintAndLogEx(FAILED
, "Couldn't calculate SHA-512 of Firmware");
730 if (memcmp(hash1
, hash2
, 64)) {
731 PrintAndLogEx(FAILED
, "Couldn't verify integrity of Firmware file (wrong SHA-512)");
735 PrintAndLogEx(SUCCESS
, "RDV4.0 Smartcard Socket Firmware uploading to PM3");
739 uint32_t bytes_sent
= 0;
740 uint32_t bytes_remaining
= firmware_size
;
742 while (bytes_remaining
> 0){
743 uint32_t bytes_in_packet
= MIN(USB_CMD_DATA_SIZE
, bytes_remaining
);
744 UsbCommand c
= {CMD_SMART_UPLOAD
, {index
+ bytes_sent
, bytes_in_packet
, 0}};
746 // Fill usb bytes with 0xFF
747 memset(c
.d
.asBytes
, 0xFF, USB_CMD_DATA_SIZE
);
748 memcpy(c
.d
.asBytes
, dump
+ bytes_sent
, bytes_in_packet
);
749 clearCommandBuffer();
751 if ( !WaitForResponseTimeout(CMD_ACK
, NULL
, 2000) ) {
752 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
757 bytes_remaining
-= bytes_in_packet
;
758 bytes_sent
+= bytes_in_packet
;
759 printf("."); fflush(stdout
);
763 PrintAndLogEx(SUCCESS
, "RDV4.0 Smartcard Socket Firmware updating, don\'t turn off your PM3!");
765 // trigger the firmware upgrade
766 UsbCommand c
= {CMD_SMART_UPGRADE
, {firmware_size
, 0, 0}};
767 clearCommandBuffer();
770 if ( !WaitForResponseTimeout(CMD_ACK
, &resp
, 2500) ) {
771 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
774 if ( (resp
.arg
[0] & 0xFF ) )
775 PrintAndLogEx(SUCCESS
, "RDV4.0 Smartcard Socket Firmware upgraded successful");
777 PrintAndLogEx(FAILED
, "RDV4.0 Smartcard Socket Firmware Upgrade failed");
782 static int CmdSmartInfo(const char *Cmd
){
784 bool errors
= false, silent
= false;
786 while (param_getchar(Cmd
, cmdp
) != 0x00 && !errors
) {
787 switch (tolower(param_getchar(Cmd
, cmdp
))) {
788 case 'h': return usage_sm_info();
793 PrintAndLogEx(WARNING
, "Unknown parameter '%c'", param_getchar(Cmd
, cmdp
));
801 if (errors
) return usage_sm_info();
803 smart_card_atr_t card
;
804 if (!smart_getATR(&card
)) {
805 if (!silent
) PrintAndLogEx(WARNING
, "smart card select failed");
810 if (!silent
) PrintAndLogEx(ERR
, "can't get ATR from a smart card");
815 PrintAndLogEx(INFO
, "--- Smartcard Information ---------");
816 PrintAndLogEx(INFO
, "-------------------------------------------------------------");
817 PrintAndLogEx(INFO
, "ISO7618-3 ATR : %s", sprint_hex(card
.atr
, card
.atr_len
));
818 PrintAndLogEx(INFO
, "\nhttp://smartcard-atr.appspot.com/parse?ATR=%s", sprint_hex_inrow(card
.atr
, card
.atr_len
) );
821 PrintAndLogEx(NORMAL
, "");
822 PrintAndLogEx(INFO
, "ATR");
823 PrintATR(card
.atr
, card
.atr_len
);
825 // print D/F (brom byte TA1 or defaults)
826 PrintAndLogEx(NORMAL
, "");
827 PrintAndLogEx(INFO
, "D/F (TA1)");
828 int Di
= GetATRDi(card
.atr
, card
.atr_len
);
829 int Fi
= GetATRFi(card
.atr
, card
.atr_len
);
830 float F
= GetATRF(card
.atr
, card
.atr_len
);
831 if (GetATRTA1(card
.atr
, card
.atr_len
) == 0x11)
832 PrintAndLogEx(INFO
, "Using default values...");
834 PrintAndLogEx(NORMAL
, "\t- Di=%d", Di
);
835 PrintAndLogEx(NORMAL
, "\t- Fi=%d", Fi
);
836 PrintAndLogEx(NORMAL
, "\t- F=%.1f MHz", F
);
839 PrintAndLogEx(NORMAL
, "\t- Cycles/ETU=%d", Fi
/Di
);
840 PrintAndLogEx(NORMAL
, "\t- %.1f bits/sec at 4MHz", (float)4000000 / (Fi
/Di
));
841 PrintAndLogEx(NORMAL
, "\t- %.1f bits/sec at Fmax=%.1fMHz", (F
* 1000000) / (Fi
/Di
), F
);
843 PrintAndLogEx(WARNING
, "\t- Di or Fi is RFU.");
849 int CmdSmartReader(const char *Cmd
){
851 bool errors
= false, silent
= false;
853 while (param_getchar(Cmd
, cmdp
) != 0x00 && !errors
) {
854 switch (tolower(param_getchar(Cmd
, cmdp
))) {
855 case 'h': return usage_sm_reader();
860 PrintAndLogEx(WARNING
, "Unknown parameter '%c'", param_getchar(Cmd
, cmdp
));
868 if (errors
) return usage_sm_reader();
870 smart_card_atr_t card
;
871 if (!smart_getATR(&card
)) {
872 if (!silent
) PrintAndLogEx(WARNING
, "smart card select failed");
876 PrintAndLogEx(INFO
, "ISO7816-3 ATR : %s", sprint_hex(card
.atr
, card
.atr_len
));
881 static int CmdSmartSetClock(const char *Cmd
){
885 while (param_getchar(Cmd
, cmdp
) != 0x00 && !errors
) {
886 switch (tolower(param_getchar(Cmd
, cmdp
))) {
887 case 'h': return usage_sm_setclock();
889 clock
= param_get8ex(Cmd
, cmdp
+1, 2, 10);
896 PrintAndLogEx(WARNING
, "Unknown parameter '%c'", param_getchar(Cmd
, cmdp
));
903 if (errors
|| cmdp
== 0) return usage_sm_setclock();
905 UsbCommand c
= {CMD_SMART_SETCLOCK
, {clock
, 0, 0}};
906 clearCommandBuffer();
909 if ( !WaitForResponseTimeout(CMD_ACK
, &resp
, 2500) ) {
910 PrintAndLogEx(WARNING
, "smart card select failed");
914 uint8_t isok
= resp
.arg
[0] & 0xFF;
916 PrintAndLogEx(WARNING
, "smart card set clock failed");
922 PrintAndLogEx(SUCCESS
, "Clock changed to 16mhz giving 10800 baudrate");
925 PrintAndLogEx(SUCCESS
, "Clock changed to 8mhz giving 21600 baudrate");
928 PrintAndLogEx(SUCCESS
, "Clock changed to 4mhz giving 86400 baudrate");
937 static int CmdSmartList(const char *Cmd
) {
938 if (UseAlternativeSmartcardReader
) {
947 static int CmdSmartBruteforceSFI(const char *Cmd
) {
949 char ctmp
= tolower(param_getchar(Cmd
, 0));
950 if (ctmp
== 'h') return usage_sm_brute();
952 uint8_t data
[5] = {0x00, 0xB2, 0x00, 0x00, 0x00};
954 PrintAndLogEx(INFO
, "Selecting card");
955 if ( !smart_select(false) ) {
959 PrintAndLogEx(INFO
, "Selecting PSE aid");
960 CmdSmartRaw("s 0 t d 00a404000e325041592e5359532e4444463031");
961 CmdSmartRaw("0 t d 00a4040007a000000004101000"); // mastercard
962 // CmdSmartRaw("0 t d 00a4040007a0000000031010"); // visa
964 PrintAndLogEx(INFO
, "starting");
966 int response_len
= 0;
967 uint8_t* response
= malloc(ISO7816_MAX_FRAME_SIZE
);
971 for (uint8_t i
=1; i
< 4; i
++) {
972 for (int p1
=1; p1
< 5; p1
++) {
975 data
[3] = (i
<< 3) + 4;
977 smart_transmit(data
, sizeof(data
), SC_RAW_T0
, response
, &response_len
, ISO7816_MAX_FRAME_SIZE
);
979 if ( response
[0] == 0x6C ) {
980 data
[4] = response
[1];
981 smart_transmit(data
, sizeof(data
), SC_RAW_T0
, response
, &response_len
, ISO7816_MAX_FRAME_SIZE
);
984 if (response_len
> 4)
985 TLVPrintFromBuffer(response
+1, response_len
-3);
989 memset(response
, 0x00, ISO7816_MAX_FRAME_SIZE
);
996 static command_t CommandTable
[] = {
997 {"help", CmdHelp
, 1, "This help"},
998 {"select", CmdSmartSelect
, 1, "Select the Smartcard Reader to use"},
999 {"list", CmdSmartList
, 1, "List ISO 7816 history"},
1000 {"info", CmdSmartInfo
, 1, "Tag information"},
1001 {"reader", CmdSmartReader
, 1, "Act like an IS07816 reader"},
1002 {"raw", CmdSmartRaw
, 1, "Send raw hex data to tag"},
1003 {"upgrade", CmdSmartUpgrade
, 0, "Upgrade firmware"},
1004 {"setclock", CmdSmartSetClock
, 1, "Set clock speed"},
1005 {"brute", CmdSmartBruteforceSFI
, 1, "Bruteforce SFI"},
1006 {NULL
, NULL
, 0, NULL
}
1010 int CmdSmartcard(const char *Cmd
) {
1011 clearCommandBuffer();
1012 CmdsParse(CommandTable
, Cmd
);
1017 static int CmdHelp(const char *Cmd
) {
1018 CmdsHelp(CommandTable
);