fix one too small
[RRG-proxmark3.git] / client / src / cmdsmartcard.c
bloba6a07c4c613a06a82744081f45b4bf89e3bfe992
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // Proxmark3 RDV40 Smartcard module commands
17 //-----------------------------------------------------------------------------
18 #include "cmdsmartcard.h"
19 #include <ctype.h>
20 #include <string.h>
21 #include "cmdparser.h" // command_t
22 #include "commonutil.h" // ARRAYLEN
23 #include "iso7816/iso7816core.h"
24 #include "protocols.h"
25 #include "cmdtrace.h"
26 #include "proxmark3.h"
27 #include "comms.h" // getfromdevice
28 #include "emv/emvcore.h" // decodeTVL
29 #include "crypto/libpcrypto.h" // sha512hash
30 #include "ui.h"
31 #include "util.h"
32 #include "fileutils.h"
33 #include "crc16.h" // crc
34 #include "cliparser.h" // cliparsing
35 #include "atrs.h" // ATR lookup
37 #pragma GCC diagnostic push
38 #pragma GCC diagnostic ignored "-Wswitch-enum"
39 #include "mbedtls/net_sockets.h"
40 #pragma GCC diagnostic pop
42 #include "mifare.h"
43 #include "util_posix.h"
44 #include "cmdhf14a.h"
45 #include "cmdhf14b.h"
47 static int CmdHelp(const char *Cmd);
49 static int smart_loadjson(const char *preferredName, json_t **root) {
51 json_error_t error;
53 if (preferredName == NULL) return 1;
55 char *path;
56 int res = searchFile(&path, RESOURCES_SUBDIR, preferredName, ".json", false);
57 if (res != PM3_SUCCESS) {
58 return PM3_EFILE;
61 int retval = PM3_SUCCESS;
62 *root = json_load_file(path, 0, &error);
63 if (!*root) {
64 PrintAndLogEx(ERR, "json (%s) error on line %d: %s", path, error.line, error.text);
65 retval = PM3_ESOFT;
66 goto out;
69 if (!json_is_array(*root)) {
70 PrintAndLogEx(ERR, "Invalid json (%s) format. root must be an array.", path);
71 retval = PM3_ESOFT;
72 goto out;
75 PrintAndLogEx(SUCCESS, "Loaded file (%s) OK.", path);
76 out:
77 free(path);
78 return retval;
81 static uint8_t GetATRTA1(const uint8_t *atr, size_t atrlen) {
82 if (atrlen > 2) {
83 uint8_t T0 = atr[1];
84 if (T0 & 0x10)
85 return atr[2];
88 return 0x11; // default value is 0x11, corresponding to fmax=5 MHz, Fi=372, Di=1.
91 static int DiArray[] = {
92 0, // b0000 RFU
93 1, // b0001
97 16,
98 32, // b0110
99 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
102 0, // b1010 RFU
104 0, // ...
107 0 // b1111 RFU
110 static int FiArray[] = {
111 372, // b0000 Historical note: in ISO/IEC 7816-3:1989, this was assigned to cards with internal clock
112 372, // b0001
113 558, // b0010
114 744, // b0011
115 1116, // b0100
116 1488, // b0101
117 1860, // b0110
118 0, // b0111 RFU
119 0, // b1000 RFU
120 512, // b1001
121 768, // b1010
122 1024, // b1011
123 1536, // b1100
124 2048, // b1101
125 0, // b1110 RFU
126 0 // b1111 RFU
129 static float FArray[] = {
130 4, // b0000 Historical note: in ISO/IEC 7816-3:1989, this was assigned to cards with internal clock
131 5, // b0001
132 6, // b0010
133 8, // b0011
134 12, // b0100
135 16, // b0101
136 20, // b0110
137 0, // b0111 RFU
138 0, // b1000 RFU
139 5, // b1001
140 7.5, // b1010
141 10, // b1011
142 15, // b1100
143 20, // b1101
144 0, // b1110 RFU
145 0 // b1111 RFU
148 static int GetATRDi(uint8_t *atr, size_t atrlen) {
149 uint8_t TA1 = GetATRTA1(atr, atrlen);
150 return DiArray[TA1 & 0x0F]; // The 4 low-order bits of TA1 (4th MSbit to 1st LSbit) encode Di
153 static int GetATRFi(uint8_t *atr, size_t atrlen) {
154 uint8_t TA1 = GetATRTA1(atr, atrlen);
155 return FiArray[TA1 >> 4]; // The 4 high-order bits of TA1 (8th MSbit to 5th LSbit) encode fmax and Fi
158 static float GetATRF(uint8_t *atr, size_t atrlen) {
159 uint8_t TA1 = GetATRTA1(atr, atrlen);
160 return FArray[TA1 >> 4]; // The 4 high-order bits of TA1 (8th MSbit to 5th LSbit) encode fmax and Fi
163 static void PrintATR(uint8_t *atr, size_t atrlen) {
165 uint8_t T0 = atr[1];
166 uint8_t K = T0 & 0x0F;
167 uint8_t T1len = 0, TD1len = 0, TDilen = 0;
168 bool protocol_T0_present = true;
169 bool protocol_T15_present = false;
171 if (T0 & 0x10) {
172 PrintAndLogEx(INFO, " - TA1 (Maximum clock frequency, proposed bit duration) [ 0x%02x ]", atr[2 + T1len]);
173 T1len++;
176 if (T0 & 0x20) {
177 PrintAndLogEx(INFO, " - TB1 (Deprecated: VPP requirements) [ 0x%02x ]", atr[2 + T1len]);
178 T1len++;
181 if (T0 & 0x40) {
182 PrintAndLogEx(INFO, " - TC1 (Extra delay between bytes required by card) [ 0x%02x ]", atr[2 + T1len]);
183 T1len++;
186 if (T0 & 0x80) {
187 uint8_t TD1 = atr[2 + T1len];
188 PrintAndLogEx(INFO, " - TD1 (First offered transmission protocol, presence of TA2..TD2) [ 0x%02x ] Protocol " _GREEN_("T%d"), TD1, TD1 & 0x0f);
189 protocol_T0_present = false;
190 if ((TD1 & 0x0f) == 0) {
191 protocol_T0_present = true;
193 if ((TD1 & 0x0f) == 15) {
194 protocol_T15_present = true;
197 T1len++;
199 if (TD1 & 0x10) {
200 PrintAndLogEx(INFO, " - TA2 (Specific protocol and parameters to be used after the ATR) [ 0x%02x ]", atr[2 + T1len + TD1len]);
201 TD1len++;
203 if (TD1 & 0x20) {
204 PrintAndLogEx(INFO, " - TB2 (Deprecated: VPP precise voltage requirement) [ 0x%02x ]", atr[2 + T1len + TD1len]);
205 TD1len++;
207 if (TD1 & 0x40) {
208 PrintAndLogEx(INFO, " - TC2 (Maximum waiting time for protocol T=0) [ 0x%02x ]", atr[2 + T1len + TD1len]);
209 TD1len++;
211 if (TD1 & 0x80) {
212 uint8_t TDi = atr[2 + T1len + TD1len];
213 PrintAndLogEx(INFO, " - TD2 (A supported protocol or more global parameters, presence of TA3..TD3) [ 0x%02x ] Protocol " _GREEN_("T%d"), TDi, TDi & 0x0f);
214 if ((TDi & 0x0f) == 0) {
215 protocol_T0_present = true;
217 if ((TDi & 0x0f) == 15) {
218 protocol_T15_present = true;
220 TD1len++;
222 bool nextCycle = true;
223 uint8_t vi = 3;
224 while (nextCycle) {
225 nextCycle = false;
226 if (TDi & 0x10) {
227 PrintAndLogEx(INFO, " - TA%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]);
228 TDilen++;
230 if (TDi & 0x20) {
231 PrintAndLogEx(INFO, " - TB%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]);
232 TDilen++;
234 if (TDi & 0x40) {
235 PrintAndLogEx(INFO, " - TC%d: 0x%02x", vi, atr[2 + T1len + TD1len + TDilen]);
236 TDilen++;
238 if (TDi & 0x80) {
239 TDi = atr[2 + T1len + TD1len + TDilen];
240 PrintAndLogEx(INFO, " - TD%d [ 0x%02x ] Protocol T=%d", vi, TDi, TDi & 0x0f);
241 TDilen++;
243 nextCycle = true;
244 vi++;
250 if (!protocol_T0_present || protocol_T15_present) { // there is CRC Check Byte TCK
251 uint8_t vxor = 0;
252 for (int i = 1; i < atrlen; i++)
253 vxor ^= atr[i];
255 if (vxor)
256 PrintAndLogEx(WARNING, "Invalid check sum. Must be 0 got 0x%02X", vxor);
257 else
258 PrintAndLogEx(INFO, "Check sum OK.");
261 if (atr[0] != 0x3b)
262 PrintAndLogEx(WARNING, "Not a direct convention [ 0x%02x ]", atr[0]);
264 uint8_t calen = 2 + T1len + TD1len + TDilen + K;
266 if (atrlen != calen && atrlen != calen + 1) // may be CRC
267 PrintAndLogEx(WARNING, "Invalid ATR length. len: %zu, T1len: %d, TD1len: %d, TDilen: %d, K: %d", atrlen, T1len, TD1len, TDilen, K);
269 if (K > 0)
270 PrintAndLogEx(DEBUG, "Historical bytes | len %02d | format %02x", K, atr[2 + T1len + TD1len + TDilen]);
272 if (K > 1) {
273 PrintAndLogEx(INFO, " Historical bytes ( %u )", K);
274 print_buffer(&atr[2 + T1len + TD1len + TDilen], K, 1);
278 static int smart_wait(uint8_t *out, int maxoutlen, bool verbose) {
279 int i = 4;
280 uint32_t len;
281 do {
282 clearCommandBuffer();
283 PacketResponseNG resp;
284 if (WaitForResponseTimeout(CMD_SMART_RAW, &resp, 1000)) {
286 if (resp.status != PM3_SUCCESS) {
287 if (verbose) PrintAndLogEx(WARNING, "smart card response status failed");
288 return -3;
291 len = resp.length;
292 if (len == 0) {
293 if (verbose) PrintAndLogEx(WARNING, "smart card response failed");
294 return -2;
297 if (len > maxoutlen) {
298 if (verbose) PrintAndLogEx(ERR, "Response too large. Got %u, expected %d", len, maxoutlen);
299 return -4;
302 memcpy(out, resp.data.asBytes, len);
303 if (len >= 2) {
304 if (verbose) {
307 if (out[len - 2] == 0x90 && out[len - 1] == 0x00) {
308 PrintAndLogEx(SUCCESS, _GREEN_("%02X%02X") " | %s", out[len - 2], out[len - 1], GetAPDUCodeDescription(out[len - 2], out[len - 1]));
309 } else {
310 PrintAndLogEx(SUCCESS, "%02X%02X | %s", out[len - 2], out[len - 1], GetAPDUCodeDescription(out[len - 2], out[len - 1]));
313 } else {
314 if (verbose) {
315 PrintAndLogEx(SUCCESS, " %d | %s", len, sprint_hex_inrow_ex(out, len, 8));
318 return len;
320 } while (i--);
322 if (verbose) {
323 PrintAndLogEx(WARNING, "smart card response timeout");
325 return -1;
328 static int smart_responseEx(uint8_t *out, int maxoutlen, bool verbose) {
330 int datalen = smart_wait(out, maxoutlen, verbose);
331 int totallen = datalen;
332 bool needGetData = false;
334 if (datalen < 2) {
335 goto out;
338 if (out[datalen - 2] == 0x61 || out[datalen - 2] == 0x9F) {
339 needGetData = true;
342 if (needGetData) {
343 // Don't discard data we already received except the SW code.
344 // If we only received 1 byte, this is the echo of INS, we discard it.
345 totallen -= 2;
346 if (totallen == 1) {
347 totallen = 0;
349 int ofs = totallen;
350 maxoutlen -= totallen;
351 PrintAndLogEx(DEBUG, "Keeping data (%d bytes): %s", ofs, sprint_hex(out, ofs));
353 int len = out[datalen - 1];
354 if (len == 0 || len > MAX_APDU_SIZE) {
355 // Cap the data length or the smartcard may send us a buffer we can't handle
356 len = MAX_APDU_SIZE;
358 if (maxoutlen < len) {
359 // We don't have enough buffer to hold the next part
360 goto out;
363 if (verbose) PrintAndLogEx(INFO, "Requesting " _YELLOW_("0x%02X") " bytes response", len);
365 uint8_t cmd_getresp[] = {0x00, ISO7816_GET_RESPONSE, 0x00, 0x00, len};
366 smart_card_raw_t *payload = calloc(1, sizeof(smart_card_raw_t) + sizeof(cmd_getresp));
367 payload->flags = SC_RAW | SC_LOG;
368 payload->len = sizeof(cmd_getresp);
369 payload->wait_delay = 0;
370 memcpy(payload->data, cmd_getresp, sizeof(cmd_getresp));
372 clearCommandBuffer();
373 SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + sizeof(cmd_getresp));
374 free(payload);
376 datalen = smart_wait(&out[ofs], maxoutlen, verbose);
378 if (datalen < 2) {
379 goto out;
382 // data wo ACK
383 if (datalen != len + 2) {
384 // data with ACK
385 if (datalen == len + 2 + 1) { // 2 - response, 1 - ACK
386 if (out[ofs] != ISO7816_GET_RESPONSE) {
387 if (verbose) {
388 PrintAndLogEx(ERR, "GetResponse ACK error. len 0x%x | data[0] %02X", len, out[0]);
390 datalen = 0;
391 goto out;
394 datalen--;
395 memmove(&out[ofs], &out[ofs + 1], datalen);
396 totallen += datalen;
397 } else {
398 // wrong length
399 if (verbose) {
400 PrintAndLogEx(WARNING, "GetResponse wrong length. Must be 0x%02X got 0x%02X", len, datalen - 3);
406 out:
407 return totallen;
410 static int smart_response(uint8_t *out, int maxoutlen) {
411 return smart_responseEx(out, maxoutlen, true);
414 static int CmdSmartRaw(const char *Cmd) {
415 CLIParserContext *ctx;
416 CLIParserInit(&ctx, "smart raw",
417 "Sends raw bytes to card",
418 "smart raw -s -0 -d 00a404000e315041592e5359532e4444463031 -> `1PAY.SYS.DDF01` PPSE directory with get ATR\n"
419 "smart raw -0 -d 00a404000e325041592e5359532e4444463031 -> `2PAY.SYS.DDF01` PPSE directory\n"
420 "smart raw -0 -t -d 00a4040007a0000000041010 -> Mastercard\n"
421 "smart raw -0 -t -d 00a4040007a0000000031010 -> Visa"
424 void *argtable[] = {
425 arg_param_begin,
426 arg_lit0("r", NULL, "do not read response"),
427 arg_lit0("a", NULL, "active smartcard without select (reset sc module)"),
428 arg_lit0("s", NULL, "active smartcard with select (get ATR)"),
429 arg_lit0("t", "tlv", "executes TLV decoder if it possible"),
430 arg_lit0("0", NULL, "use protocol T=0"),
431 arg_int0(NULL, "timeout", "<ms>", "Timeout in MS waiting for SIM to respond. (def 337ms)"),
432 arg_str1("d", "data", "<hex>", "bytes to send"),
433 arg_param_end
435 CLIExecWithReturn(ctx, Cmd, argtable, true);
437 bool reply = (arg_get_lit(ctx, 1) == false);
438 bool active = arg_get_lit(ctx, 2);
439 bool active_select = arg_get_lit(ctx, 3);
440 bool decode_tlv = arg_get_lit(ctx, 4);
441 bool use_t0 = arg_get_lit(ctx, 5);
442 int timeout = arg_get_int_def(ctx, 6, -1);
444 int dlen = 0;
445 uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
446 int res = CLIParamHexToBuf(arg_get_str(ctx, 7), data, sizeof(data), &dlen);
447 CLIParserFree(ctx);
449 if (res) {
450 PrintAndLogEx(FAILED, "Error parsing bytes");
451 return PM3_EINVARG;
454 smart_card_raw_t *payload = calloc(1, sizeof(smart_card_raw_t) + dlen);
455 if (payload == NULL) {
456 PrintAndLogEx(FAILED, "failed to allocate memory");
457 return PM3_EMALLOC;
459 payload->len = dlen;
460 memcpy(payload->data, data, dlen);
462 payload->flags = SC_LOG;
463 if (active || active_select) {
465 payload->flags |= (SC_CONNECT | SC_CLEARLOG);
466 if (active_select)
467 payload->flags |= SC_SELECT;
470 payload->wait_delay = 0;
471 if (timeout > -1) {
472 payload->flags |= SC_WAIT;
473 payload->wait_delay = timeout;
475 PrintAndLogEx(DEBUG, "SIM Card timeout... %u ms", payload->wait_delay);
477 if (dlen > 0) {
478 if (use_t0)
479 payload->flags |= SC_RAW_T0;
480 else
481 payload->flags |= SC_RAW;
484 uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
485 if (buf == NULL) {
486 PrintAndLogEx(DEBUG, "failed to allocate memory");
487 free(payload);
488 return PM3_EMALLOC;
491 clearCommandBuffer();
492 SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + dlen);
494 if (reply == false) {
495 goto out;
498 // reading response from smart card
499 int len = smart_response(buf, PM3_CMD_DATA_SIZE);
500 if (len < 0) {
501 free(payload);
502 free(buf);
503 return PM3_ESOFT;
506 if (buf[0] == 0x6C) {
508 // request more bytes to download
509 data[4] = buf[1];
510 memcpy(payload->data, data, dlen);
511 clearCommandBuffer();
512 SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + dlen);
514 len = smart_response(buf, PM3_CMD_DATA_SIZE);
516 data[4] = 0;
519 if (decode_tlv && len > 4) {
520 TLVPrintFromBuffer(buf, len - 2);
521 } else {
522 if (len > 2) {
523 PrintAndLogEx(INFO, "Response data:");
524 PrintAndLogEx(INFO, " # | bytes | ascii");
525 PrintAndLogEx(INFO, "---+-------------------------------------------------+-----------------");
526 print_hex_break(buf, len, 16);
529 PrintAndLogEx(NORMAL, "");
530 out:
531 free(payload);
532 free(buf);
533 return PM3_SUCCESS;
536 static int CmdSmartUpgrade(const char *Cmd) {
537 PrintAndLogEx(INFO, "--------------------------------------------------------------------");
538 PrintAndLogEx(WARNING, _RED_("WARNING") " - sim module firmware upgrade");
539 PrintAndLogEx(WARNING, _RED_("A dangerous command, do wrong and you could brick the sim module"));
540 PrintAndLogEx(INFO, "--------------------------------------------------------------------");
541 PrintAndLogEx(NORMAL, "");
543 CLIParserContext *ctx;
544 CLIParserInit(&ctx, "smart upgrade",
545 "Upgrade RDV4 sim module firmware",
546 "smart upgrade -f sim014.bin"
549 void *argtable[] = {
550 arg_param_begin,
551 arg_str1("f", "file", "<fn>", "Specify firmware file name"),
552 arg_param_end
554 CLIExecWithReturn(ctx, Cmd, argtable, true);
555 int fnlen = 0;
556 char filename[FILE_PATH_SIZE] = {0};
557 CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
558 CLIParserFree(ctx);
560 char *bin_extension = filename;
561 char *dot_position = NULL;
562 while ((dot_position = strchr(bin_extension, '.')) != NULL) {
563 bin_extension = dot_position + 1;
566 // generate filename for the related SHA512 hash file
567 char sha512filename[FILE_PATH_SIZE] = {'\0'};
568 if (!strcmp(bin_extension, "BIN") || !strcmp(bin_extension, "bin")) {
569 memcpy(sha512filename, filename, strlen(filename) - strlen("bin"));
570 strcat(sha512filename, "sha512.txt");
571 } else {
572 PrintAndLogEx(FAILED, "Filename extension of firmware upgrade file must be .BIN");
573 return PM3_ESOFT;
576 PrintAndLogEx(INFO, "firmware file " _YELLOW_("%s"), filename);
577 PrintAndLogEx(INFO, "Checking integrity " _YELLOW_("%s"), sha512filename);
579 // load firmware file
580 size_t firmware_size = 0;
581 uint8_t *firmware = NULL;
582 if (loadFile_safe(filename, "", (void **)&firmware, &firmware_size) != PM3_SUCCESS) {
583 PrintAndLogEx(FAILED, "Firmware file " _YELLOW_("%s") " not found or locked.", filename);
584 return PM3_EFILE;
587 // load sha512 file
588 size_t sha512_size = 0;
589 char *hashstring = NULL;
590 if (loadFile_safe(sha512filename, "", (void **)&hashstring, &sha512_size) != PM3_SUCCESS) {
591 PrintAndLogEx(FAILED, "SHA-512 file not found or locked.");
592 free(firmware);
593 return PM3_EFILE;
596 if (sha512_size < 128) {
597 PrintAndLogEx(FAILED, "SHA-512 file wrong size");
598 free(hashstring);
599 free(firmware);
600 return PM3_ESOFT;
602 hashstring[128] = '\0';
604 int hash1n = 0;
605 uint8_t hash_1[64];
606 if (param_gethex_ex(hashstring, 0, hash_1, &hash1n) && hash1n != 128) {
607 PrintAndLogEx(FAILED, "Couldn't read SHA-512 file. expect 128 hex bytes, got ( "_RED_("%d") " )", hash1n);
608 free(hashstring);
609 free(firmware);
610 return PM3_ESOFT;
613 uint8_t hash_2[64];
614 if (sha512hash(firmware, firmware_size, hash_2)) {
615 PrintAndLogEx(FAILED, "Couldn't calculate SHA-512 of firmware");
616 free(hashstring);
617 free(firmware);
618 return PM3_ESOFT;
621 if (memcmp(hash_1, hash_2, 64)) {
622 PrintAndLogEx(FAILED, "Couldn't verify integrity of firmware file " _RED_("(wrong SHA-512 hash)"));
623 free(hashstring);
624 free(firmware);
625 return PM3_ESOFT;
627 free(hashstring);
629 PrintAndLogEx(INFO, _GREEN_("Don\'t turn off your PM3!"));
630 PrintAndLogEx(SUCCESS, "Sim module firmware uploading to PM3...");
632 PacketResponseNG resp;
634 //Send to device
635 uint32_t index = 0;
636 uint32_t bytes_sent = 0;
637 uint32_t bytes_remaining = firmware_size;
639 while (bytes_remaining > 0) {
641 struct {
642 uint32_t idx;
643 uint32_t bytes_in_packet;
644 uint16_t crc;
645 uint8_t data[400];
646 } PACKED upload;
648 uint32_t bytes_in_packet = MIN(sizeof(upload.data), bytes_remaining);
650 upload.idx = index + bytes_sent;
651 upload.bytes_in_packet = bytes_in_packet;
652 memcpy(upload.data, firmware + bytes_sent, bytes_in_packet);
654 uint8_t a = 0, b = 0;
655 compute_crc(CRC_14443_A, upload.data, bytes_in_packet, &a, &b);
656 upload.crc = (a << 8 | b);
658 clearCommandBuffer();
659 SendCommandNG(CMD_SMART_UPLOAD, (uint8_t *)&upload, sizeof(upload));
660 if (!WaitForResponseTimeout(CMD_SMART_UPLOAD, &resp, 2000)) {
661 PrintAndLogEx(WARNING, "timeout while waiting for reply.");
662 free(firmware);
663 return PM3_ETIMEOUT;
666 if (resp.status != PM3_SUCCESS) {
667 PrintAndLogEx(WARNING, "uploading to device failed");
668 free(firmware);
669 return resp.status;
671 bytes_remaining -= bytes_in_packet;
672 bytes_sent += bytes_in_packet;
673 PrintAndLogEx(INPLACE, "%d bytes sent", bytes_sent);
675 PrintAndLogEx(NORMAL, "");
676 PrintAndLogEx(SUCCESS, "Sim module firmware updating...");
678 // trigger the firmware upgrade
679 clearCommandBuffer();
680 struct {
681 uint16_t fw_size;
682 uint16_t crc;
683 } PACKED payload;
684 payload.fw_size = firmware_size;
686 uint8_t a = 0, b = 0;
687 compute_crc(CRC_14443_A, firmware, firmware_size, &a, &b);
688 payload.crc = (a << 8 | b);
690 free(firmware);
691 SendCommandNG(CMD_SMART_UPGRADE, (uint8_t *)&payload, sizeof(payload));
692 if (!WaitForResponseTimeout(CMD_SMART_UPGRADE, &resp, 2500)) {
693 PrintAndLogEx(WARNING, "timeout while waiting for reply.");
694 return PM3_ETIMEOUT;
697 if (resp.status == PM3_SUCCESS) {
698 PrintAndLogEx(SUCCESS, "Sim module firmware upgrade " _GREEN_("successful"));
699 PrintAndLogEx(HINT, "run " _YELLOW_("`hw status`") " to validate the fw version ");
700 } else {
701 PrintAndLogEx(FAILED, "Sim module firmware upgrade " _RED_("failed"));
703 return PM3_SUCCESS;
706 static int CmdSmartInfo(const char *Cmd) {
707 CLIParserContext *ctx;
708 CLIParserInit(&ctx, "smart info",
709 "Extract more detailed information from smart card.",
710 "smart info -v"
713 void *argtable[] = {
714 arg_param_begin,
715 arg_lit0("v", "verbose", "verbose output"),
716 arg_param_end
718 CLIExecWithReturn(ctx, Cmd, argtable, true);
719 bool verbose = arg_get_lit(ctx, 1);
720 CLIParserFree(ctx);
722 clearCommandBuffer();
723 SendCommandNG(CMD_SMART_ATR, NULL, 0);
724 PacketResponseNG resp;
725 if (WaitForResponseTimeout(CMD_SMART_ATR, &resp, 2500) == false) {
726 if (verbose) {
727 PrintAndLogEx(WARNING, "smart card timeout");
729 return PM3_ETIMEOUT;
732 if (resp.status != PM3_SUCCESS) {
733 if (verbose) {
734 PrintAndLogEx(WARNING, "smart card select failed");
736 return PM3_ESOFT;
739 smart_card_atr_t card;
740 memcpy(&card, (smart_card_atr_t *)resp.data.asBytes, sizeof(smart_card_atr_t));
742 // print header
743 PrintAndLogEx(INFO, "--- " _CYAN_("Smartcard Information") " ---------");
744 PrintAndLogEx(INFO, "ISO7816-3 ATR... %s", sprint_hex(card.atr, card.atr_len));
745 // convert bytes to str.
746 char *hexstr = calloc((card.atr_len << 1) + 1, sizeof(uint8_t));
747 if (hexstr == NULL) {
748 PrintAndLogEx(WARNING, "failed to allocate memory");
749 return PM3_EMALLOC;
752 hex_to_buffer((uint8_t *)hexstr, card.atr, card.atr_len, (card.atr_len << 1), 0, 0, true);
753 PrintAndLogEx(INFO, "Fingerprint..... %s", getAtrInfo(hexstr));
754 free(hexstr);
756 // print ATR
757 PrintAndLogEx(INFO, "ATR");
758 PrintATR(card.atr, card.atr_len);
760 // print D/F (brom byte TA1 or defaults)
761 PrintAndLogEx(NORMAL, "");
762 PrintAndLogEx(INFO, "D/F (TA1)");
763 int Di = GetATRDi(card.atr, card.atr_len);
764 int Fi = GetATRFi(card.atr, card.atr_len);
765 float F = GetATRF(card.atr, card.atr_len);
766 if (GetATRTA1(card.atr, card.atr_len) == 0x11)
767 PrintAndLogEx(INFO, "Using default values...");
769 PrintAndLogEx(INFO, "\t- Di %d", Di);
770 PrintAndLogEx(INFO, "\t- Fi %d", Fi);
771 PrintAndLogEx(INFO, "\t- F %.1f MHz", F);
773 if (Di && Fi) {
774 PrintAndLogEx(INFO, "\t- Cycles/ETU %d", Fi / Di);
775 PrintAndLogEx(INFO, "\t- %.1f bits/sec at 4 MHz", (float)4000000 / (Fi / Di));
776 PrintAndLogEx(INFO, "\t- %.1f bits/sec at Fmax (%.1fMHz)", (F * 1000000) / (Fi / Di), F);
777 } else {
778 PrintAndLogEx(WARNING, "\t- Di or Fi is RFU.");
781 return PM3_SUCCESS;
784 static int CmdSmartReader(const char *Cmd) {
785 CLIParserContext *ctx;
786 CLIParserInit(&ctx, "smart reader",
787 "Act as a smart card reader.",
788 "smart reader"
791 void *argtable[] = {
792 arg_param_begin,
793 arg_lit0("v", "verbose", "verbose output"),
794 arg_param_end
796 CLIExecWithReturn(ctx, Cmd, argtable, true);
797 bool verbose = arg_get_lit(ctx, 1);
798 CLIParserFree(ctx);
800 clearCommandBuffer();
801 SendCommandNG(CMD_SMART_ATR, NULL, 0);
802 PacketResponseNG resp;
803 if (WaitForResponseTimeout(CMD_SMART_ATR, &resp, 2500) == false) {
804 if (verbose) {
805 PrintAndLogEx(WARNING, "smart card select failed");
807 return PM3_ETIMEOUT;
810 if (resp.status != PM3_SUCCESS) {
811 if (verbose) {
812 PrintAndLogEx(WARNING, "smart card select failed");
814 return PM3_ESOFT;
816 smart_card_atr_t *card = (smart_card_atr_t *)resp.data.asBytes;
817 PrintAndLogEx(INFO, "ISO7816-3 ATR... %s", sprint_hex(card->atr, card->atr_len));
819 // convert bytes to str.
820 char *hexstr = calloc((card->atr_len << 1) + 1, sizeof(uint8_t));
821 if (hexstr == NULL) {
822 PrintAndLogEx(WARNING, "failed to allocate memory");
823 return PM3_EMALLOC;
826 hex_to_buffer((uint8_t *)hexstr, card->atr, card->atr_len, (card->atr_len << 1), 0, 0, true);
827 PrintAndLogEx(INFO, "Fingerprint..... %s", getAtrInfo(hexstr));
828 free(hexstr);
829 return PM3_SUCCESS;
832 static int CmdSmartSetClock(const char *Cmd) {
834 CLIParserContext *ctx;
835 CLIParserInit(&ctx, "smart setclock",
836 "Set clock speed for smart card interface.",
837 "smart setclock --4mhz\n"
838 "smart setclock --16mhz"
841 void *argtable[] = {
842 arg_param_begin,
843 arg_lit0(NULL, "16mhz", "16 MHz clock speed"),
844 arg_lit0(NULL, "8mhz", "8 MHz clock speed"),
845 arg_lit0(NULL, "4mhz", "4 MHz clock speed"),
846 arg_param_end
848 CLIExecWithReturn(ctx, Cmd, argtable, false);
849 bool c16 = arg_get_lit(ctx, 1);
850 bool c8 = arg_get_lit(ctx, 2);
851 bool c4 = arg_get_lit(ctx, 3);
852 CLIParserFree(ctx);
854 if ((c16 + c8 + c4) > 1) {
855 PrintAndLogEx(WARNING, "Only one clock speed can be used at a time");
856 return PM3_EINVARG;
859 struct {
860 uint32_t new_clk;
861 } PACKED payload;
863 if (c16)
864 payload.new_clk = 0;
865 else if (c8)
866 payload.new_clk = 1;
867 else if (c4)
868 payload.new_clk = 2;
870 clearCommandBuffer();
871 SendCommandNG(CMD_SMART_SETCLOCK, (uint8_t *)&payload, sizeof(payload));
872 PacketResponseNG resp;
873 if (!WaitForResponseTimeout(CMD_SMART_SETCLOCK, &resp, 2500)) {
874 PrintAndLogEx(WARNING, "smart card select failed");
875 return PM3_ETIMEOUT;
878 if (resp.status != PM3_SUCCESS) {
879 PrintAndLogEx(WARNING, "smart card set clock failed");
880 return PM3_ESOFT;
883 switch (payload.new_clk) {
884 case 0:
885 PrintAndLogEx(SUCCESS, "Clock changed to " _GREEN_("16") " MHz giving " _GREEN_("10800") " baudrate");
886 break;
887 case 1:
888 PrintAndLogEx(SUCCESS, "Clock changed to " _GREEN_("8") " MHz giving " _GREEN_("21600") " baudrate");
889 break;
890 case 2:
891 PrintAndLogEx(SUCCESS, "Clock changed to " _GREEN_("4") " MHz giving " _GREEN_("86400") " baudrate");
892 break;
893 default:
894 break;
896 return PM3_SUCCESS;
899 static int CmdSmartList(const char *Cmd) {
900 return CmdTraceListAlias(Cmd, "smart", "7816");
903 static void smart_brute_prim(void) {
905 uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
906 if (!buf)
907 return;
909 uint8_t get_card_data[] = {
910 0x80, 0xCA, 0x9F, 0x13, 0x00,
911 0x80, 0xCA, 0x9F, 0x17, 0x00,
912 0x80, 0xCA, 0x9F, 0x36, 0x00,
913 0x80, 0xCA, 0x9F, 0x4f, 0x00
916 PrintAndLogEx(INFO, "Reading primitives");
918 for (int i = 0; i < ARRAYLEN(get_card_data); i += 5) {
920 smart_card_raw_t *payload = calloc(1, sizeof(smart_card_raw_t) + 5);
921 payload->flags = SC_RAW_T0;
922 payload->len = 5;
923 payload->wait_delay = 0;
924 memcpy(payload->data, get_card_data + i, 5);
926 clearCommandBuffer();
927 SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + 5);
928 free(payload);
930 int len = smart_responseEx(buf, PM3_CMD_DATA_SIZE, false);
931 if (len > 2) {
932 PrintAndLogEx(SUCCESS, "\tHEX %d |: %s", len, sprint_hex(buf, len));
935 free(buf);
938 static int smart_brute_sfi(bool decodeTLV) {
940 uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
941 if (buf == NULL)
942 return 1;
944 int len;
945 // READ RECORD
946 uint8_t READ_RECORD[] = {0x00, 0xB2, 0x00, 0x00, 0x00};
947 PrintAndLogEx(INFO, "Start SFI brute forcing");
949 for (uint8_t sfi = 1; sfi <= 31; sfi++) {
951 PrintAndLogEx(NORMAL, "." NOLF);
953 for (uint16_t rec = 1; rec <= 255; rec++) {
955 if (kbd_enter_pressed()) {
956 PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
957 free(buf);
958 return 1;
961 READ_RECORD[2] = rec;
962 READ_RECORD[3] = (sfi << 3) | 4;
964 smart_card_raw_t *payload = calloc(1, sizeof(smart_card_raw_t) + sizeof(READ_RECORD));
965 payload->flags = SC_RAW_T0;
966 payload->len = sizeof(READ_RECORD);
967 payload->wait_delay = 0;
968 memcpy(payload->data, READ_RECORD, sizeof(READ_RECORD));
970 clearCommandBuffer();
971 SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + sizeof(READ_RECORD));
973 len = smart_responseEx(buf, PM3_CMD_DATA_SIZE, false);
975 if (buf[0] == 0x6C) {
976 READ_RECORD[4] = buf[1];
978 memcpy(payload->data, READ_RECORD, sizeof(READ_RECORD));
979 clearCommandBuffer();
980 SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + sizeof(READ_RECORD));
981 len = smart_responseEx(buf, PM3_CMD_DATA_SIZE, false);
983 READ_RECORD[4] = 0;
986 free(payload);
988 if (len > 4) {
990 PrintAndLogEx(SUCCESS, "\n\t file %02d, record %02d found", sfi, rec);
992 uint8_t modifier = (buf[0] == 0xC0) ? 1 : 0;
994 if (decodeTLV) {
995 if (!TLVPrintFromBuffer(buf + modifier, len - 2 - modifier)) {
996 PrintAndLogEx(SUCCESS, "\tHEX: %s", sprint_hex(buf, len));
1000 memset(buf, 0x00, PM3_CMD_DATA_SIZE);
1003 free(buf);
1004 return 0;
1007 static void smart_brute_options(bool decodeTLV) {
1009 uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
1010 if (!buf)
1011 return;
1013 // Get processing options command
1014 uint8_t GET_PROCESSING_OPTIONS[] = {0x80, 0xA8, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00};
1016 smart_card_raw_t *payload = calloc(1, sizeof(smart_card_raw_t) + sizeof(GET_PROCESSING_OPTIONS));
1017 payload->flags = SC_RAW_T0;
1018 payload->len = sizeof(GET_PROCESSING_OPTIONS);
1019 memcpy(payload->data, GET_PROCESSING_OPTIONS, sizeof(GET_PROCESSING_OPTIONS));
1021 clearCommandBuffer();
1022 SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + sizeof(GET_PROCESSING_OPTIONS));
1023 free(payload);
1025 int len = smart_responseEx(buf, PM3_CMD_DATA_SIZE, false);
1026 if (len > 4) {
1027 PrintAndLogEx(SUCCESS, "Got processing options");
1028 if (decodeTLV) {
1029 TLVPrintFromBuffer(buf, len - 2);
1031 } else {
1032 PrintAndLogEx(FAILED, "Getting processing options failed");
1035 free(buf);
1038 static int CmdSmartBruteforceSFI(const char *Cmd) {
1039 CLIParserContext *ctx;
1040 CLIParserInit(&ctx, "smart brute",
1041 "Tries to bruteforce SFI, using a known list of AID's",
1042 "smart brute -t"
1045 void *argtable[] = {
1046 arg_param_begin,
1047 arg_lit0("t", "tlv", "executes TLV decoder if it possible"),
1048 // arg_lit0("0", NULL, "use protocol T=0"),
1049 arg_param_end
1051 CLIExecWithReturn(ctx, Cmd, argtable, true);
1052 bool decode_tlv = arg_get_lit(ctx, 1);
1053 // bool use_t0 = arg_get_lit(ctx, 2);
1054 CLIParserFree(ctx);
1056 const char *SELECT = "00a40400%02zu%s";
1058 // uint8_t GENERATE_AC[] = {0x80, 0xAE};
1059 // uint8_t GET_CHALLENGE[] = {0x00, 0x84, 0x00};
1060 // uint8_t GET_DATA[] = {0x80, 0xCA, 0x00, 0x00, 0x00};
1061 // uint8_t SELECT[] = {0x00, 0xA4, 0x04, 0x00};
1062 // uint8_t UNBLOCK_PIN[] = {0x84, 0x24, 0x00, 0x00, 0x00};
1063 // uint8_t VERIFY[] = {0x00, 0x20, 0x00, 0x80};
1065 PrintAndLogEx(INFO, "Importing AID list");
1066 json_t *root = NULL;
1067 smart_loadjson("aidlist", &root);
1069 uint8_t *buf = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
1070 if (!buf)
1071 return PM3_EMALLOC;
1073 PrintAndLogEx(INFO, "Selecting card");
1074 if (!smart_select(false, NULL)) {
1075 free(buf);
1076 return PM3_ESOFT;
1079 char *caid = NULL;
1081 for (int i = 0; i < json_array_size(root); i++) {
1083 PrintAndLogEx(NORMAL, "+" NOLF);
1085 if (caid)
1086 free(caid);
1088 json_t *data, *jaid;
1090 data = json_array_get(root, i);
1091 if (json_is_object(data) == false) {
1092 PrintAndLogEx(ERR, "\ndata %d is not an object\n", i + 1);
1093 json_decref(root);
1094 free(buf);
1095 return PM3_ESOFT;
1098 jaid = json_object_get(data, "AID");
1099 if (json_is_string(jaid) == false) {
1100 PrintAndLogEx(ERR, "\nAID data [%d] is not a string", i + 1);
1101 json_decref(root);
1102 free(buf);
1103 return PM3_ESOFT;
1106 const char *aid = json_string_value(jaid);
1107 if (aid == false)
1108 continue;
1110 size_t aidlen = strlen(aid);
1111 caid = calloc(8 + 2 + aidlen + 1, sizeof(uint8_t));
1112 snprintf(caid, 8 + 2 + aidlen + 1, SELECT, aidlen >> 1, aid);
1114 int hexlen = 0;
1115 uint8_t cmddata[PM3_CMD_DATA_SIZE];
1116 int res = param_gethex_to_eol(caid, 0, cmddata, sizeof(cmddata), &hexlen);
1117 if (res)
1118 continue;
1120 smart_card_raw_t *payload = calloc(1, sizeof(smart_card_raw_t) + hexlen);
1121 payload->flags = SC_RAW_T0;
1122 payload->len = hexlen;
1123 payload->wait_delay = 0;
1124 memcpy(payload->data, cmddata, hexlen);
1125 clearCommandBuffer();
1126 SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + hexlen);
1127 free(payload);
1129 int len = smart_responseEx(buf, PM3_CMD_DATA_SIZE, false);
1130 if (len < 3)
1131 continue;
1133 json_t *jvendor, *jname;
1134 jvendor = json_object_get(data, "Vendor");
1135 if (json_is_string(jvendor) == false) {
1136 PrintAndLogEx(ERR, "Vendor data [%d] is not a string", i + 1);
1137 continue;
1140 const char *vendor = json_string_value(jvendor);
1141 if (!vendor)
1142 continue;
1144 jname = json_object_get(data, "Name");
1145 if (json_is_string(jname) == false) {
1146 PrintAndLogEx(ERR, "Name data [%d] is not a string", i + 1);
1147 continue;
1149 const char *name = json_string_value(jname);
1150 if (!name)
1151 continue;
1153 PrintAndLogEx(SUCCESS, "\nAID %s | %s | %s", aid, vendor, name);
1155 smart_brute_options(decode_tlv);
1157 smart_brute_prim();
1159 smart_brute_sfi(decode_tlv);
1161 PrintAndLogEx(SUCCESS, "\nSFI brute force done\n");
1164 if (caid)
1165 free(caid);
1167 free(buf);
1168 json_decref(root);
1170 PrintAndLogEx(SUCCESS, "\nSearch completed.");
1171 return PM3_SUCCESS;
1174 static void atsToEmulatedAtr(uint8_t *ats, uint8_t *atr, int *atrLen) {
1175 uint8_t historicalLen = 0;
1176 uint8_t offset = 2;
1178 if (ats[0] < 2) {
1179 historicalLen = 0;
1180 } else {
1182 if ((ats[1] & 64) != 0) {
1183 offset++;
1185 if ((ats[1] & 32) != 0) {
1186 offset++;
1188 if ((ats[1] & 16) != 0) {
1189 offset++;
1192 if (offset >= ats[0]) {
1193 historicalLen = 0;
1194 } else {
1195 historicalLen = ats[0] - offset;
1199 atr[0] = 0x3B;
1200 atr[1] = 0x80 | historicalLen;
1201 atr[2] = 0x80;
1202 atr[3] = 0x01;
1204 uint8_t tck = atr[1] ^ atr[2] ^ atr[3];
1205 for (uint8_t i = 0; i < historicalLen; ++i) {
1206 atr[4 + i] = ats[offset + i];
1207 tck = tck ^ ats[offset + i];
1209 atr[4 + historicalLen] = tck;
1211 *atrLen = 5 + historicalLen;
1214 static void atqbToEmulatedAtr(uint8_t *atqb, uint8_t cid, uint8_t *atr, int *atrLen) {
1215 atr[0] = 0x3B;
1216 atr[1] = 0x80 | 8;
1217 atr[2] = 0x80;
1218 atr[3] = 0x01;
1220 memcpy(atr + 4, atqb, 7);
1221 atr[11] = cid >> 4;
1223 uint8_t tck = 0;
1224 for (int i = 1; i < 12; ++i) {
1225 tck = tck ^ atr[i];
1227 atr[12] = tck;
1229 *atrLen = 13;
1232 static int CmdPCSC(const char *Cmd) {
1233 CLIParserContext *ctx;
1234 CLIParserInit(&ctx, "smart pcsc",
1235 "Make pm3 available to host OS smartcard driver via vpcd to enable use with other software such as GlobalPlatform Pro",
1236 "Requires the virtual smartcard daemon to be installed and running\n"
1237 " see https://frankmorgner.github.io/vsmartcard/virtualsmartcard/README.html\n"
1238 "note:\n"
1239 " `-v` shows APDU transactions between OS and card\n"
1242 void *argtable[] = {
1243 arg_param_begin,
1244 arg_str0(NULL, "host", "<str>", "vpcd socket host (default: localhost)"),
1245 arg_str0("p", "port", "<int>", "vpcd socket port (default: 35963)"),
1246 arg_lit0("v", "verbose", "display APDU transactions between OS and card"),
1247 arg_lit0("a", NULL, "use ISO 14443A contactless interface"),
1248 arg_lit0("b", NULL, "use ISO 14443B contactless interface"),
1249 // arg_lit0("v", NULL, "use ISO 15693 contactless interface"),
1250 arg_lit0("c", NULL, "use ISO 7816 contact interface"),
1251 arg_param_end
1253 CLIExecWithReturn(ctx, Cmd, argtable, true);
1255 uint8_t host[100] = {0};
1256 int hostLen = sizeof(host) - 1; // CLIGetStrWithReturn does not guarantee string to be null-terminated
1257 CLIGetStrWithReturn(ctx, 1, host, &hostLen);
1258 if (hostLen == 0) {
1259 strcpy((char *) host, "localhost");
1262 uint8_t port[6] = {0};
1263 int portLen = sizeof(port) - 1; // CLIGetStrWithReturn does not guarantee string to be null-terminated
1264 CLIGetStrWithReturn(ctx, 2, port, &portLen);
1265 if (portLen == 0) {
1266 strcpy((char *) port, "35963");
1269 bool verbose = arg_get_lit(ctx, 3);
1270 bool use14a = arg_get_lit(ctx, 4);
1271 bool use14b = arg_get_lit(ctx, 5);
1272 // bool use15 = arg_get_lit(ctx, 6);
1273 bool use_contact = arg_get_lit(ctx, 6);
1274 CLIParserFree(ctx);
1276 mbedtls_net_context netCtx;
1277 mbedtls_net_init(&netCtx);
1279 PrintAndLogEx(INFO, "Relaying PM3 to host OS pcsc daemon");
1280 PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
1282 uint8_t cmdbuf[512] = {0};
1283 iso14a_card_select_t card14a;
1284 iso14b_card_select_t card14b;
1285 smart_card_atr_t card;
1287 bool have_card = false;
1288 Iso7816CommandChannel card_type = CC_CONTACT;
1289 isodep_state_t cl_proto = ISODEP_INACTIVE;
1290 bool field_activated = false;
1292 // main loop
1293 do {
1295 if (have_card) {
1296 int bytes_read = mbedtls_net_recv_timeout(&netCtx, cmdbuf, sizeof(cmdbuf), 100);
1298 if (bytes_read == MBEDTLS_ERR_SSL_TIMEOUT || bytes_read == MBEDTLS_ERR_SSL_WANT_READ) {
1299 continue;
1302 if (bytes_read > 0) {
1304 if (cmdbuf[1] == 0x01 && cmdbuf[2] == 0x04) { // vpcd GET ATR
1305 uint8_t atr[256] = {0};
1306 int atrLen = 0;
1308 switch (card_type) {
1309 case CC_CONTACT: {
1310 memcpy(atr, card.atr, card.atr_len);
1311 atrLen = card.atr_len;
1312 break;
1314 case CC_CONTACTLESS: {
1316 if (cl_proto == ISODEP_NFCA) {
1317 atsToEmulatedAtr(card14a.ats, atr, &atrLen);
1319 if (cl_proto == ISODEP_NFCB) {
1320 atqbToEmulatedAtr(card14b.atqb, card14b.cid, atr, &atrLen);
1322 if (cl_proto == ISODEP_NFCV) {
1323 // Not implemented
1325 break;
1327 default: {
1328 break;
1332 uint8_t res[22] = {0};
1333 res[1] = atrLen;
1334 memcpy(res + 2, atr, atrLen);
1335 mbedtls_net_send(&netCtx, res, 2 + atrLen);
1337 } else if (cmdbuf[1] != 0x01) { // vpcd APDU
1338 int apduLen = (cmdbuf[0] << 8) + cmdbuf[1];
1340 uint8_t apduRes[APDU_RES_LEN] = {0};
1341 int apduResLen = 0;
1343 if (verbose) {
1344 PrintAndLogEx(INFO, ">> %s", sprint_hex(cmdbuf + 2, apduLen));
1347 switch (card_type) {
1348 case CC_CONTACT: {
1349 if (ExchangeAPDUSC(false, cmdbuf + 2, apduLen, !field_activated, true, apduRes, sizeof(apduRes), &apduResLen) != PM3_SUCCESS) {
1350 have_card = false;
1351 mbedtls_net_close(&netCtx);
1352 continue;
1354 break;
1356 case CC_CONTACTLESS: {
1358 if (cl_proto == ISODEP_NFCA) {
1359 if (ExchangeAPDU14a(cmdbuf + 2, apduLen, !field_activated, true, apduRes, sizeof(apduRes), &apduResLen) != PM3_SUCCESS) {
1360 have_card = false;
1361 mbedtls_net_close(&netCtx);
1362 continue;
1365 if (cl_proto == ISODEP_NFCB) {
1367 if (exchange_14b_apdu(cmdbuf + 2, apduLen, !field_activated, true, apduRes, sizeof(apduRes), &apduResLen, 0)) {
1368 have_card = false;
1369 mbedtls_net_close(&netCtx);
1370 continue;
1373 if (cl_proto == ISODEP_NFCV) {
1374 // Not implemented
1376 break;
1379 default: {
1380 break;
1384 field_activated = true;
1386 if (verbose) {
1387 PrintAndLogEx(INFO, "<< %s", sprint_hex(apduRes, apduResLen));
1390 uint8_t res[APDU_RES_LEN + 2] = {0};
1391 res[0] = (apduResLen >> 8) & 0xFF;
1392 res[1] = apduResLen & 0xFF;
1393 memcpy(res + 2, apduRes, apduResLen);
1394 mbedtls_net_send(&netCtx, res, 2 + apduResLen);
1397 } else {
1399 if (use14a && IfPm3Iso14443a() && SelectCard14443A_4(false, false, &card14a) == PM3_SUCCESS) {
1400 have_card = true;
1401 card_type = CC_CONTACTLESS;
1402 cl_proto = ISODEP_NFCA;
1405 if (use14b && IfPm3Iso14443b() && select_card_14443b_4(false, &card14b) == PM3_SUCCESS) {
1406 have_card = true;
1407 card_type = CC_CONTACTLESS;
1408 cl_proto = ISODEP_NFCB;
1411 // ISO 15.
1413 if (use_contact && IfPm3Iso14443() && smart_select(false, &card) == PM3_SUCCESS) {
1414 have_card = true;
1415 card_type = CC_CONTACT;
1418 if (have_card) {
1419 field_activated = false;
1420 if (mbedtls_net_connect(&netCtx, (char *) host, (char *) port, MBEDTLS_NET_PROTO_TCP)) {
1421 PrintAndLogEx(FAILED, "Failed to connect to vpcd socket. Ensure you have vpcd installed and running");
1422 mbedtls_net_close(&netCtx);
1423 mbedtls_net_free(&netCtx);
1424 DropField();
1425 return PM3_EINVARG;
1428 msleep(300);
1431 } while (!kbd_enter_pressed());
1433 mbedtls_net_close(&netCtx);
1434 mbedtls_net_free(&netCtx);
1435 DropField();
1437 return PM3_SUCCESS;
1440 static command_t CommandTable[] = {
1441 {"----------", CmdHelp, IfPm3Iso14443a, "------------------- " _CYAN_("General") " -------------------"},
1442 {"help", CmdHelp, AlwaysAvailable, "This help"},
1443 {"list", CmdSmartList, AlwaysAvailable, "List ISO 7816 history"},
1444 {"----------", CmdHelp, IfPm3Iso14443a, "------------------- " _CYAN_("Operations") " -------------------"},
1445 {"brute", CmdSmartBruteforceSFI, IfPm3Smartcard, "Bruteforce SFI"},
1446 {"info", CmdSmartInfo, IfPm3Smartcard, "Tag information"},
1447 {"pcsc", CmdPCSC, AlwaysAvailable, "Turn pm3 into pcsc reader and relay to host OS via vpcd"},
1448 {"reader", CmdSmartReader, IfPm3Smartcard, "Act like an IS07816 reader"},
1449 {"raw", CmdSmartRaw, IfPm3Smartcard, "Send raw hex data to tag"},
1450 {"upgrade", CmdSmartUpgrade, AlwaysAvailable, "Upgrade sim module firmware"},
1451 {"setclock", CmdSmartSetClock, IfPm3Smartcard, "Set clock speed"},
1452 {NULL, NULL, NULL, NULL}
1455 static int CmdHelp(const char *Cmd) {
1456 (void)Cmd; // Cmd is not used so far
1457 CmdsHelp(CommandTable);
1458 return PM3_SUCCESS;
1461 int CmdSmartcard(const char *Cmd) {
1462 clearCommandBuffer();
1463 return CmdsParse(CommandTable, Cmd);
1466 int ExchangeAPDUSC(bool verbose, uint8_t *datain, int datainlen, bool activateCard, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) {
1468 *dataoutlen = 0;
1470 smart_card_raw_t *payload = calloc(1, sizeof(smart_card_raw_t) + datainlen);
1471 payload->flags = (SC_RAW_T0 | SC_LOG);
1472 if (activateCard) {
1473 payload->flags |= (SC_SELECT | SC_CONNECT);
1475 payload->len = datainlen;
1476 payload->wait_delay = 0;
1477 memcpy(payload->data, datain, datainlen);
1479 clearCommandBuffer();
1480 SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + datainlen);
1482 int len = smart_responseEx(dataout, maxdataoutlen, verbose);
1483 if (len < 0) {
1484 free(payload);
1485 return PM3_ESOFT;
1488 // retry
1489 if (len > 1 && dataout[len - 2] == 0x6c && datainlen > 4) {
1491 payload->flags = SC_RAW_T0;
1492 payload->len = 5;
1493 // transfer length via T=0
1494 datain[4] = dataout[len - 1];
1495 memcpy(payload->data, datain, 5);
1496 clearCommandBuffer();
1497 SendCommandNG(CMD_SMART_RAW, (uint8_t *)payload, sizeof(smart_card_raw_t) + 5);
1498 datain[4] = 0;
1499 len = smart_responseEx(dataout, maxdataoutlen, verbose);
1500 if (len < 0) {
1501 free(payload);
1502 return PM3_ESOFT;
1506 free(payload);
1507 *dataoutlen = len;
1508 return PM3_SUCCESS;
1511 bool smart_select(bool verbose, smart_card_atr_t *atr) {
1512 if (atr) {
1513 memset(atr, 0, sizeof(smart_card_atr_t));
1516 clearCommandBuffer();
1517 SendCommandNG(CMD_SMART_ATR, NULL, 0);
1518 PacketResponseNG resp;
1519 if (WaitForResponseTimeout(CMD_SMART_ATR, &resp, 2500) == false) {
1520 if (verbose) PrintAndLogEx(WARNING, "smart card select timeout");
1521 return false;
1524 if (resp.status != PM3_SUCCESS) {
1525 if (verbose) PrintAndLogEx(WARNING, "smart card select failed");
1526 return false;
1529 smart_card_atr_t card;
1530 memcpy(&card, (smart_card_atr_t *)resp.data.asBytes, sizeof(smart_card_atr_t));
1532 if (atr) {
1533 memcpy(atr, &card, sizeof(smart_card_atr_t));
1536 if (verbose)
1537 PrintAndLogEx(INFO, "ISO7816-3 ATR : %s", sprint_hex(card.atr, card.atr_len));
1539 return true;