1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2017, 2018 Merlok
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 //-----------------------------------------------------------------------------
9 //-----------------------------------------------------------------------------
14 #include "proxmark3.h"
15 #include "cmdparser.h"
20 #include "test/cryptotest.h"
21 #include "cliparser/cliparser.h"
26 #define TLV_ADD(tag, value)( tlvdb_change_or_add_node(tlvRoot, tag, sizeof(value) - 1, (const unsigned char *)value) )
27 void ParamLoadDefaults(struct tlvdb
*tlvRoot
) {
28 //9F02:(Amount, authorized (Numeric)) len:6
29 TLV_ADD(0x9F02, "\x00\x00\x00\x00\x01\x00");
30 //9F1A:(Terminal Country Code) len:2
31 TLV_ADD(0x9F1A, "ru");
32 //5F2A:(Transaction Currency Code) len:2
33 // USD 840, EUR 978, RUR 810, RUB 643, RUR 810(old), UAH 980, AZN 031, n/a 999
34 TLV_ADD(0x5F2A, "\x09\x80");
35 //9A:(Transaction Date) len:3
36 TLV_ADD(0x9A, "\x00\x00\x00");
37 //9C:(Transaction Type) len:1 | 00 => Goods and service #01 => Cash
38 TLV_ADD(0x9C, "\x00");
39 // 9F37 Unpredictable Number len:4
40 TLV_ADD(0x9F37, "\x01\x02\x03\x04");
41 // 9F6A Unpredictable Number (MSD for UDOL) len:4
42 TLV_ADD(0x9F6A, "\x01\x02\x03\x04");
43 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
44 TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC
47 int CmdEMVSelect(const char *cmd
) {
48 uint8_t data
[APDU_AID_LEN
] = {0};
51 CLIParserInit("emv select",
52 "Executes select applet command",
53 "Usage:\n\temv select -s a00000000101 -> select card, select applet\n\temv select -st a00000000101 -> select card, select applet, show result in TLV\n");
57 arg_lit0("sS", "select", "activate field and select card"),
58 arg_lit0("kK", "keep", "keep field for next command"),
59 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
60 arg_lit0("tT", "tlv", "TLV decode results"),
62 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
64 arg_strx0(NULL
, NULL
, "<HEX applet AID>", NULL
),
67 CLIExecWithReturn(cmd
, argtable
, true);
69 bool activateField
= arg_get_lit(1);
70 bool leaveSignalON
= arg_get_lit(2);
71 bool APDULogging
= arg_get_lit(3);
72 bool decodeTLV
= arg_get_lit(4);
73 EMVCommandChannel channel
= ECC_CONTACTLESS
;
76 channel
= ECC_CONTACT
;
77 CLIGetHexWithReturn(6, data
, &datalen
);
79 CLIGetHexWithReturn(5, data
, &datalen
);
83 SetAPDULogging(APDULogging
);
86 uint8_t buf
[APDU_RES_LEN
] = {0};
89 int res
= EMVSelect(channel
, activateField
, leaveSignalON
, data
, datalen
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
92 PrintAndLogEx(INFO
, "APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
98 TLVPrintFromBuffer(buf
, len
);
103 int CmdEMVSearch(const char *cmd
) {
105 CLIParserInit("emv search",
106 "Tries to select all applets from applet list:\n",
107 "Usage:\n\temv search -s -> select card and search\n\temv search -st -> select card, search and show result in TLV\n");
111 arg_lit0("sS", "select", "activate field and select card"),
112 arg_lit0("kK", "keep", "keep field ON for next command"),
113 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
114 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
115 #ifdef WITH_SMARTCARD
116 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
120 CLIExecWithReturn(cmd
, argtable
, true);
122 bool activateField
= arg_get_lit(1);
123 bool leaveSignalON
= arg_get_lit(2);
124 bool APDULogging
= arg_get_lit(3);
125 bool decodeTLV
= arg_get_lit(4);
126 EMVCommandChannel channel
= ECC_CONTACTLESS
;
127 #ifdef WITH_SMARTCARD
129 channel
= ECC_CONTACT
;
133 SetAPDULogging(APDULogging
);
135 struct tlvdb
*t
= NULL
;
136 const char *al
= "Applets list";
137 t
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
);
139 if (EMVSearch(channel
, activateField
, leaveSignalON
, decodeTLV
, t
)) {
144 PrintAndLogEx(SUCCESS
, "Search completed.");
148 TLVPrintAIDlistFromSelectTLV(t
);
156 int CmdEMVPPSE(const char *cmd
) {
158 CLIParserInit("emv pse",
159 "Executes PSE/PPSE select command. It returns list of applet on the card:\n",
160 "Usage:\n\temv pse -s1 -> select, get pse\n\temv pse -st2 -> select, get ppse, show result in TLV\n");
164 arg_lit0("sS", "select", "activate field and select card"),
165 arg_lit0("kK", "keep", "keep field ON for next command"),
166 arg_lit0("1", "pse", "pse (1PAY.SYS.DDF01) mode"),
167 arg_lit0("2", "ppse", "ppse (2PAY.SYS.DDF01) mode (default mode)"),
168 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
169 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
170 #ifdef WITH_SMARTCARD
171 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
175 CLIExecWithReturn(cmd
, argtable
, true);
177 bool activateField
= arg_get_lit(1);
178 bool leaveSignalON
= arg_get_lit(2);
184 bool APDULogging
= arg_get_lit(5);
185 bool decodeTLV
= arg_get_lit(6);
186 EMVCommandChannel channel
= ECC_CONTACTLESS
;
187 #ifdef WITH_SMARTCARD
189 channel
= ECC_CONTACT
;
193 SetAPDULogging(APDULogging
);
196 uint8_t buf
[APDU_RES_LEN
] = {0};
199 int res
= EMVSelectPSE(channel
, activateField
, leaveSignalON
, PSENum
, buf
, sizeof(buf
), &len
, &sw
);
202 PrintAndLogEx(INFO
, "APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
209 TLVPrintFromBuffer(buf
, len
);
214 int CmdEMVGPO(const char *cmd
) {
215 uint8_t data
[APDU_RES_LEN
] = {0};
218 CLIParserInit("emv gpo",
219 "Executes Get Processing Options command. It returns data in TLV format (0x77 - format2) or plain format (0x80 - format1).\nNeeds a EMV applet to be selected.",
220 "Usage:\n\temv gpo -k -> execute GPO\n"
221 "\temv gpo -t 01020304 -> execute GPO with 4-byte PDOL data, show result in TLV\n"
222 "\temv gpo -pmt 9F 37 04 -> load params from file, make PDOL data from PDOL, execute GPO with PDOL, show result in TLV\n");
226 arg_lit0("kK", "keep", "keep field ON for next command"),
227 arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for PDOLdata making from PDOL and parameters"),
228 arg_lit0("mM", "make", "make PDOLdata from PDOL (tag 9F38) and parameters (by default uses default parameters)"),
229 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
230 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
231 #ifdef WITH_SMARTCARD
232 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
234 arg_strx0(NULL
, NULL
, "<HEX PDOLdata/PDOL>", NULL
),
237 CLIExecWithReturn(cmd
, argtable
, true);
239 bool leaveSignalON
= arg_get_lit(1);
240 bool paramsLoadFromFile
= arg_get_lit(2);
241 bool dataMakeFromPDOL
= arg_get_lit(3);
242 bool APDULogging
= arg_get_lit(4);
243 bool decodeTLV
= arg_get_lit(5);
244 EMVCommandChannel channel
= ECC_CONTACTLESS
;
245 #ifdef WITH_SMARTCARD
247 channel
= ECC_CONTACT
;
248 CLIGetHexWithReturn(7, data
, &datalen
);
250 CLIGetHexWithReturn(6, data
, &datalen
);
254 SetAPDULogging(APDULogging
);
257 const char *alr
= "Root terminal TLV tree";
258 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
261 struct tlv
*pdol_data_tlv
= NULL
;
262 struct tlv data_tlv
= {
265 .value
= (uint8_t *)data
,
267 if (dataMakeFromPDOL
) {
268 ParamLoadDefaults(tlvRoot
);
270 if (paramsLoadFromFile
) {
271 PrintAndLogEx(INFO
, "Params loading from file...");
272 ParamLoadFromJson(tlvRoot
);
275 pdol_data_tlv
= dol_process((const struct tlv
*)tlvdb_external(0x9f38, datalen
, data
), tlvRoot
, 0x83);
277 PrintAndLogEx(ERR
, "Can't create PDOL TLV.");
282 if (paramsLoadFromFile
) {
283 PrintAndLogEx(WARNING
, "Don't need to load parameters. Sending plain PDOL data...");
285 pdol_data_tlv
= &data_tlv
;
288 size_t pdol_data_tlv_data_len
= 0;
289 unsigned char *pdol_data_tlv_data
= tlv_encode(pdol_data_tlv
, &pdol_data_tlv_data_len
);
290 if (!pdol_data_tlv_data
) {
291 PrintAndLogEx(ERR
, "Can't create PDOL data.");
295 PrintAndLogEx(INFO
, "PDOL data[%d]: %s", pdol_data_tlv_data_len
, sprint_hex(pdol_data_tlv_data
, pdol_data_tlv_data_len
));
298 uint8_t buf
[APDU_RES_LEN
] = {0};
301 int res
= EMVGPO(channel
, leaveSignalON
, pdol_data_tlv_data
, pdol_data_tlv_data_len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
303 if (pdol_data_tlv
!= &data_tlv
)
308 PrintAndLogEx(INFO
, "APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
314 TLVPrintFromBuffer(buf
, len
);
319 int CmdEMVReadRecord(const char *cmd
) {
320 uint8_t data
[APDU_RES_LEN
] = {0};
323 CLIParserInit("emv readrec",
324 "Executes Read Record command. It returns data in TLV format.\nNeeds a bank applet to be selected and sometimes needs GPO to be executed.",
325 "Usage:\n\temv readrec -k 0101 -> read file SFI=01, SFIrec=01\n\temv readrec -kt 0201-> read file 0201 and show result in TLV\n");
329 arg_lit0("kK", "keep", "keep field ON for next command"),
330 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
331 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
332 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
333 arg_strx1(NULL
, NULL
, "<SFI 1byte HEX><SFIrecord 1byte HEX>", NULL
),
336 CLIExecWithReturn(cmd
, argtable
, true);
338 bool leaveSignalON
= arg_get_lit(1);
339 bool APDULogging
= arg_get_lit(2);
340 bool decodeTLV
= arg_get_lit(3);
341 EMVCommandChannel channel
= ECC_CONTACTLESS
;
342 #ifdef WITH_SMARTCARD
344 channel
= ECC_CONTACT
;
345 CLIGetHexWithReturn(5, data
, &datalen
);
347 CLIGetHexWithReturn(4, data
, &datalen
);
352 PrintAndLogEx(ERR
, "Command needs to have 2 bytes of data");
356 SetAPDULogging(APDULogging
);
359 uint8_t buf
[APDU_RES_LEN
] = {0};
362 int res
= EMVReadRecord(channel
, leaveSignalON
, data
[0], data
[1], buf
, sizeof(buf
), &len
, &sw
, NULL
);
365 PrintAndLogEx(INFO
, "APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
372 TLVPrintFromBuffer(buf
, len
);
377 int CmdEMVAC(const char *cmd
) {
378 uint8_t data
[APDU_RES_LEN
] = {0};
381 CLIParserInit("emv genac",
382 "Generate Application Cryptogram command. It returns data in TLV format .\nNeeds a EMV applet to be selected and GPO to be executed.",
383 "Usage:\n\temv genac -k 0102 -> generate AC with 2-byte CDOLdata and keep field ON after command\n"
384 "\temv genac -t 01020304 -> generate AC with 4-byte CDOL data, show result in TLV\n"
385 "\temv genac -Daac 01020304 -> generate AC with 4-byte CDOL data and terminal decision 'declined'\n"
386 "\temv genac -pmt 9F 37 04 -> load params from file, make CDOL data from CDOL, generate AC with CDOL, show result in TLV");
390 arg_lit0("kK", "keep", "keep field ON for next command"),
391 arg_lit0("cC", "cda", "executes CDA transaction. Needs to get SDAD in results."),
392 arg_str0("dD", "decision", "<aac|tc|arqc>", "Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested"),
393 arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for CDOLdata making from CDOL and parameters"),
394 arg_lit0("mM", "make", "make CDOLdata from CDOL (tag 8C and 8D) and parameters (by default uses default parameters)"),
395 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
396 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
397 #ifdef WITH_SMARTCARD
398 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
400 arg_strx1(NULL
, NULL
, "<HEX CDOLdata/CDOL>", NULL
),
403 CLIExecWithReturn(cmd
, argtable
, false);
405 bool leaveSignalON
= arg_get_lit(1);
406 bool trTypeCDA
= arg_get_lit(2);
407 uint8_t termDecision
= 0xff;
408 if (arg_get_str_len(3)) {
409 if (!strncmp(arg_get_str(3)->sval
[0], "aac", 4))
410 termDecision
= EMVAC_AAC
;
411 if (!strncmp(arg_get_str(3)->sval
[0], "tc", 4))
412 termDecision
= EMVAC_TC
;
413 if (!strncmp(arg_get_str(3)->sval
[0], "arqc", 4))
414 termDecision
= EMVAC_ARQC
;
416 if (termDecision
== 0xff) {
417 PrintAndLog("ERROR: can't find terminal decision '%s'", arg_get_str(3)->sval
[0]);
421 termDecision
= EMVAC_TC
;
424 termDecision
= termDecision
| EMVAC_CDAREQ
;
425 bool paramsLoadFromFile
= arg_get_lit(4);
426 bool dataMakeFromCDOL
= arg_get_lit(5);
427 bool APDULogging
= arg_get_lit(6);
428 bool decodeTLV
= arg_get_lit(7);
429 EMVCommandChannel channel
= ECC_CONTACTLESS
;
430 #ifdef WITH_SMARTCARD
432 channel
= ECC_CONTACT
;
433 CLIGetHexWithReturn(9, data
, &datalen
);
435 CLIGetHexWithReturn(8, data
, &datalen
);
439 SetAPDULogging(APDULogging
);
442 const char *alr
= "Root terminal TLV tree";
443 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
446 struct tlv
*cdol_data_tlv
= NULL
;
447 struct tlv data_tlv
= {
450 .value
= (uint8_t *)data
,
453 if (dataMakeFromCDOL
) {
454 ParamLoadDefaults(tlvRoot
);
456 if (paramsLoadFromFile
) {
457 PrintAndLogEx(INFO
, "Params loading from file...");
458 ParamLoadFromJson(tlvRoot
);
461 cdol_data_tlv
= dol_process((const struct tlv
*)tlvdb_external(0x8c, datalen
, data
), tlvRoot
, 0x01); // 0x01 - dummy tag
463 PrintAndLogEx(ERR
, "Can't create CDOL TLV.");
468 if (paramsLoadFromFile
) {
469 PrintAndLogEx(WARNING
, "Don't need to load parameters. Sending plain CDOL data...");
471 cdol_data_tlv
= &data_tlv
;
474 PrintAndLogEx(INFO
, "CDOL data[%d]: %s", cdol_data_tlv
->len
, sprint_hex(cdol_data_tlv
->value
, cdol_data_tlv
->len
));
477 uint8_t buf
[APDU_RES_LEN
] = {0};
480 int res
= EMVAC(channel
, leaveSignalON
, termDecision
, (uint8_t *)cdol_data_tlv
->value
, cdol_data_tlv
->len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
482 if (cdol_data_tlv
!= &data_tlv
)
487 PrintAndLogEx(INFO
, "APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
493 TLVPrintFromBuffer(buf
, len
);
498 int CmdEMVGenerateChallenge(const char *cmd
) {
500 CLIParserInit("emv challenge",
501 "Executes Generate Challenge command. It returns 4 or 8-byte random number from card.\nNeeds a EMV applet to be selected and GPO to be executed.",
502 "Usage:\n\temv challenge -> get challenge\n\temv challenge -k -> get challenge, keep fileld ON\n");
506 arg_lit0("kK", "keep", "keep field ON for next command"),
507 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
508 #ifdef WITH_SMARTCARD
509 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
513 CLIExecWithReturn(cmd
, argtable
, true);
515 bool leaveSignalON
= arg_get_lit(1);
516 bool APDULogging
= arg_get_lit(2);
517 EMVCommandChannel channel
= ECC_CONTACTLESS
;
518 #ifdef WITH_SMARTCARD
520 channel
= ECC_CONTACT
;
524 SetAPDULogging(APDULogging
);
527 uint8_t buf
[APDU_RES_LEN
] = {0};
530 int res
= EMVGenerateChallenge(channel
, leaveSignalON
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
533 PrintAndLogEx(INFO
, "APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
538 PrintAndLogEx(SUCCESS
, "Challenge: %s", sprint_hex(buf
, len
));
540 if (len
!= 4 && len
!= 8)
541 PrintAndLogEx(WARNING
, "Length of challenge must be 4 or 8, but it %d", len
);
546 int CmdEMVInternalAuthenticate(const char *cmd
) {
547 uint8_t data
[APDU_RES_LEN
] = {0};
550 CLIParserInit("emv intauth",
551 "Generate Internal Authenticate command. Usually needs 4-byte random number. It returns data in TLV format .\n"
552 "Needs a EMV applet to be selected and GPO to be executed.",
555 "\temv intauth -k 01020304 -> execute Internal Authenticate with 4-byte DDOLdata and keep field ON after command\n"
556 "\temv intauth -t 01020304 -> execute Internal Authenticate with 4-byte DDOL data, show result in TLV\n"
557 "\temv intauth -pmt 9F 37 04 -> load params from file, make DDOL data from DDOL, Internal Authenticate with DDOL, show result in TLV");
561 arg_lit0("kK", "keep", "keep field ON for next command"),
562 arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for DDOLdata making from DDOL and parameters"),
563 arg_lit0("mM", "make", "make DDOLdata from DDOL (tag 9F49) and parameters (by default uses default parameters)"),
564 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
565 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
566 #ifdef WITH_SMARTCARD
567 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
569 arg_strx1(NULL
, NULL
, "<HEX DDOLdata/DDOL>", NULL
),
572 CLIExecWithReturn(cmd
, argtable
, false);
574 bool leaveSignalON
= arg_get_lit(1);
575 bool paramsLoadFromFile
= arg_get_lit(2);
576 bool dataMakeFromDDOL
= arg_get_lit(3);
577 bool APDULogging
= arg_get_lit(4);
578 bool decodeTLV
= arg_get_lit(5);
579 EMVCommandChannel channel
= ECC_CONTACTLESS
;
580 #ifdef WITH_SMARTCARD
582 channel
= ECC_CONTACT
;
583 CLIGetHexWithReturn(7, data
, &datalen
);
585 CLIGetHexWithReturn(6, data
, &datalen
);
589 SetAPDULogging(APDULogging
);
592 const char *alr
= "Root terminal TLV tree";
593 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
596 struct tlv
*ddol_data_tlv
= NULL
;
597 struct tlv data_tlv
= {
600 .value
= (uint8_t *)data
,
603 if (dataMakeFromDDOL
) {
604 ParamLoadDefaults(tlvRoot
);
606 if (paramsLoadFromFile
) {
607 PrintAndLogEx(INFO
, "Params loading from file...");
608 ParamLoadFromJson(tlvRoot
);
611 ddol_data_tlv
= dol_process((const struct tlv
*)tlvdb_external(0x9f49, datalen
, data
), tlvRoot
, 0x01); // 0x01 - dummy tag
613 PrintAndLogEx(ERR
, "Can't create DDOL TLV.");
618 if (paramsLoadFromFile
) {
619 PrintAndLogEx(WARNING
, "Don't need to load parameters. Sending plain DDOL data...");
621 ddol_data_tlv
= &data_tlv
;
624 PrintAndLogEx(INFO
, "DDOL data[%d]: %s", ddol_data_tlv
->len
, sprint_hex(ddol_data_tlv
->value
, ddol_data_tlv
->len
));
627 uint8_t buf
[APDU_RES_LEN
] = {0};
630 int res
= EMVInternalAuthenticate(channel
, leaveSignalON
, data
, datalen
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
632 if (ddol_data_tlv
!= &data_tlv
)
637 PrintAndLogEx(INFO
, "APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
643 TLVPrintFromBuffer(buf
, len
);
648 #define dreturn(n) {free(pdol_data_tlv);tlvdb_free(tlvSelect);tlvdb_free(tlvRoot);DropField();return n;}
650 void InitTransactionParameters(struct tlvdb
*tlvRoot
, bool paramLoadJSON
, enum TransactionType TrType
, bool GenACGPO
) {
652 ParamLoadDefaults(tlvRoot
);
655 PrintAndLog("* * Transaction parameters loading from JSON...");
656 ParamLoadFromJson(tlvRoot
);
659 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
660 char *qVSDC
= "\x26\x00\x00\x00";
662 qVSDC
= "\x26\x80\x00\x00";
666 TLV_ADD(0x9F66, "\x86\x00\x00\x00"); // MSD
668 // not standard for contactless. just for test.
670 TLV_ADD(0x9F66, "\x46\x00\x00\x00"); // VSDC
673 TLV_ADD(0x9F66, qVSDC
); // qVSDC
676 TLV_ADD(0x9F66, qVSDC
); // qVSDC (VISA CDA not enabled)
683 void ProcessGPOResponseFormat1(struct tlvdb
*tlvRoot
, uint8_t *buf
, size_t len
, bool decodeTLV
) {
684 if (buf
[0] == 0x80) {
686 PrintAndLog("GPO response format1:");
687 TLVPrintFromBuffer(buf
, len
);
690 if (len
< 4 || (len
- 4) % 4) {
691 PrintAndLogEx(ERR
, "GPO response format1 parsing error. length=%d", len
);
694 struct tlvdb
* f1AIP
= tlvdb_fixed(0x82, 2, buf
+ 2);
695 tlvdb_add(tlvRoot
, f1AIP
);
697 PrintAndLogEx(INFO
, "\n* * Decode response format 1 (0x80) AIP and AFL:");
698 TLVPrintFromTLV(f1AIP
);
702 struct tlvdb
* f1AFL
= tlvdb_fixed(0x94, len
- 4, buf
+ 2 + 2);
703 tlvdb_add(tlvRoot
, f1AFL
);
705 TLVPrintFromTLV(f1AFL
);
709 TLVPrintFromBuffer(buf
, len
);
713 int CmdEMVExec(const char *cmd
) {
714 uint8_t buf
[APDU_RES_LEN
] = {0};
717 uint8_t AID
[APDU_AID_LEN
] = {0};
719 uint8_t ODAiList
[4096];
720 size_t ODAiListLen
= 0;
724 struct tlvdb
*tlvSelect
= NULL
;
725 struct tlvdb
*tlvRoot
= NULL
;
726 struct tlv
*pdol_data_tlv
= NULL
;
728 CLIParserInit("emv exec",
729 "Executes EMV contactless transaction",
731 "\temv exec -sat -> select card, execute MSD transaction, show APDU and TLV\n"
732 "\temv exec -satc -> select card, execute CDA transaction, show APDU and TLV\n");
736 arg_lit0("sS", "select", "activate field and select card."),
737 arg_lit0("aA", "apdu", "show APDU reqests and responses."),
738 arg_lit0("tT", "tlv", "TLV decode results."),
739 arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."),
740 arg_lit0("fF", "forceaid", "Force search AID. Search AID instead of execute PPSE."),
741 arg_rem("By default:", "Transaction type - MSD"),
742 arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
743 arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
744 arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standart behavior."),
745 arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."),
746 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
749 CLIExecWithReturn(cmd
, argtable
, true);
751 bool activateField
= arg_get_lit(1);
752 bool showAPDU
= arg_get_lit(2);
753 bool decodeTLV
= arg_get_lit(3);
754 bool paramLoadJSON
= arg_get_lit(4);
755 bool forceSearch
= arg_get_lit(5);
757 enum TransactionType TrType
= TT_MSD
;
759 TrType
= TT_QVSDCMCHIP
;
765 bool GenACGPO
= arg_get_lit(10);
766 EMVCommandChannel channel
= ECC_CONTACTLESS
;
767 #ifdef WITH_SMARTCARD
769 channel
= ECC_CONTACT
;
771 uint8_t psenum
= (channel
== ECC_CONTACT
) ? 1 : 2;
774 SetAPDULogging(showAPDU
);
776 // init applets list tree
777 const char *al
= "Applets list";
778 tlvSelect
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
);
780 // Application Selection
781 // https://www.openscdp.org/scripts/tutorial/emv/applicationselection.html
784 PrintAndLogEx(NORMAL
, "\n* PPSE.");
785 SetAPDULogging(showAPDU
);
786 res
= EMVSearchPSE(channel
, activateField
, true, psenum
, decodeTLV
, tlvSelect
);
788 // check PPSE and select application id
790 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
791 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
);
797 PrintAndLogEx(NORMAL
, "\n* Search AID in list.");
798 SetAPDULogging(false);
799 if (EMVSearch(channel
, activateField
, true, decodeTLV
, tlvSelect
)) {
803 // check search and select application id
804 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
805 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
);
809 const char *alr
= "Root terminal TLV tree";
810 tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
812 // check if we found EMV application on card
814 PrintAndLogEx(WARNING
, "Can't select AID. EMV AID not found");
819 PrintAndLogEx(NORMAL
, "\n* Selecting AID:%s", sprint_hex_inrow(AID
, AIDlen
));
820 SetAPDULogging(showAPDU
);
821 res
= EMVSelect(channel
, false, true, AID
, AIDlen
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
824 PrintAndLogEx(WARNING
, "Can't select AID (%d). Exit...", res
);
829 TLVPrintFromBuffer(buf
, len
);
830 PrintAndLogEx(INFO
, "* Selected.");
832 PrintAndLogEx(INFO
, "\n* Init transaction parameters.");
833 InitTransactionParameters(tlvRoot
, paramLoadJSON
, TrType
, GenACGPO
);
834 TLVPrintFromTLV(tlvRoot
); // TODO delete!!!
836 PrintAndLogEx(NORMAL
, "\n* Calc PDOL.");
837 pdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x9f38, NULL
), tlvRoot
, 0x83);
839 PrintAndLogEx(WARNING
, "Error: can't create PDOL TLV.");
843 size_t pdol_data_tlv_data_len
;
844 unsigned char *pdol_data_tlv_data
= tlv_encode(pdol_data_tlv
, &pdol_data_tlv_data_len
);
845 if (!pdol_data_tlv_data
) {
846 PrintAndLogEx(WARNING
, "Error: can't create PDOL data.");
849 PrintAndLogEx(NORMAL
, "PDOL data[%d]: %s", pdol_data_tlv_data_len
, sprint_hex(pdol_data_tlv_data
, pdol_data_tlv_data_len
));
851 PrintAndLogEx(NORMAL
, "\n* GPO.");
852 res
= EMVGPO(channel
, true, pdol_data_tlv_data
, pdol_data_tlv_data_len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
854 free(pdol_data_tlv_data
);
855 //free(pdol_data_tlv); --- free on exit.
858 PrintAndLogEx(NORMAL
, "GPO error(%d): %4x. Exit...", res
, sw
);
862 // process response template format 1 [id:80 2b AIP + x4b AFL] and format 2 [id:77 TLV]
863 ProcessGPOResponseFormat1(tlvRoot
, buf
, len
, decodeTLV
);
865 // extract PAN from track2
867 const struct tlv
*track2
= tlvdb_get(tlvRoot
, 0x57, NULL
);
868 if (!tlvdb_get(tlvRoot
, 0x5a, NULL
) && track2
&& track2
->len
>= 8) {
869 struct tlvdb
*pan
= GetPANFromTrack2(track2
);
871 tlvdb_add(tlvRoot
, pan
);
873 const struct tlv
*pantlv
= tlvdb_get(tlvRoot
, 0x5a, NULL
);
874 PrintAndLogEx(NORMAL
, "\n* * Extracted PAN from track2: %s", sprint_hex(pantlv
->value
, pantlv
->len
));
876 PrintAndLogEx(NORMAL
, "\n* * WARNING: Can't extract PAN from track2.");
881 PrintAndLogEx(NORMAL
, "\n* Read records from AFL.");
882 const struct tlv
*AFL
= tlvdb_get(tlvRoot
, 0x94, NULL
);
883 if (!AFL
|| !AFL
->len
) {
884 PrintAndLogEx(WARNING
, "AFL not found.");
887 while(AFL
&& AFL
->len
) {
889 PrintAndLogEx(WARNING
, "Error: Wrong AFL length: %d", AFL
->len
);
893 for (int i
= 0; i
< AFL
->len
/ 4; i
++) {
894 uint8_t SFI
= AFL
->value
[i
* 4 + 0] >> 3;
895 uint8_t SFIstart
= AFL
->value
[i
* 4 + 1];
896 uint8_t SFIend
= AFL
->value
[i
* 4 + 2];
897 uint8_t SFIoffline
= AFL
->value
[i
* 4 + 3];
899 PrintAndLogEx(NORMAL
, "* * SFI[%02x] start:%02x end:%02x offline:%02x", SFI
, SFIstart
, SFIend
, SFIoffline
);
900 if (SFI
== 0 || SFI
== 31 || SFIstart
== 0 || SFIstart
> SFIend
) {
901 PrintAndLogEx(NORMAL
, "SFI ERROR! Skipped...");
905 for(int n
= SFIstart
; n
<= SFIend
; n
++) {
906 PrintAndLogEx(NORMAL
, "* * * SFI[%02x] %d", SFI
, n
);
908 res
= EMVReadRecord(channel
, true, SFI
, n
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
910 PrintAndLogEx(WARNING
, "Error SFI[%02x]. APDU error %4x", SFI
, sw
);
915 TLVPrintFromBuffer(buf
, len
);
916 PrintAndLogEx(NORMAL
, "");
919 // Build Input list for Offline Data Authentication
920 // EMV 4.3 book3 10.3, page 96
923 const unsigned char *abuf
= buf
;
926 if (tlv_parse_tl(&abuf
, &elmlen
, &e
)) {
927 memcpy(&ODAiList
[ODAiListLen
], &buf
[len
- elmlen
], elmlen
);
928 ODAiListLen
+= elmlen
;
930 PrintAndLogEx(WARNING
, "Error SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI
);
933 memcpy(&ODAiList
[ODAiListLen
], buf
, len
);
943 // copy Input list for Offline Data Authentication
945 struct tlvdb
*oda
= tlvdb_fixed(0x21, ODAiListLen
, ODAiList
); // not a standard tag
946 tlvdb_add(tlvRoot
, oda
);
947 PrintAndLogEx(NORMAL
, "* Input list for Offline Data Authentication added to TLV. len=%d \n", ODAiListLen
);
952 const struct tlv
*AIPtlv
= tlvdb_get(tlvRoot
, 0x82, NULL
);
954 AIP
= AIPtlv
->value
[0] + AIPtlv
->value
[1] * 0x100;
955 PrintAndLogEx(NORMAL
, "* * AIP=%04x", AIP
);
957 PrintAndLogEx(ERR
, "Can't found AIP.");
962 PrintAndLogEx(NORMAL
, "\n* SDA");
968 PrintAndLogEx(NORMAL
, "\n* DDA");
969 trDDA(channel
, decodeTLV
, tlvRoot
);
975 if (TrType
== TT_QVSDCMCHIP
|| TrType
== TT_CDA
){
976 // 9F26: Application Cryptogram
977 const struct tlv
*AC
= tlvdb_get(tlvRoot
, 0x9F26, NULL
);
979 PrintAndLogEx(NORMAL
, "\n--> qVSDC transaction.");
980 PrintAndLogEx(NORMAL
, "* AC path");
982 // 9F36: Application Transaction Counter (ATC)
983 const struct tlv
*ATC
= tlvdb_get(tlvRoot
, 0x9F36, NULL
);
986 // 9F10: Issuer Application Data - optional
987 const struct tlv
*IAD
= tlvdb_get(tlvRoot
, 0x9F10, NULL
);
990 PrintAndLogEx(NORMAL
, "ATC: %s", sprint_hex(ATC
->value
, ATC
->len
));
991 PrintAndLogEx(NORMAL
, "AC: %s", sprint_hex(AC
->value
, AC
->len
));
993 PrintAndLogEx(NORMAL
, "IAD: %s", sprint_hex(IAD
->value
, IAD
->len
));
995 if (IAD
->len
>= IAD
->value
[0] + 1) {
996 PrintAndLogEx(NORMAL
, "\tKey index: 0x%02x", IAD
->value
[1]);
997 PrintAndLogEx(NORMAL
, "\tCrypto ver: 0x%02x(%03d)", IAD
->value
[2], IAD
->value
[2]);
998 PrintAndLogEx(NORMAL
, "\tCVR:", sprint_hex(&IAD
->value
[3], IAD
->value
[0] - 2));
999 struct tlvdb
* cvr
= tlvdb_fixed(0x20, IAD
->value
[0] - 2, &IAD
->value
[3]);
1000 TLVPrintFromTLVLev(cvr
, 1);
1003 PrintAndLogEx(WARNING
, "IAD not found.");
1007 PrintAndLogEx(ERR
, "AC: Application Transaction Counter (ATC) not found.");
1012 // Mastercard M/CHIP
1013 if (GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
&& (TrType
== TT_QVSDCMCHIP
|| TrType
== TT_CDA
)){
1014 const struct tlv
*CDOL1
= tlvdb_get(tlvRoot
, 0x8c, NULL
);
1015 if (CDOL1
&& GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
) { // and m/chip transaction flag
1016 PrintAndLogEx(NORMAL
, "\n--> Mastercard M/Chip transaction.");
1018 PrintAndLogEx(NORMAL
, "* * Generate challenge");
1019 res
= EMVGenerateChallenge(channel
, true, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1021 PrintAndLogEx(WARNING
, "GetChallenge. APDU error %4x", sw
);
1025 PrintAndLogEx(WARNING
, "GetChallenge. Wrong challenge length %d", len
);
1029 // ICC Dynamic Number
1030 struct tlvdb
* ICCDynN
= tlvdb_fixed(0x9f4c, len
, buf
);
1031 tlvdb_add(tlvRoot
, ICCDynN
);
1033 PrintAndLogEx(NORMAL
, "\n* * ICC Dynamic Number:");
1034 TLVPrintFromTLV(ICCDynN
);
1037 PrintAndLogEx(NORMAL
, "* * Calc CDOL1");
1038 struct tlv
*cdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x8c, NULL
), tlvRoot
, 0x01); // 0x01 - dummy tag
1039 if (!cdol_data_tlv
){
1040 PrintAndLogEx(WARNING
, "Error: can't create CDOL1 TLV.");
1043 PrintAndLogEx(NORMAL
, "CDOL1 data[%d]: %s", cdol_data_tlv
->len
, sprint_hex(cdol_data_tlv
->value
, cdol_data_tlv
->len
));
1045 PrintAndLogEx(NORMAL
, "* * AC1");
1046 // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD
1047 res
= EMVAC(channel
, true, (TrType
== TT_CDA
) ? EMVAC_TC
+ EMVAC_CDAREQ
: EMVAC_TC
, (uint8_t *)cdol_data_tlv
->value
, cdol_data_tlv
->len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1050 PrintAndLogEx(NORMAL
, "AC1 error(%d): %4x. Exit...", res
, sw
);
1055 TLVPrintFromBuffer(buf
, len
);
1058 PrintAndLogEx(NORMAL
, "\n* CDA:");
1059 struct tlvdb
*ac_tlv
= tlvdb_parse_multi(buf
, len
);
1060 res
= trCDA(tlvRoot
, ac_tlv
, pdol_data_tlv
, cdol_data_tlv
);
1062 PrintAndLogEx(NORMAL
, "CDA error (%d)", res
);
1065 free(cdol_data_tlv
);
1067 PrintAndLogEx(NORMAL
, "\n* M/Chip transaction result:");
1068 // 9F27: Cryptogram Information Data (CID)
1069 const struct tlv
*CID
= tlvdb_get(tlvRoot
, 0x9F27, NULL
);
1071 emv_tag_dump(CID
, stdout
, 0);
1072 PrintAndLogEx(NORMAL
, "------------------------------");
1074 switch(CID
->value
[0] & EMVAC_AC_MASK
){
1076 PrintAndLogEx(NORMAL
, "Transaction DECLINED.");
1079 PrintAndLogEx(NORMAL
, "Transaction approved OFFLINE.");
1082 PrintAndLogEx(NORMAL
, "Transaction approved ONLINE.");
1085 PrintAndLogEx(WARNING
, "Error: CID transaction code error %2x", CID
->value
[0] & EMVAC_AC_MASK
);
1089 PrintAndLogEx(WARNING
, "Wrong CID length %d", CID
->len
);
1092 PrintAndLogEx(WARNING
, "CID(9F27) not found.");
1099 if (AIP
& 0x8000 && TrType
== TT_MSD
) {
1100 PrintAndLogEx(NORMAL
, "\n--> MSD transaction.");
1102 PrintAndLogEx(NORMAL
, "* MSD dCVV path. Check dCVV");
1104 const struct tlv
*track2
= tlvdb_get(tlvRoot
, 0x57, NULL
);
1106 PrintAndLogEx(NORMAL
, "Track2: %s", sprint_hex(track2
->value
, track2
->len
));
1108 struct tlvdb
*dCVV
= GetdCVVRawFromTrack2(track2
);
1109 PrintAndLogEx(NORMAL
, "dCVV raw data:");
1110 TLVPrintFromTLV(dCVV
);
1112 if (GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
) {
1113 PrintAndLogEx(NORMAL
, "\n* Mastercard calculate UDOL");
1116 const struct tlv
*UDOL
= tlvdb_get(tlvRoot
, 0x9F69, NULL
);
1117 // UDOL(9F69) default: 9F6A (Unpredictable number) 4 bytes
1118 const struct tlv defUDOL
= {
1121 .value
= (uint8_t *)"\x9f\x6a\x04",
1124 PrintAndLogEx(NORMAL
, "Use default UDOL.");
1126 struct tlv
*udol_data_tlv
= dol_process(UDOL
? UDOL
: &defUDOL
, tlvRoot
, 0x01); // 0x01 - dummy tag
1127 if (!udol_data_tlv
){
1128 PrintAndLogEx(WARNING
, "can't create UDOL TLV.");
1132 PrintAndLogEx(NORMAL
, "UDOL data[%d]: %s", udol_data_tlv
->len
, sprint_hex(udol_data_tlv
->value
, udol_data_tlv
->len
));
1134 PrintAndLogEx(NORMAL
, "\n* Mastercard compute cryptographic checksum(UDOL)");
1136 res
= MSCComputeCryptoChecksum(channel
, true, (uint8_t *)udol_data_tlv
->value
, udol_data_tlv
->len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1138 PrintAndLogEx(WARNING
, "Compute Crypto Checksum. APDU error %4x", sw
);
1139 free(udol_data_tlv
);
1143 // Mastercard compute cryptographic checksum result
1144 TLVPrintFromBuffer(buf
, len
);
1145 PrintAndLogEx(NORMAL
, "");
1147 free(udol_data_tlv
);
1151 PrintAndLogEx(WARNING
, "MSD: Track2 data not found.");
1158 free(pdol_data_tlv
);
1159 tlvdb_free(tlvSelect
);
1160 tlvdb_free(tlvRoot
);
1162 PrintAndLogEx(NORMAL
, "\n* Transaction completed.");
1166 int CmdEMVScan(const char *cmd
) {
1167 uint8_t AID
[APDU_AID_LEN
] = {0};
1169 uint8_t buf
[APDU_RES_LEN
] = {0};
1176 CLIParserInit("emv scan",
1177 "Scan EMV card and save it contents to a file.",
1178 "It executes EMV contactless transaction and saves result to a file which can be used for emulation\n"
1179 "Usage:\n\temv scan -at -> scan MSD transaction mode and show APDU and TLV\n"
1180 "\temv scan -c -> scan CDA transaction mode\n");
1182 void* argtable
[] = {
1184 arg_lit0("aA", "apdu", "show APDU reqests and responses."),
1185 arg_lit0("tT", "tlv", "TLV decode results."),
1186 arg_lit0("eE", "extract", "Extract TLV elements and fill Application Data"),
1187 arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."),
1188 arg_rem("By default:", "Transaction type - MSD"),
1189 arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
1190 arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
1191 arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standart behavior."),
1192 arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."),
1193 arg_lit0("mM", "merge", "Merge output file with card's data. (warning: the file may be corrupted!)"),
1194 #ifdef WITH_SMARTCARD
1195 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
1197 arg_str1(NULL
, NULL
, "output.json", "JSON output file name"),
1200 CLIExecWithReturn(cmd
, argtable
, true);
1202 bool showAPDU
= arg_get_lit(1);
1203 bool decodeTLV
= arg_get_lit(2);
1204 bool extractTLVElements
= arg_get_lit(3);
1205 bool paramLoadJSON
= arg_get_lit(4);
1207 enum TransactionType TrType
= TT_MSD
;
1209 TrType
= TT_QVSDCMCHIP
;
1215 bool GenACGPO
= arg_get_lit(9);
1216 bool MergeJSON
= arg_get_lit(10);
1217 EMVCommandChannel channel
= ECC_CONTACTLESS
;
1218 uint8_t relfname
[250] = {0};
1219 char *crelfname
= (char *)relfname
;
1220 int relfnamelen
= 0;
1221 #ifdef WITH_SMARTCARD
1222 if (arg_get_lit(11)) {
1223 channel
= ECC_CONTACT
;
1225 CLIGetStrWithReturn(12, relfname
, &relfnamelen
);
1227 CLIGetStrWithReturn(11, relfname
, &relfnamelen
);
1229 uint8_t psenum
= (channel
== ECC_CONTACT
) ? 1 : 2;
1232 SetAPDULogging(showAPDU
);
1235 if (channel
== ECC_CONTACT
) {
1236 PrintAndLogEx(ERR
, "Do not use contact interface. Exit.");
1240 // current path + file name
1241 if (!strstr(crelfname
, ".json"))
1242 strcat(crelfname
, ".json");
1243 char fname
[strlen(get_my_executable_directory()) + strlen(crelfname
) + 1];
1244 strcpy(fname
, get_my_executable_directory());
1245 strcat(fname
, crelfname
);
1248 root
= json_load_file(fname
, 0, &error
);
1250 PrintAndLogEx(ERR
, "json error on line %d: %s", error
.line
, error
.text
);
1254 if (!json_is_object(root
)) {
1255 PrintAndLogEx(ERR
, "Invalid json format. root must be an object.");
1259 root
= json_object();
1262 // drop field at start
1266 PrintAndLogEx(NORMAL
, "--> GET UID, ATS.");
1268 iso14a_card_select_t card
;
1269 if (Hf14443_4aGetCardData(&card
)) {
1273 JsonSaveStr(root
, "$.File.Created", "proxmark3 `emv scan`");
1275 JsonSaveStr(root
, "$.Card.Communication", "iso14443-4a");
1276 JsonSaveBufAsHex(root
, "$.Card.UID", (uint8_t *)&card
.uid
, card
.uidlen
);
1277 JsonSaveHex(root
, "$.Card.ATQA", card
.atqa
[0] + (card
.atqa
[1] << 2), 2);
1278 JsonSaveHex(root
, "$.Card.SAK", card
.sak
, 0);
1279 JsonSaveBufAsHex(root
, "$.Card.ATS", (uint8_t *)card
.ats
, card
.ats_len
);
1281 // init applets list tree
1282 const char *al
= "Applets list";
1283 struct tlvdb
*tlvSelect
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
);
1286 PrintAndLogEx(NORMAL
, "--> PPSE.");
1287 res
= EMVSelectPSE(channel
, true, true, 2, buf
, sizeof(buf
), &len
, &sw
);
1289 if (!res
&& sw
== 0x9000){
1291 TLVPrintFromBuffer(buf
, len
);
1293 JsonSaveBufAsHex(root
, "$.PPSE.AID", (uint8_t *)"2PAY.SYS.DDF01", 14);
1295 struct tlvdb
*fci
= tlvdb_parse_multi(buf
, len
);
1296 if (extractTLVElements
)
1297 JsonSaveTLVTree(root
, root
, "$.PPSE.FCITemplate", fci
);
1299 JsonSaveTLVTreeElm(root
, "$.PPSE.FCITemplate", fci
, true, true, false);
1300 JsonSaveTLVValue(root
, "$.Application.KernelID", tlvdb_find_full(fci
, 0x9f2a));
1304 res
= EMVSearchPSE(channel
, false, true, psenum
, decodeTLV
, tlvSelect
);
1306 // check PPSE and select application id
1308 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
1310 // EMV SEARCH with AID list
1311 SetAPDULogging(false);
1312 PrintAndLogEx(NORMAL
, "--> AID search.");
1313 if (EMVSearch(channel
, false, true, decodeTLV
, tlvSelect
)) {
1314 PrintAndLogEx(ERR
, "Can't found any of EMV AID. Exit...");
1315 tlvdb_free(tlvSelect
);
1320 // check search and select application id
1321 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
1324 // EMV SELECT application
1325 SetAPDULogging(showAPDU
);
1326 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
);
1328 tlvdb_free(tlvSelect
);
1331 PrintAndLogEx(INFO
, "Can't select AID. EMV AID not found. Exit...");
1336 JsonSaveBufAsHex(root
, "$.Application.AID", AID
, AIDlen
);
1339 const char *alr
= "Root terminal TLV tree";
1340 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
1342 // EMV SELECT applet
1344 PrintAndLogEx(NORMAL
, "\n-->Selecting AID:%s.", sprint_hex_inrow(AID
, AIDlen
));
1345 SetAPDULogging(showAPDU
);
1346 res
= EMVSelect(channel
, false, true, AID
, AIDlen
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1349 PrintAndLogEx(ERR
, "Can't select AID (%d). Exit...", res
);
1350 tlvdb_free(tlvRoot
);
1356 TLVPrintFromBuffer(buf
, len
);
1359 if (tlvdb_get(tlvRoot
, 0x9f38, NULL
)) {
1360 JsonSaveStr(root
, "$.Application.Mode", TransactionTypeStr
[TrType
]);
1363 struct tlvdb
*fci
= tlvdb_parse_multi(buf
, len
);
1364 if (extractTLVElements
)
1365 JsonSaveTLVTree(root
, root
, "$.Application.FCITemplate", fci
);
1367 JsonSaveTLVTreeElm(root
, "$.Application.FCITemplate", fci
, true, true, false);
1370 // create transaction parameters
1371 PrintAndLogEx(NORMAL
, "-->Init transaction parameters.");
1372 InitTransactionParameters(tlvRoot
, paramLoadJSON
, TrType
, GenACGPO
);
1374 PrintAndLogEx(NORMAL
, "-->Calc PDOL.");
1375 struct tlv
*pdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x9f38, NULL
), tlvRoot
, 0x83);
1376 if (!pdol_data_tlv
){
1377 PrintAndLogEx(ERR
, "Can't create PDOL TLV.");
1378 tlvdb_free(tlvRoot
);
1383 size_t pdol_data_tlv_data_len
;
1384 unsigned char *pdol_data_tlv_data
= tlv_encode(pdol_data_tlv
, &pdol_data_tlv_data_len
);
1385 if (!pdol_data_tlv_data
) {
1386 PrintAndLogEx(ERR
, "Can't create PDOL data.");
1387 tlvdb_free(tlvRoot
);
1391 PrintAndLogEx(INFO
, "PDOL data[%d]: %s", pdol_data_tlv_data_len
, sprint_hex(pdol_data_tlv_data
, pdol_data_tlv_data_len
));
1393 PrintAndLogEx(INFO
, "-->GPO.");
1394 res
= EMVGPO(channel
, true, pdol_data_tlv_data
, pdol_data_tlv_data_len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1396 free(pdol_data_tlv_data
);
1397 free(pdol_data_tlv
);
1400 PrintAndLogEx(ERR
, "GPO error(%d): %4x. Exit...", res
, sw
);
1401 tlvdb_free(tlvRoot
);
1405 ProcessGPOResponseFormat1(tlvRoot
, buf
, len
, decodeTLV
);
1407 struct tlvdb
*gpofci
= tlvdb_parse_multi(buf
, len
);
1408 if (extractTLVElements
)
1409 JsonSaveTLVTree(root
, root
, "$.Application.GPO", gpofci
);
1411 JsonSaveTLVTreeElm(root
, "$.Application.GPO", gpofci
, true, true, false);
1413 JsonSaveTLVValue(root
, "$.ApplicationData.AIP", tlvdb_find_full(gpofci
, 0x82));
1414 JsonSaveTLVValue(root
, "$.ApplicationData.AFL", tlvdb_find_full(gpofci
, 0x94));
1418 PrintAndLogEx(INFO
, "-->Read records from AFL.");
1419 const struct tlv
*AFL
= tlvdb_get(tlvRoot
, 0x94, NULL
);
1421 while(AFL
&& AFL
->len
) {
1423 PrintAndLogEx(ERR
, "Wrong AFL length: %d", AFL
->len
);
1427 json_t
*sfijson
= json_path_get(root
, "$.Application.Records");
1429 json_t
*app
= json_path_get(root
, "$.Application");
1430 json_object_set_new(app
, "Records", json_array());
1432 sfijson
= json_path_get(root
, "$.Application.Records");
1434 if (!json_is_array(sfijson
)) {
1435 PrintAndLogEx(ERR
, "Internal logic error. `$.Application.Records` is not an array.");
1438 for (int i
= 0; i
< AFL
->len
/ 4; i
++) {
1439 uint8_t SFI
= AFL
->value
[i
* 4 + 0] >> 3;
1440 uint8_t SFIstart
= AFL
->value
[i
* 4 + 1];
1441 uint8_t SFIend
= AFL
->value
[i
* 4 + 2];
1442 uint8_t SFIoffline
= AFL
->value
[i
* 4 + 3];
1444 PrintAndLogEx(INFO
, "--->SFI[%02x] start:%02x end:%02x offline:%02x", SFI
, SFIstart
, SFIend
, SFIoffline
);
1445 if (SFI
== 0 || SFI
== 31 || SFIstart
== 0 || SFIstart
> SFIend
) {
1446 PrintAndLogEx(ERR
, "SFI ERROR! Skipped...");
1450 for(int n
= SFIstart
; n
<= SFIend
; n
++) {
1451 PrintAndLogEx(INFO
, "---->SFI[%02x] %d", SFI
, n
);
1453 res
= EMVReadRecord(channel
, true, SFI
, n
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1455 PrintAndLogEx(ERR
, "SFI[%02x]. APDU error %4x", SFI
, sw
);
1460 TLVPrintFromBuffer(buf
, len
);
1461 PrintAndLogEx(NORMAL
, "");
1464 json_t
*jsonelm
= json_object();
1465 json_array_append_new(sfijson
, jsonelm
);
1467 JsonSaveHex(jsonelm
, "SFI", SFI
, 1);
1468 JsonSaveHex(jsonelm
, "RecordNum", n
, 1);
1469 JsonSaveHex(jsonelm
, "Offline", SFIoffline
, 1);
1471 struct tlvdb
*rsfi
= tlvdb_parse_multi(buf
, len
);
1472 if (extractTLVElements
)
1473 JsonSaveTLVTree(root
, jsonelm
, "$.Data", rsfi
);
1475 JsonSaveTLVTreeElm(jsonelm
, "$.Data", rsfi
, true, true, false);
1483 // getting certificates
1484 if (tlvdb_get(tlvRoot
, 0x90, NULL
)) {
1485 PrintAndLogEx(INFO
, "-->Recovering certificates.");
1486 PKISetStrictExecution(false);
1487 RecoveryCertificates(tlvRoot
, root
);
1488 PKISetStrictExecution(true);
1492 tlvdb_free(tlvRoot
);
1497 res
= json_dump_file(root
, fname
, JSON_INDENT(2));
1499 PrintAndLogEx(ERR
, "Can't save the file: %s", fname
);
1502 PrintAndLogEx(SUCCESS
, "File `%s` saved.", fname
);
1510 int CmdEMVTest(const char *cmd
) {
1511 return ExecuteCryptoTests(true);
1514 int CmdEMVRoca(const char *cmd
) {
1515 uint8_t AID
[APDU_AID_LEN
] = {0};
1517 uint8_t buf
[APDU_RES_LEN
] = {0};
1522 CLIParserInit("emv roca",
1523 "Tries to extract public keys and run the ROCA test against them.\n",
1525 "\temv roca -w -> select CONTACT card and run test\n\temv roca -> select CONTACTLESS card and run test\n");
1527 void* argtable
[] = {
1529 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
1532 CLIExecWithReturn(cmd
, argtable
, true);
1534 EMVCommandChannel channel
= ECC_CONTACTLESS
;
1536 channel
= ECC_CONTACT
;
1539 uint8_t psenum
= (channel
== ECC_CONTACT
) ? 1 : 2;
1541 SetAPDULogging(false);
1543 // init applets list tree
1544 const char *al
= "Applets list";
1545 struct tlvdb
*tlvSelect
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
);
1548 PrintAndLogEx(NORMAL
, "--> PPSE.");
1549 res
= EMVSearchPSE(channel
, false, true, psenum
, false, tlvSelect
);
1551 // check PPSE and select application id
1553 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
1555 // EMV SEARCH with AID list
1556 PrintAndLogEx(NORMAL
, "--> AID search.");
1557 if (EMVSearch(channel
, false, true, false, tlvSelect
)) {
1558 PrintAndLogEx(ERR
, "Can't found any of EMV AID. Exit...");
1559 tlvdb_free(tlvSelect
);
1564 // check search and select application id
1565 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
1568 // EMV SELECT application
1569 SetAPDULogging(false);
1570 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
);
1572 tlvdb_free(tlvSelect
);
1575 PrintAndLogEx(INFO
, "Can't select AID. EMV AID not found. Exit...");
1581 const char *alr
= "Root terminal TLV tree";
1582 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
1584 // EMV SELECT applet
1585 PrintAndLogEx(NORMAL
, "\n-->Selecting AID:%s.", sprint_hex_inrow(AID
, AIDlen
));
1586 res
= EMVSelect(channel
, false, true, AID
, AIDlen
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1589 PrintAndLogEx(ERR
, "Can't select AID (%d). Exit...", res
);
1590 tlvdb_free(tlvRoot
);
1595 PrintAndLog("\n* Init transaction parameters.");
1596 InitTransactionParameters(tlvRoot
, true, TT_QVSDCMCHIP
, false);
1598 PrintAndLogEx(NORMAL
, "-->Calc PDOL.");
1599 struct tlv
*pdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x9f38, NULL
), tlvRoot
, 0x83);
1600 if (!pdol_data_tlv
){
1601 PrintAndLogEx(ERR
, "Can't create PDOL TLV.");
1602 tlvdb_free(tlvRoot
);
1607 size_t pdol_data_tlv_data_len
;
1608 unsigned char *pdol_data_tlv_data
= tlv_encode(pdol_data_tlv
, &pdol_data_tlv_data_len
);
1609 if (!pdol_data_tlv_data
) {
1610 PrintAndLogEx(ERR
, "Can't create PDOL data.");
1611 tlvdb_free(tlvRoot
);
1615 PrintAndLogEx(INFO
, "PDOL data[%d]: %s", pdol_data_tlv_data_len
, sprint_hex(pdol_data_tlv_data
, pdol_data_tlv_data_len
));
1617 PrintAndLogEx(INFO
, "-->GPO.");
1618 res
= EMVGPO(channel
, true, pdol_data_tlv_data
, pdol_data_tlv_data_len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1620 free(pdol_data_tlv_data
);
1621 free(pdol_data_tlv
);
1624 PrintAndLogEx(ERR
, "GPO error(%d): %4x. Exit...", res
, sw
);
1625 tlvdb_free(tlvRoot
);
1629 ProcessGPOResponseFormat1(tlvRoot
, buf
, len
, false);
1631 PrintAndLogEx(INFO
, "-->Read records from AFL.");
1632 const struct tlv
*AFL
= tlvdb_get(tlvRoot
, 0x94, NULL
);
1634 while(AFL
&& AFL
->len
) {
1636 PrintAndLogEx(ERR
, "Wrong AFL length: %d", AFL
->len
);
1640 for (int i
= 0; i
< AFL
->len
/ 4; i
++) {
1641 uint8_t SFI
= AFL
->value
[i
* 4 + 0] >> 3;
1642 uint8_t SFIstart
= AFL
->value
[i
* 4 + 1];
1643 uint8_t SFIend
= AFL
->value
[i
* 4 + 2];
1644 uint8_t SFIoffline
= AFL
->value
[i
* 4 + 3];
1646 PrintAndLogEx(INFO
, "--->SFI[%02x] start:%02x end:%02x offline:%02x", SFI
, SFIstart
, SFIend
, SFIoffline
);
1647 if (SFI
== 0 || SFI
== 31 || SFIstart
== 0 || SFIstart
> SFIend
) {
1648 PrintAndLogEx(ERR
, "SFI ERROR! Skipped...");
1652 for(int n
= SFIstart
; n
<= SFIend
; n
++) {
1653 PrintAndLogEx(INFO
, "---->SFI[%02x] %d", SFI
, n
);
1655 res
= EMVReadRecord(channel
, true, SFI
, n
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1657 PrintAndLogEx(ERR
, "SFI[%02x]. APDU error %4x", SFI
, sw
);
1666 // getting certificates
1667 if (tlvdb_get(tlvRoot
, 0x90, NULL
)) {
1668 PrintAndLogEx(INFO
, "-->Recovering certificates.");
1669 PKISetStrictExecution(false);
1671 struct emv_pk
*pk
= get_ca_pk(tlvRoot
);
1673 PrintAndLogEx(ERR
, "ERROR: Key not found. Exit.");
1677 struct emv_pk
*issuer_pk
= emv_pki_recover_issuer_cert(pk
, tlvRoot
);
1680 PrintAndLogEx(WARNING
, "WARNING: Issuer certificate not found. Exit.");
1684 PrintAndLogEx(SUCCESS
, "Issuer PK recovered. RID %s IDX %02hhx CSN %s",
1685 sprint_hex(issuer_pk
->rid
, 5),
1687 sprint_hex(issuer_pk
->serial
, 3)
1691 struct emv_pk
*icc_pk
= emv_pki_recover_icc_cert(issuer_pk
, tlvRoot
, NULL
);
1694 emv_pk_free(issuer_pk
);
1695 PrintAndLogEx(WARNING
, "WARNING: ICC certificate not found. Exit.");
1698 PrintAndLogEx(SUCCESS
, "ICC PK recovered. RID %s IDX %02hhx CSN %s\n",
1699 sprint_hex(icc_pk
->rid
, 5),
1701 sprint_hex(icc_pk
->serial
, 3)
1704 PrintAndLogEx(INFO
, "ICC pk modulus: %s", sprint_hex_inrow(icc_pk
->modulus
, icc_pk
->mlen
));
1706 // icc_pk->exp, icc_pk->elen
1707 // icc_pk->modulus, icc_pk->mlen
1708 if (icc_pk
->elen
> 0 && icc_pk
->mlen
> 0) {
1709 if (emv_rocacheck(icc_pk
->modulus
, icc_pk
->mlen
, true)) {
1710 PrintAndLogEx(INFO
, "ICC pk is a subject to ROCA vulnerability, insecure..");
1712 PrintAndLogEx(INFO
, "ICC pk is OK(");
1716 PKISetStrictExecution(true);
1722 tlvdb_free(tlvRoot
);
1724 if ( channel
== ECC_CONTACTLESS
)
1731 int CmdHelp(const char *Cmd
);
1733 static command_t CommandTable
[] = {
1734 {"help", CmdHelp
, 1, "This help"},
1735 {"exec", CmdEMVExec
, 0, "Executes EMV contactless transaction."},
1736 {"pse", CmdEMVPPSE
, 0, "Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory."},
1737 {"search", CmdEMVSearch
, 0, "Try to select all applets from applets list and print installed applets."},
1738 {"select", CmdEMVSelect
, 0, "Select applet."},
1739 {"gpo", CmdEMVGPO
, 0, "Execute GetProcessingOptions."},
1740 {"readrec", CmdEMVReadRecord
, 0, "Read files from card."},
1741 {"genac", CmdEMVAC
, 0, "Generate ApplicationCryptogram."},
1742 {"challenge", CmdEMVGenerateChallenge
, 0, "Generate challenge."},
1743 {"intauth", CmdEMVInternalAuthenticate
, 0, "Internal authentication."},
1744 {"scan", CmdEMVScan
, 0, "Scan EMV card and save it contents to json file for emulator."},
1745 {"test", CmdEMVTest
, 0, "Crypto logic test."},
1746 {"roca", CmdEMVRoca
, 0, "Extract public keys and run ROCA test"},
1747 {NULL
, NULL
, 0, NULL
}
1750 int CmdEMV(const char *Cmd
) {
1751 CmdsParse(CommandTable
, Cmd
);
1755 int CmdHelp(const char *Cmd
) {
1756 CmdsHelp(CommandTable
);