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 //-----------------------------------------------------------------------------
15 #include "proxmark3.h"
16 #include "cmdparser.h"
23 #include "test/cryptotest.h"
24 #include "cliparser/cliparser.h"
32 #include "cmdsmartcard.h"
34 #define TLV_ADD(tag, value)( tlvdb_change_or_add_node(tlvRoot, tag, sizeof(value) - 1, (const unsigned char *)value) )
35 void ParamLoadDefaults(struct tlvdb
*tlvRoot
) {
36 //9F02:(Amount, authorized (Numeric)) len:6
37 TLV_ADD(0x9F02, "\x00\x00\x00\x00\x01\x00");
38 //9F1A:(Terminal Country Code) len:2
39 TLV_ADD(0x9F1A, "ru");
40 //5F2A:(Transaction Currency Code) len:2
41 // USD 840, EUR 978, RUR 810, RUB 643, RUR 810(old), UAH 980, AZN 031, n/a 999
42 TLV_ADD(0x5F2A, "\x09\x80");
43 //9A:(Transaction Date) len:3
44 TLV_ADD(0x9A, "\x00\x00\x00");
45 //9C:(Transaction Type) len:1 | 00 => Goods and service #01 => Cash
46 TLV_ADD(0x9C, "\x00");
47 // 9F37 Unpredictable Number len:4
48 TLV_ADD(0x9F37, "\x01\x02\x03\x04");
49 // 9F6A Unpredictable Number (MSD for UDOL) len:4
50 TLV_ADD(0x9F6A, "\x01\x02\x03\x04");
51 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
52 TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC
53 //95:(Terminal Verification Results) len:5
55 TLV_ADD(0x95, "\x00\x00\x00\x00\x00");
58 void PrintChannel(EMVCommandChannel channel
) {
61 PrintAndLogEx(INFO
, "Channel: CONTACTLESS");
64 PrintAndLogEx(INFO
, "Channel: CONTACT, using %s", getAlternativeSmartcardReader());
69 int CmdEMVSelect(const char *cmd
) {
70 uint8_t data
[APDU_DATA_LEN
] = {0};
73 CLIParserInit("emv select",
74 "Executes select applet command",
75 "Usage:\n\temv select -s a00000000101 -> select card, select applet\n\temv select -st a00000000101 -> select card, select applet, show result in TLV\n");
79 arg_lit0("sS", "select", "activate field and select card"),
80 arg_lit0("kK", "keep", "keep field for next command"),
81 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
82 arg_lit0("tT", "tlv", "TLV decode results"),
84 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
86 arg_strx0(NULL
, NULL
, "<HEX applet AID>", NULL
),
89 CLIExecWithReturn(cmd
, argtable
, true);
91 bool activateField
= arg_get_lit(1);
92 bool leaveSignalON
= arg_get_lit(2);
93 bool APDULogging
= arg_get_lit(3);
94 bool decodeTLV
= arg_get_lit(4);
95 EMVCommandChannel channel
= ECC_CONTACTLESS
;
98 channel
= ECC_CONTACT
;
99 PrintChannel(channel
);
100 CLIGetHexWithReturn(6, data
, &datalen
);
102 CLIGetHexWithReturn(5, data
, &datalen
);
106 SetAPDULogging(APDULogging
);
109 uint8_t buf
[APDU_RESPONSE_LEN
] = {0};
112 int res
= EMVSelect(channel
, activateField
, leaveSignalON
, data
, datalen
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
115 PrintAndLogEx(INFO
, "APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
121 TLVPrintFromBuffer(buf
, len
);
126 int CmdEMVSearch(const char *cmd
) {
128 CLIParserInit("emv search",
129 "Tries to select all applets from applet list:\n",
130 "Usage:\n\temv search -s -> select card and search\n\temv search -st -> select card, search and show result in TLV\n");
134 arg_lit0("sS", "select", "activate field and select card"),
135 arg_lit0("kK", "keep", "keep field ON for next command"),
136 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
137 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
138 #ifdef WITH_SMARTCARD
139 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
143 CLIExecWithReturn(cmd
, argtable
, true);
145 bool activateField
= arg_get_lit(1);
146 bool leaveSignalON
= arg_get_lit(2);
147 bool APDULogging
= arg_get_lit(3);
148 bool decodeTLV
= arg_get_lit(4);
149 EMVCommandChannel channel
= ECC_CONTACTLESS
;
150 #ifdef WITH_SMARTCARD
152 channel
= ECC_CONTACT
;
154 PrintChannel(channel
);
157 SetAPDULogging(APDULogging
);
159 struct tlvdb
*t
= NULL
;
160 const char *al
= "Applets list";
161 t
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
);
163 if (EMVSearch(channel
, activateField
, leaveSignalON
, decodeTLV
, t
)) {
168 PrintAndLogEx(SUCCESS
, "Search completed.");
172 TLVPrintAIDlistFromSelectTLV(t
);
180 int CmdEMVPPSE(const char *cmd
) {
182 CLIParserInit("emv pse",
183 "Executes PSE/PPSE select command. It returns list of applet on the card:\n",
184 "Usage:\n\temv pse -s1 -> select, get pse\n\temv pse -st2 -> select, get ppse, show result in TLV\n");
188 arg_lit0("sS", "select", "activate field and select card"),
189 arg_lit0("kK", "keep", "keep field ON for next command"),
190 arg_lit0("1", "pse", "pse (1PAY.SYS.DDF01) mode"),
191 arg_lit0("2", "ppse", "ppse (2PAY.SYS.DDF01) mode (default mode)"),
192 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
193 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
194 #ifdef WITH_SMARTCARD
195 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
199 CLIExecWithReturn(cmd
, argtable
, true);
201 bool activateField
= arg_get_lit(1);
202 bool leaveSignalON
= arg_get_lit(2);
208 bool APDULogging
= arg_get_lit(5);
209 bool decodeTLV
= arg_get_lit(6);
210 EMVCommandChannel channel
= ECC_CONTACTLESS
;
211 #ifdef WITH_SMARTCARD
213 channel
= ECC_CONTACT
;
215 PrintChannel(channel
);
218 SetAPDULogging(APDULogging
);
221 uint8_t buf
[APDU_RESPONSE_LEN
] = {0};
224 int res
= EMVSelectPSE(channel
, activateField
, leaveSignalON
, PSENum
, buf
, sizeof(buf
), &len
, &sw
);
227 PrintAndLogEx(INFO
, "APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
234 TLVPrintFromBuffer(buf
, len
);
239 int CmdEMVGPO(const char *cmd
) {
240 uint8_t data
[APDU_RESPONSE_LEN
] = {0};
243 CLIParserInit("emv gpo",
244 "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.",
245 "Usage:\n\temv gpo -k -> execute GPO\n"
246 "\temv gpo -t 01020304 -> execute GPO with 4-byte PDOL data, show result in TLV\n"
247 "\temv gpo -pmt 9F 37 04 -> load params from file, make PDOL data from PDOL, execute GPO with PDOL, show result in TLV\n");
251 arg_lit0("kK", "keep", "keep field ON for next command"),
252 arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for PDOLdata making from PDOL and parameters"),
253 arg_lit0("mM", "make", "make PDOLdata from PDOL (tag 9F38) and parameters (by default uses default parameters)"),
254 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
255 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
256 #ifdef WITH_SMARTCARD
257 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
259 arg_strx0(NULL
, NULL
, "<HEX PDOLdata/PDOL>", NULL
),
262 CLIExecWithReturn(cmd
, argtable
, true);
264 bool leaveSignalON
= arg_get_lit(1);
265 bool paramsLoadFromFile
= arg_get_lit(2);
266 bool dataMakeFromPDOL
= arg_get_lit(3);
267 bool APDULogging
= arg_get_lit(4);
268 bool decodeTLV
= arg_get_lit(5);
269 EMVCommandChannel channel
= ECC_CONTACTLESS
;
270 #ifdef WITH_SMARTCARD
272 channel
= ECC_CONTACT
;
273 CLIGetHexWithReturn(7, data
, &datalen
);
275 CLIGetHexWithReturn(6, data
, &datalen
);
277 PrintChannel(channel
);
280 SetAPDULogging(APDULogging
);
283 const char *alr
= "Root terminal TLV tree";
284 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
287 struct tlv
*pdol_data_tlv
= NULL
;
288 struct tlv data_tlv
= {
291 .value
= (uint8_t *)data
,
293 if (dataMakeFromPDOL
) {
294 ParamLoadDefaults(tlvRoot
);
296 if (paramsLoadFromFile
) {
297 PrintAndLogEx(INFO
, "Params loading from file...");
298 ParamLoadFromJson(tlvRoot
);
301 pdol_data_tlv
= dol_process((const struct tlv
*)tlvdb_external(0x9f38, datalen
, data
), tlvRoot
, 0x83);
303 PrintAndLogEx(ERR
, "Can't create PDOL TLV.");
308 if (paramsLoadFromFile
) {
309 PrintAndLogEx(WARNING
, "Don't need to load parameters. Sending plain PDOL data...");
311 pdol_data_tlv
= &data_tlv
;
314 size_t pdol_data_tlv_data_len
= 0;
315 unsigned char *pdol_data_tlv_data
= tlv_encode(pdol_data_tlv
, &pdol_data_tlv_data_len
);
316 if (!pdol_data_tlv_data
) {
317 PrintAndLogEx(ERR
, "Can't create PDOL data.");
321 PrintAndLogEx(INFO
, "PDOL data[%d]: %s", pdol_data_tlv_data_len
, sprint_hex(pdol_data_tlv_data
, pdol_data_tlv_data_len
));
324 uint8_t buf
[APDU_RESPONSE_LEN
] = {0};
327 int res
= EMVGPO(channel
, leaveSignalON
, pdol_data_tlv_data
, pdol_data_tlv_data_len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
329 if (pdol_data_tlv
!= &data_tlv
)
334 PrintAndLogEx(INFO
, "APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
340 TLVPrintFromBuffer(buf
, len
);
345 int CmdEMVReadRecord(const char *cmd
) {
346 uint8_t data
[APDU_RESPONSE_LEN
] = {0};
349 CLIParserInit("emv readrec",
350 "Executes Read Record command. It returns data in TLV format.\nNeeds a bank applet to be selected and sometimes needs GPO to be executed.",
351 "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");
355 arg_lit0("kK", "keep", "keep field ON for next command"),
356 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
357 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
358 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
359 arg_strx1(NULL
, NULL
, "<SFI 1byte HEX><SFIrecord 1byte HEX>", NULL
),
362 CLIExecWithReturn(cmd
, argtable
, true);
364 bool leaveSignalON
= arg_get_lit(1);
365 bool APDULogging
= arg_get_lit(2);
366 bool decodeTLV
= arg_get_lit(3);
367 EMVCommandChannel channel
= ECC_CONTACTLESS
;
368 #ifdef WITH_SMARTCARD
370 channel
= ECC_CONTACT
;
371 CLIGetHexWithReturn(5, data
, &datalen
);
373 CLIGetHexWithReturn(4, data
, &datalen
);
375 PrintChannel(channel
);
379 PrintAndLogEx(ERR
, "Command needs to have 2 bytes of data");
383 SetAPDULogging(APDULogging
);
386 uint8_t buf
[APDU_RESPONSE_LEN
] = {0};
389 int res
= EMVReadRecord(channel
, leaveSignalON
, data
[0], data
[1], buf
, sizeof(buf
), &len
, &sw
, NULL
);
392 PrintAndLogEx(INFO
, "APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
399 TLVPrintFromBuffer(buf
, len
);
404 int CmdEMVAC(const char *cmd
) {
405 uint8_t data
[APDU_RESPONSE_LEN
] = {0};
408 CLIParserInit("emv genac",
409 "Generate Application Cryptogram command. It returns data in TLV format .\nNeeds a EMV applet to be selected and GPO to be executed.",
410 "Usage:\n\temv genac -k 0102 -> generate AC with 2-byte CDOLdata and keep field ON after command\n"
411 "\temv genac -t 01020304 -> generate AC with 4-byte CDOL data, show result in TLV\n"
412 "\temv genac -Daac 01020304 -> generate AC with 4-byte CDOL data and terminal decision 'declined'\n"
413 "\temv genac -pmt 9F 37 04 -> load params from file, make CDOL data from CDOL, generate AC with CDOL, show result in TLV");
417 arg_lit0("kK", "keep", "keep field ON for next command"),
418 arg_lit0("cC", "cda", "executes CDA transaction. Needs to get SDAD in results."),
419 arg_str0("dD", "decision", "<aac|tc|arqc>", "Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested"),
420 arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for CDOLdata making from CDOL and parameters"),
421 arg_lit0("mM", "make", "make CDOLdata from CDOL (tag 8C and 8D) and parameters (by default uses default parameters)"),
422 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
423 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
424 #ifdef WITH_SMARTCARD
425 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
427 arg_strx1(NULL
, NULL
, "<HEX CDOLdata/CDOL>", NULL
),
430 CLIExecWithReturn(cmd
, argtable
, false);
432 bool leaveSignalON
= arg_get_lit(1);
433 bool trTypeCDA
= arg_get_lit(2);
434 uint8_t termDecision
= 0xff;
435 if (arg_get_str_len(3)) {
436 if (!strncmp(arg_get_str(3)->sval
[0], "aac", 4))
437 termDecision
= EMVAC_AAC
;
438 if (!strncmp(arg_get_str(3)->sval
[0], "tc", 4))
439 termDecision
= EMVAC_TC
;
440 if (!strncmp(arg_get_str(3)->sval
[0], "arqc", 4))
441 termDecision
= EMVAC_ARQC
;
443 if (termDecision
== 0xff) {
444 PrintAndLog("ERROR: can't find terminal decision '%s'", arg_get_str(3)->sval
[0]);
448 termDecision
= EMVAC_TC
;
451 termDecision
= termDecision
| EMVAC_CDAREQ
;
452 bool paramsLoadFromFile
= arg_get_lit(4);
453 bool dataMakeFromCDOL
= arg_get_lit(5);
454 bool APDULogging
= arg_get_lit(6);
455 bool decodeTLV
= arg_get_lit(7);
456 EMVCommandChannel channel
= ECC_CONTACTLESS
;
457 #ifdef WITH_SMARTCARD
459 channel
= ECC_CONTACT
;
460 CLIGetHexWithReturn(9, data
, &datalen
);
462 CLIGetHexWithReturn(8, data
, &datalen
);
464 PrintChannel(channel
);
467 SetAPDULogging(APDULogging
);
470 const char *alr
= "Root terminal TLV tree";
471 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
474 struct tlv
*cdol_data_tlv
= NULL
;
475 struct tlv data_tlv
= {
478 .value
= (uint8_t *)data
,
481 if (dataMakeFromCDOL
) {
482 ParamLoadDefaults(tlvRoot
);
484 if (paramsLoadFromFile
) {
485 PrintAndLogEx(INFO
, "Params loading from file...");
486 ParamLoadFromJson(tlvRoot
);
489 cdol_data_tlv
= dol_process((const struct tlv
*)tlvdb_external(0x8c, datalen
, data
), tlvRoot
, 0x01); // 0x01 - dummy tag
491 PrintAndLogEx(ERR
, "Can't create CDOL TLV.");
496 if (paramsLoadFromFile
) {
497 PrintAndLogEx(WARNING
, "Don't need to load parameters. Sending plain CDOL data...");
499 cdol_data_tlv
= &data_tlv
;
502 PrintAndLogEx(INFO
, "CDOL data[%d]: %s", cdol_data_tlv
->len
, sprint_hex(cdol_data_tlv
->value
, cdol_data_tlv
->len
));
505 uint8_t buf
[APDU_RESPONSE_LEN
] = {0};
508 int res
= EMVAC(channel
, leaveSignalON
, termDecision
, (uint8_t *)cdol_data_tlv
->value
, cdol_data_tlv
->len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
510 if (cdol_data_tlv
!= &data_tlv
)
515 PrintAndLogEx(INFO
, "APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
521 TLVPrintFromBuffer(buf
, len
);
526 int CmdEMVGenerateChallenge(const char *cmd
) {
528 CLIParserInit("emv challenge",
529 "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.",
530 "Usage:\n\temv challenge -> get challenge\n\temv challenge -k -> get challenge, keep fileld ON\n");
534 arg_lit0("kK", "keep", "keep field ON for next command"),
535 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
536 #ifdef WITH_SMARTCARD
537 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
541 CLIExecWithReturn(cmd
, argtable
, true);
543 bool leaveSignalON
= arg_get_lit(1);
544 bool APDULogging
= arg_get_lit(2);
545 EMVCommandChannel channel
= ECC_CONTACTLESS
;
546 #ifdef WITH_SMARTCARD
548 channel
= ECC_CONTACT
;
550 PrintChannel(channel
);
553 SetAPDULogging(APDULogging
);
556 uint8_t buf
[APDU_RESPONSE_LEN
] = {0};
559 int res
= EMVGenerateChallenge(channel
, leaveSignalON
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
562 PrintAndLogEx(INFO
, "APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
567 PrintAndLogEx(SUCCESS
, "Challenge: %s", sprint_hex(buf
, len
));
569 if (len
!= 4 && len
!= 8)
570 PrintAndLogEx(WARNING
, "Length of challenge must be 4 or 8, but it %d", len
);
575 int CmdEMVInternalAuthenticate(const char *cmd
) {
576 uint8_t data
[APDU_RESPONSE_LEN
] = {0};
579 CLIParserInit("emv intauth",
580 "Generate Internal Authenticate command. Usually needs 4-byte random number. It returns data in TLV format .\n"
581 "Needs a EMV applet to be selected and GPO to be executed.",
584 "\temv intauth -k 01020304 -> execute Internal Authenticate with 4-byte DDOLdata and keep field ON after command\n"
585 "\temv intauth -t 01020304 -> execute Internal Authenticate with 4-byte DDOL data, show result in TLV\n"
586 "\temv intauth -pmt 9F 37 04 -> load params from file, make DDOL data from DDOL, Internal Authenticate with DDOL, show result in TLV");
590 arg_lit0("kK", "keep", "keep field ON for next command"),
591 arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for DDOLdata making from DDOL and parameters"),
592 arg_lit0("mM", "make", "make DDOLdata from DDOL (tag 9F49) and parameters (by default uses default parameters)"),
593 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
594 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
595 #ifdef WITH_SMARTCARD
596 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
598 arg_strx1(NULL
, NULL
, "<HEX DDOLdata/DDOL>", NULL
),
601 CLIExecWithReturn(cmd
, argtable
, false);
603 bool leaveSignalON
= arg_get_lit(1);
604 bool paramsLoadFromFile
= arg_get_lit(2);
605 bool dataMakeFromDDOL
= arg_get_lit(3);
606 bool APDULogging
= arg_get_lit(4);
607 bool decodeTLV
= arg_get_lit(5);
608 EMVCommandChannel channel
= ECC_CONTACTLESS
;
609 #ifdef WITH_SMARTCARD
611 channel
= ECC_CONTACT
;
612 CLIGetHexWithReturn(7, data
, &datalen
);
614 CLIGetHexWithReturn(6, data
, &datalen
);
616 PrintChannel(channel
);
619 SetAPDULogging(APDULogging
);
622 const char *alr
= "Root terminal TLV tree";
623 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
626 struct tlv
*ddol_data_tlv
= NULL
;
627 struct tlv data_tlv
= {
630 .value
= (uint8_t *)data
,
633 if (dataMakeFromDDOL
) {
634 ParamLoadDefaults(tlvRoot
);
636 if (paramsLoadFromFile
) {
637 PrintAndLogEx(INFO
, "Params loading from file...");
638 ParamLoadFromJson(tlvRoot
);
641 ddol_data_tlv
= dol_process((const struct tlv
*)tlvdb_external(0x9f49, datalen
, data
), tlvRoot
, 0x01); // 0x01 - dummy tag
643 PrintAndLogEx(ERR
, "Can't create DDOL TLV.");
648 if (paramsLoadFromFile
) {
649 PrintAndLogEx(WARNING
, "Don't need to load parameters. Sending plain DDOL data...");
651 ddol_data_tlv
= &data_tlv
;
654 PrintAndLogEx(INFO
, "DDOL data[%d]: %s", ddol_data_tlv
->len
, sprint_hex(ddol_data_tlv
->value
, ddol_data_tlv
->len
));
657 uint8_t buf
[APDU_RESPONSE_LEN
] = {0};
660 int res
= EMVInternalAuthenticate(channel
, leaveSignalON
, data
, datalen
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
662 if (ddol_data_tlv
!= &data_tlv
)
667 PrintAndLogEx(INFO
, "APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
673 TLVPrintFromBuffer(buf
, len
);
678 #define dreturn(n) {free(pdol_data_tlv); tlvdb_free(tlvSelect); tlvdb_free(tlvRoot); DropFieldEx( channel ); return n;}
680 void InitTransactionParameters(struct tlvdb
*tlvRoot
, bool paramLoadJSON
, enum TransactionType TrType
, bool GenACGPO
) {
682 ParamLoadDefaults(tlvRoot
);
685 PrintAndLog("* * Transaction parameters loading from JSON...");
686 ParamLoadFromJson(tlvRoot
);
689 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
690 char *qVSDC
= "\x26\x00\x00\x00";
692 qVSDC
= "\x26\x80\x00\x00";
696 TLV_ADD(0x9F66, "\x86\x00\x00\x00"); // MSD
698 // not standard for contactless. just for test.
700 TLV_ADD(0x9F66, "\x46\x00\x00\x00"); // VSDC
703 TLV_ADD(0x9F66, qVSDC
); // qVSDC
706 TLV_ADD(0x9F66, qVSDC
); // qVSDC (VISA CDA not enabled)
713 void ProcessGPOResponseFormat1(struct tlvdb
*tlvRoot
, uint8_t *buf
, size_t len
, bool decodeTLV
) {
714 if (buf
[0] == 0x80) {
716 PrintAndLog("GPO response format1:");
717 TLVPrintFromBuffer(buf
, len
);
720 if (len
< 4 || (len
- 4) % 4) {
721 PrintAndLogEx(ERR
, "GPO response format1 parsing error. length=%d", len
);
724 struct tlvdb
* f1AIP
= tlvdb_fixed(0x82, 2, buf
+ 2);
725 tlvdb_add(tlvRoot
, f1AIP
);
727 PrintAndLogEx(INFO
, "\n* * Decode response format 1 (0x80) AIP and AFL:");
728 TLVPrintFromTLV(f1AIP
);
732 struct tlvdb
* f1AFL
= tlvdb_fixed(0x94, len
- 4, buf
+ 2 + 2);
733 tlvdb_add(tlvRoot
, f1AFL
);
735 TLVPrintFromTLV(f1AFL
);
739 TLVPrintFromBuffer(buf
, len
);
743 void ProcessACResponseFormat1(struct tlvdb
*tlvRoot
, uint8_t *buf
, size_t len
, bool decodeTLV
) {
744 if (buf
[0] == 0x80) {
746 PrintAndLog("GPO response format1:");
747 TLVPrintFromBuffer(buf
, len
);
750 uint8_t elmlen
= len
- 2; // wo 0x80XX
752 if (len
< 4 + 2 || (elmlen
- 2) % 4 || elmlen
!= buf
[1]) {
753 PrintAndLogEx(ERR
, "GPO response format1 parsing error. length=%d", len
);
755 struct tlvdb
*tlvElm
= NULL
;
757 PrintAndLog("\n------------ Format1 decoded ------------");
759 // CID (Cryptogram Information Data)
760 tlvdb_change_or_add_node_ex(tlvRoot
, 0x9f27, 1, &buf
[2], &tlvElm
);
762 TLVPrintFromTLV(tlvElm
);
764 // ATC (Application Transaction Counter)
765 tlvdb_change_or_add_node_ex(tlvRoot
, 0x9f36, 2, &buf
[3], &tlvElm
);
767 TLVPrintFromTLV(tlvElm
);
769 // AC (Application Cryptogram)
770 tlvdb_change_or_add_node_ex(tlvRoot
, 0x9f26, MIN(8, elmlen
- 3), &buf
[5], &tlvElm
);
772 TLVPrintFromTLV(tlvElm
);
774 // IAD (Issuer Application Data) - optional
776 tlvdb_change_or_add_node_ex(tlvRoot
, 0x9f10, elmlen
- 11, &buf
[13], &tlvElm
);
778 TLVPrintFromTLV(tlvElm
);
783 TLVPrintFromBuffer(buf
, len
);
787 int CmdEMVExec(const char *cmd
) {
788 uint8_t buf
[APDU_RESPONSE_LEN
] = {0};
791 uint8_t AID
[APDU_DATA_LEN
] = {0};
793 uint8_t ODAiList
[4096];
794 size_t ODAiListLen
= 0;
798 struct tlvdb
*tlvSelect
= NULL
;
799 struct tlvdb
*tlvRoot
= NULL
;
800 struct tlv
*pdol_data_tlv
= NULL
;
802 CLIParserInit("emv exec",
803 "Executes EMV contactless transaction",
805 "\temv exec -sat -> select card, execute MSD transaction, show APDU and TLV\n"
806 "\temv exec -satc -> select card, execute CDA transaction, show APDU and TLV\n");
810 arg_lit0("sS", "select", "activate field and select card."),
811 arg_lit0("aA", "apdu", "show APDU reqests and responses."),
812 arg_lit0("tT", "tlv", "TLV decode results."),
813 arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."),
814 arg_lit0("fF", "forceaid", "Force search AID. Search AID instead of execute PPSE."),
815 arg_rem("By default:", "Transaction type - MSD"),
816 arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
817 arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
818 arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standart behavior."),
819 arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."),
820 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
823 CLIExecWithReturn(cmd
, argtable
, true);
825 bool activateField
= arg_get_lit(1);
826 bool showAPDU
= arg_get_lit(2);
827 bool decodeTLV
= arg_get_lit(3);
828 bool paramLoadJSON
= arg_get_lit(4);
829 bool forceSearch
= arg_get_lit(5);
831 enum TransactionType TrType
= TT_MSD
;
833 TrType
= TT_QVSDCMCHIP
;
839 bool GenACGPO
= arg_get_lit(10);
840 EMVCommandChannel channel
= ECC_CONTACTLESS
;
841 #ifdef WITH_SMARTCARD
843 channel
= ECC_CONTACT
;
845 PrintChannel(channel
);
846 uint8_t psenum
= (channel
== ECC_CONTACT
) ? 1 : 2;
847 char *PSE_or_PPSE
= psenum
== 1 ? "PSE" : "PPSE";
851 SetAPDULogging(showAPDU
);
853 // init applets list tree
854 const char *al
= "Applets list";
855 tlvSelect
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
);
857 // Application Selection
858 // https://www.openscdp.org/scripts/tutorial/emv/applicationselection.html
861 PrintAndLogEx(NORMAL
, "\n* %s.", PSE_or_PPSE
);
862 SetAPDULogging(showAPDU
);
863 res
= EMVSearchPSE(channel
, activateField
, true, psenum
, decodeTLV
, tlvSelect
);
865 // check PPSE / PSE and select application id
867 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
868 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
);
874 PrintAndLogEx(NORMAL
, "\n* Search AID in list.");
875 SetAPDULogging(false);
876 if (EMVSearch(channel
, activateField
, true, decodeTLV
, tlvSelect
)) {
880 // check search and select application id
881 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
882 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
);
886 const char *alr
= "Root terminal TLV tree";
887 tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
889 // check if we found EMV application on card
891 PrintAndLogEx(WARNING
, "Can't select AID. EMV AID not found");
896 PrintAndLogEx(NORMAL
, "\n* Selecting AID:%s", sprint_hex_inrow(AID
, AIDlen
));
897 SetAPDULogging(showAPDU
);
898 res
= EMVSelect(channel
, false, true, AID
, AIDlen
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
901 PrintAndLogEx(WARNING
, "Can't select AID (%d). Exit...", res
);
906 TLVPrintFromBuffer(buf
, len
);
907 PrintAndLogEx(INFO
, "* Selected.");
909 PrintAndLogEx(INFO
, "\n* Init transaction parameters.");
910 InitTransactionParameters(tlvRoot
, paramLoadJSON
, TrType
, GenACGPO
);
911 TLVPrintFromTLV(tlvRoot
); // TODO delete!!!
913 PrintAndLogEx(NORMAL
, "\n* Calc PDOL.");
914 pdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x9f38, NULL
), tlvRoot
, 0x83);
916 PrintAndLogEx(WARNING
, "Error: can't create PDOL TLV.");
920 size_t pdol_data_tlv_data_len
;
921 unsigned char *pdol_data_tlv_data
= tlv_encode(pdol_data_tlv
, &pdol_data_tlv_data_len
);
922 if (!pdol_data_tlv_data
) {
923 PrintAndLogEx(WARNING
, "Error: can't create PDOL data.");
926 PrintAndLogEx(NORMAL
, "PDOL data[%d]: %s", pdol_data_tlv_data_len
, sprint_hex(pdol_data_tlv_data
, pdol_data_tlv_data_len
));
928 PrintAndLogEx(NORMAL
, "\n* GPO.");
929 res
= EMVGPO(channel
, true, pdol_data_tlv_data
, pdol_data_tlv_data_len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
931 free(pdol_data_tlv_data
);
932 //free(pdol_data_tlv); --- free on exit.
935 PrintAndLogEx(NORMAL
, "GPO error(%d): %4x. Exit...", res
, sw
);
939 // process response template format 1 [id:80 2b AIP + x4b AFL] and format 2 [id:77 TLV]
940 ProcessGPOResponseFormat1(tlvRoot
, buf
, len
, decodeTLV
);
942 // extract PAN from track2
944 const struct tlv
*track2
= tlvdb_get(tlvRoot
, 0x57, NULL
);
945 if (!tlvdb_get(tlvRoot
, 0x5a, NULL
) && track2
&& track2
->len
>= 8) {
946 struct tlvdb
*pan
= GetPANFromTrack2(track2
);
948 tlvdb_add(tlvRoot
, pan
);
950 const struct tlv
*pantlv
= tlvdb_get(tlvRoot
, 0x5a, NULL
);
951 PrintAndLogEx(NORMAL
, "\n* * Extracted PAN from track2: %s", sprint_hex(pantlv
->value
, pantlv
->len
));
953 PrintAndLogEx(NORMAL
, "\n* * WARNING: Can't extract PAN from track2.");
958 PrintAndLogEx(NORMAL
, "\n* Read records from AFL.");
959 const struct tlv
*AFL
= tlvdb_get(tlvRoot
, 0x94, NULL
);
960 if (!AFL
|| !AFL
->len
) {
961 PrintAndLogEx(WARNING
, "AFL not found.");
964 while(AFL
&& AFL
->len
) {
966 PrintAndLogEx(WARNING
, "Error: Wrong AFL length: %d", AFL
->len
);
970 for (int i
= 0; i
< AFL
->len
/ 4; i
++) {
971 uint8_t SFI
= AFL
->value
[i
* 4 + 0] >> 3;
972 uint8_t SFIstart
= AFL
->value
[i
* 4 + 1];
973 uint8_t SFIend
= AFL
->value
[i
* 4 + 2];
974 uint8_t SFIoffline
= AFL
->value
[i
* 4 + 3];
976 PrintAndLogEx(NORMAL
, "* * SFI[%02x] start:%02x end:%02x offline count:%02x", SFI
, SFIstart
, SFIend
, SFIoffline
);
977 if (SFI
== 0 || SFI
== 31 || SFIstart
== 0 || SFIstart
> SFIend
) {
978 PrintAndLogEx(NORMAL
, "SFI ERROR! Skipped...");
982 for(int n
= SFIstart
; n
<= SFIend
; n
++) {
983 PrintAndLogEx(NORMAL
, "* * * SFI[%02x] %d", SFI
, n
);
985 res
= EMVReadRecord(channel
, true, SFI
, n
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
987 PrintAndLogEx(WARNING
, "Error SFI[%02x]. APDU error %4x", SFI
, sw
);
992 TLVPrintFromBuffer(buf
, len
);
993 PrintAndLogEx(NORMAL
, "");
996 // Build Input list for Offline Data Authentication
997 // EMV 4.3 book3 10.3, page 96
998 if (SFIoffline
> 0) {
1000 const unsigned char *abuf
= buf
;
1001 size_t elmlen
= len
;
1003 if (tlv_parse_tl(&abuf
, &elmlen
, &e
)) {
1004 memcpy(&ODAiList
[ODAiListLen
], &buf
[len
- elmlen
], elmlen
);
1005 ODAiListLen
+= elmlen
;
1007 PrintAndLogEx(WARNING
, "Error SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI
);
1010 memcpy(&ODAiList
[ODAiListLen
], buf
, len
);
1022 // copy Input list for Offline Data Authentication
1024 struct tlvdb
*oda
= tlvdb_fixed(0x21, ODAiListLen
, ODAiList
); // not a standard tag
1025 tlvdb_add(tlvRoot
, oda
);
1026 PrintAndLogEx(NORMAL
, "* Input list for Offline Data Authentication added to TLV. len=%d \n", ODAiListLen
);
1031 const struct tlv
*AIPtlv
= tlvdb_get(tlvRoot
, 0x82, NULL
);
1033 AIP
= AIPtlv
->value
[0] + AIPtlv
->value
[1] * 0x100;
1034 PrintAndLogEx(NORMAL
, "* * AIP=%04x", AIP
);
1036 PrintAndLogEx(ERR
, "Can't found AIP.");
1041 PrintAndLogEx(NORMAL
, "\n* SDA");
1047 PrintAndLogEx(NORMAL
, "\n* DDA");
1048 trDDA(channel
, decodeTLV
, tlvRoot
);
1051 // transaction check
1054 if (TrType
== TT_QVSDCMCHIP
|| TrType
== TT_CDA
){
1055 // 9F26: Application Cryptogram
1056 const struct tlv
*AC
= tlvdb_get(tlvRoot
, 0x9F26, NULL
);
1058 PrintAndLogEx(NORMAL
, "\n--> qVSDC transaction.");
1059 PrintAndLogEx(NORMAL
, "* AC path");
1061 // 9F36: Application Transaction Counter (ATC)
1062 const struct tlv
*ATC
= tlvdb_get(tlvRoot
, 0x9F36, NULL
);
1065 // 9F10: Issuer Application Data - optional
1066 const struct tlv
*IAD
= tlvdb_get(tlvRoot
, 0x9F10, NULL
);
1069 PrintAndLogEx(NORMAL
, "ATC: %s", sprint_hex(ATC
->value
, ATC
->len
));
1070 PrintAndLogEx(NORMAL
, "AC: %s", sprint_hex(AC
->value
, AC
->len
));
1072 PrintAndLogEx(NORMAL
, "IAD: %s", sprint_hex(IAD
->value
, IAD
->len
));
1074 if (IAD
->len
>= IAD
->value
[0] + 1) {
1075 PrintAndLogEx(NORMAL
, "\tKey index: 0x%02x", IAD
->value
[1]);
1076 PrintAndLogEx(NORMAL
, "\tCrypto ver: 0x%02x(%03d)", IAD
->value
[2], IAD
->value
[2]);
1077 PrintAndLogEx(NORMAL
, "\tCVR:", sprint_hex(&IAD
->value
[3], IAD
->value
[0] - 2));
1078 struct tlvdb
* cvr
= tlvdb_fixed(0x20, IAD
->value
[0] - 2, &IAD
->value
[3]);
1079 TLVPrintFromTLVLev(cvr
, 1);
1082 PrintAndLogEx(WARNING
, "IAD not found.");
1086 PrintAndLogEx(ERR
, "AC: Application Transaction Counter (ATC) not found.");
1091 // Mastercard M/CHIP
1092 if (GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
&& (TrType
== TT_QVSDCMCHIP
|| TrType
== TT_CDA
)){
1093 const struct tlv
*CDOL1
= tlvdb_get(tlvRoot
, 0x8c, NULL
);
1094 if (CDOL1
&& GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
) { // and m/chip transaction flag
1095 PrintAndLogEx(NORMAL
, "\n--> Mastercard M/Chip transaction.");
1097 PrintAndLogEx(NORMAL
, "* * Generate challenge");
1098 res
= EMVGenerateChallenge(channel
, true, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1100 PrintAndLogEx(WARNING
, "GetChallenge. APDU error %4x", sw
);
1104 PrintAndLogEx(WARNING
, "GetChallenge. Wrong challenge length %d", len
);
1108 // ICC Dynamic Number
1109 struct tlvdb
* ICCDynN
= tlvdb_fixed(0x9f4c, len
, buf
);
1110 tlvdb_add(tlvRoot
, ICCDynN
);
1112 PrintAndLogEx(NORMAL
, "\n* * ICC Dynamic Number:");
1113 TLVPrintFromTLV(ICCDynN
);
1116 PrintAndLogEx(NORMAL
, "* * Calc CDOL1");
1117 struct tlv
*cdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x8c, NULL
), tlvRoot
, 0x01); // 0x01 - dummy tag
1118 if (!cdol_data_tlv
){
1119 PrintAndLogEx(WARNING
, "Error: can't create CDOL1 TLV.");
1122 PrintAndLogEx(NORMAL
, "CDOL1 data[%d]: %s", cdol_data_tlv
->len
, sprint_hex(cdol_data_tlv
->value
, cdol_data_tlv
->len
));
1124 PrintAndLogEx(NORMAL
, "* * AC1");
1125 // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD
1126 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
);
1129 PrintAndLogEx(NORMAL
, "AC1 error(%d): %4x. Exit...", res
, sw
);
1134 TLVPrintFromBuffer(buf
, len
);
1137 PrintAndLogEx(NORMAL
, "\n* CDA:");
1138 struct tlvdb
*ac_tlv
= tlvdb_parse_multi(buf
, len
);
1139 res
= trCDA(tlvRoot
, ac_tlv
, pdol_data_tlv
, cdol_data_tlv
);
1141 PrintAndLogEx(NORMAL
, "CDA error (%d)", res
);
1144 free(cdol_data_tlv
);
1146 PrintAndLogEx(NORMAL
, "\n* M/Chip transaction result:");
1147 // 9F27: Cryptogram Information Data (CID)
1148 const struct tlv
*CID
= tlvdb_get(tlvRoot
, 0x9F27, NULL
);
1150 emv_tag_dump(CID
, stdout
, 0);
1151 PrintAndLogEx(NORMAL
, "------------------------------");
1153 switch(CID
->value
[0] & EMVAC_AC_MASK
){
1155 PrintAndLogEx(NORMAL
, "Transaction DECLINED.");
1158 PrintAndLogEx(NORMAL
, "Transaction approved OFFLINE.");
1161 PrintAndLogEx(NORMAL
, "Transaction approved ONLINE.");
1164 PrintAndLogEx(WARNING
, "Error: CID transaction code error %2x", CID
->value
[0] & EMVAC_AC_MASK
);
1168 PrintAndLogEx(WARNING
, "Wrong CID length %d", CID
->len
);
1171 PrintAndLogEx(WARNING
, "CID(9F27) not found.");
1178 if (AIP
& 0x8000 && TrType
== TT_MSD
) {
1179 PrintAndLogEx(NORMAL
, "\n--> MSD transaction.");
1181 PrintAndLogEx(NORMAL
, "* MSD dCVV path. Check dCVV");
1183 const struct tlv
*track2
= tlvdb_get(tlvRoot
, 0x57, NULL
);
1185 PrintAndLogEx(NORMAL
, "Track2: %s", sprint_hex(track2
->value
, track2
->len
));
1187 struct tlvdb
*dCVV
= GetdCVVRawFromTrack2(track2
);
1188 PrintAndLogEx(NORMAL
, "dCVV raw data:");
1189 TLVPrintFromTLV(dCVV
);
1191 if (GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
) {
1192 PrintAndLogEx(NORMAL
, "\n* Mastercard calculate UDOL");
1195 const struct tlv
*UDOL
= tlvdb_get(tlvRoot
, 0x9F69, NULL
);
1196 // UDOL(9F69) default: 9F6A (Unpredictable number) 4 bytes
1197 const struct tlv defUDOL
= {
1200 .value
= (uint8_t *)"\x9f\x6a\x04",
1203 PrintAndLogEx(NORMAL
, "Use default UDOL.");
1205 struct tlv
*udol_data_tlv
= dol_process(UDOL
? UDOL
: &defUDOL
, tlvRoot
, 0x01); // 0x01 - dummy tag
1206 if (!udol_data_tlv
){
1207 PrintAndLogEx(WARNING
, "can't create UDOL TLV.");
1211 PrintAndLogEx(NORMAL
, "UDOL data[%d]: %s", udol_data_tlv
->len
, sprint_hex(udol_data_tlv
->value
, udol_data_tlv
->len
));
1213 PrintAndLogEx(NORMAL
, "\n* Mastercard compute cryptographic checksum(UDOL)");
1215 res
= MSCComputeCryptoChecksum(channel
, true, (uint8_t *)udol_data_tlv
->value
, udol_data_tlv
->len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1217 PrintAndLogEx(WARNING
, "Compute Crypto Checksum. APDU error %4x", sw
);
1218 free(udol_data_tlv
);
1222 // Mastercard compute cryptographic checksum result
1223 TLVPrintFromBuffer(buf
, len
);
1224 PrintAndLogEx(NORMAL
, "");
1226 free(udol_data_tlv
);
1230 PrintAndLogEx(WARNING
, "MSD: Track2 data not found.");
1235 if (GetCardPSVendor(AID
, AIDlen
) == CV_VISA
&& (TrType
== TT_VSDC
|| TrType
== TT_CDA
)){
1236 PrintAndLogEx(NORMAL
, "\n--> VSDC transaction.");
1238 PrintAndLogEx(NORMAL
, "* * Calc CDOL1");
1239 struct tlv
*cdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x8c, NULL
), tlvRoot
, 0x01); // 0x01 - dummy tag
1240 if (!cdol_data_tlv
) {
1241 PrintAndLogEx(WARNING
, "Error: can't create CDOL1 TLV.");
1245 PrintAndLogEx(NORMAL
, "CDOL1 data[%d]: %s", cdol_data_tlv
->len
, sprint_hex(cdol_data_tlv
->value
, cdol_data_tlv
->len
));
1247 PrintAndLogEx(NORMAL
, "* * AC1");
1248 // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD
1249 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
);
1252 PrintAndLogEx(NORMAL
, "AC1 error(%d): %4x. Exit...", res
, sw
);
1256 // process Format1 (0x80) and print Format2 (0x77)
1257 ProcessACResponseFormat1(tlvRoot
, buf
, len
, decodeTLV
);
1260 tlvdb_get_uint8(tlvRoot
, 0x9f27, &CID
);
1264 if ((CID
& EMVAC_AC_MASK
) == EMVAC_AAC
) PrintAndLogEx(INFO
, "AC1 result: AAC (Transaction declined)");
1265 if ((CID
& EMVAC_AC_MASK
) == EMVAC_TC
) PrintAndLogEx(INFO
, "AC1 result: TC (Transaction approved)");
1266 if ((CID
& EMVAC_AC_MASK
) == EMVAC_ARQC
) PrintAndLogEx(INFO
, "AC1 result: ARQC (Online authorisation requested)");
1267 if ((CID
& EMVAC_AC_MASK
) == EMVAC_AC_MASK
) PrintAndLogEx(INFO
, "AC1 result: RFU");
1269 // decode Issuer Application Data (IAD)
1270 uint8_t CryptoVersion
= 0;
1271 const struct tlv
*IAD
= tlvdb_get(tlvRoot
, 0x9f10, NULL
);
1272 if (IAD
&& (IAD
->len
> 1)) {
1273 PrintAndLogEx(NORMAL
, "\n* * Issuer Application Data (IAD):");
1274 uint8_t VDDlen
= IAD
->value
[0]; // Visa discretionary data length
1275 uint8_t IDDlen
= 0; // Issuer discretionary data length
1276 PrintAndLogEx(NORMAL
, "IAD length: %d", IAD
->len
);
1277 PrintAndLogEx(NORMAL
, "VDDlen: %d", VDDlen
);
1278 if (VDDlen
< IAD
->len
- 1)
1279 IDDlen
= IAD
->value
[VDDlen
+ 1];
1280 PrintAndLogEx(NORMAL
, "IDDlen: %d", IDDlen
);
1282 uint8_t DerivKeyIndex
= IAD
->value
[1];
1283 CryptoVersion
= IAD
->value
[2];
1285 PrintAndLogEx(NORMAL
, "CryptoVersion: %d", CryptoVersion
);
1286 PrintAndLogEx(NORMAL
, "DerivKeyIndex: %d", DerivKeyIndex
);
1288 // Card Verification Results (CVR) decode
1289 if ((VDDlen
- 2) > 0) {
1290 uint8_t CVRlen
= IAD
->value
[3];
1291 if (CVRlen
== (VDDlen
- 2 - 1)) {
1292 PrintAndLogEx(NORMAL
, "CVR length: %d", CVRlen
);
1293 PrintAndLogEx(NORMAL
, "CVR: %s", sprint_hex(&IAD
->value
[4], CVRlen
));
1295 PrintAndLogEx(NORMAL
, "Wrong CVR length! CVR: %s", sprint_hex(&IAD
->value
[3], VDDlen
- 2));
1299 PrintAndLogEx(NORMAL
, "IDD: %s", sprint_hex(&IAD
->value
[VDDlen
+ 1], IDDlen
));
1301 PrintAndLogEx(NORMAL
, "Issuer Application Data (IAD) not found.");
1304 PrintAndLogEx(NORMAL
, "\n* * Processing online request");
1306 // authorization response code from acquirer
1307 const char HostResponse
[] = "00"; // 0x3030
1308 size_t HostResponseLen
= sizeof(HostResponse
) - 1;
1309 PrintAndLogEx(NORMAL
, "Host Response: `%s`", HostResponse
);
1310 tlvdb_change_or_add_node(tlvRoot
, 0x8a, HostResponseLen
, (const unsigned char *)HostResponse
);
1312 if (CryptoVersion
== 10) {
1313 PrintAndLogEx(NORMAL
, "\n* * Generate ARPC");
1315 // Application Cryptogram (AC)
1316 const struct tlv
*AC
= tlvdb_get(tlvRoot
, 0x9f26, NULL
);
1317 if (AC
&& (AC
->len
> 0)) {
1318 PrintAndLogEx(NORMAL
, "AC: %s", sprint_hex(AC
->value
, AC
->len
));
1320 size_t rawARPClen
= AC
->len
;
1321 uint8_t rawARPC
[rawARPClen
];
1322 memcpy(rawARPC
, AC
->value
, AC
->len
);
1323 for (int i
= 0; (i
< HostResponseLen
) && (i
< rawARPClen
); i
++)
1324 rawARPC
[i
] ^= HostResponse
[i
];
1325 PrintAndLogEx(NORMAL
, "raw ARPC: %s", sprint_hex(rawARPC
, rawARPClen
));
1327 // here must be calculation of ARPC, but we dont know a bank keys.
1328 PrintAndLogEx(NORMAL
, "ARPC: n/a");
1331 PrintAndLogEx(NORMAL
, "Application Cryptogram (AC) not found.");
1334 // here must be external authenticate, but we dont know ARPC
1339 // needs to send AC2 command (res == ARQC)
1340 if ((CID
& EMVAC_AC_MASK
) == EMVAC_ARQC
) {
1341 PrintAndLogEx(NORMAL
, "\n* * Calc CDOL2");
1342 struct tlv
*cdol2_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x8d, NULL
), tlvRoot
, 0x01); // 0x01 - dummy tag
1343 if (!cdol2_data_tlv
) {
1344 PrintAndLogEx(WARNING
, "Error: can't create CDOL2 TLV.");
1348 PrintAndLogEx(NORMAL
, "CDOL2 data[%d]: %s", cdol2_data_tlv
->len
, sprint_hex(cdol2_data_tlv
->value
, cdol2_data_tlv
->len
));
1350 //PrintAndLogEx(NORMAL, "* * AC2");
1353 // here must be AC2, but we dont make external authenticate (
1356 PRINT_INDENT(level);
1357 if ((CID & EMVAC_AC2_MASK) == EMVAC_AAC2) fprintf(f, "\tAC2: AAC (Transaction declined)\n");
1358 if ((CID & EMVAC_AC2_MASK) == EMVAC_TC2) fprintf(f, "\tAC2: TC (Transaction approved)\n");
1359 if ((CID & EMVAC_AC2_MASK) == EMVAC_ARQC2) fprintf(f, "\tAC2: not requested (ARQC)\n");
1360 if ((CID & EMVAC_AC2_MASK) == EMVAC_AC2_MASK) fprintf(f, "\tAC2: RFU\n");
1366 DropFieldEx( channel
);
1369 free(pdol_data_tlv
);
1370 tlvdb_free(tlvSelect
);
1371 tlvdb_free(tlvRoot
);
1373 PrintAndLogEx(NORMAL
, "\n* Transaction completed.");
1377 int CmdEMVScan(const char *cmd
) {
1378 uint8_t AID
[APDU_DATA_LEN
] = {0};
1380 uint8_t buf
[APDU_RESPONSE_LEN
] = {0};
1387 CLIParserInit("emv scan",
1388 "Scan EMV card and save it contents to a file.",
1389 "It executes EMV contactless transaction and saves result to a file which can be used for emulation\n"
1390 "Usage:\n\temv scan -at -> scan MSD transaction mode and show APDU and TLV\n"
1391 "\temv scan -c -> scan CDA transaction mode\n");
1393 void* argtable
[] = {
1395 arg_lit0("aA", "apdu", "show APDU reqests and responses."),
1396 arg_lit0("tT", "tlv", "TLV decode results."),
1397 arg_lit0("eE", "extract", "Extract TLV elements and fill Application Data"),
1398 arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."),
1399 arg_rem("By default:", "Transaction type - MSD"),
1400 arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
1401 arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
1402 arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standart behavior."),
1403 arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."),
1404 arg_lit0("mM", "merge", "Merge output file with card's data. (warning: the file may be corrupted!)"),
1405 #ifdef WITH_SMARTCARD
1406 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
1408 arg_str1(NULL
, NULL
, "output.json", "JSON output file name"),
1411 CLIExecWithReturn(cmd
, argtable
, true);
1413 bool showAPDU
= arg_get_lit(1);
1414 bool decodeTLV
= arg_get_lit(2);
1415 bool extractTLVElements
= arg_get_lit(3);
1416 bool paramLoadJSON
= arg_get_lit(4);
1418 enum TransactionType TrType
= TT_MSD
;
1420 TrType
= TT_QVSDCMCHIP
;
1426 bool GenACGPO
= arg_get_lit(9);
1427 bool MergeJSON
= arg_get_lit(10);
1428 EMVCommandChannel channel
= ECC_CONTACTLESS
;
1429 uint8_t relfname
[250] = {0};
1430 char *crelfname
= (char *)relfname
;
1431 int relfnamelen
= 0;
1432 #ifdef WITH_SMARTCARD
1433 if (arg_get_lit(11)) {
1434 channel
= ECC_CONTACT
;
1436 CLIGetStrWithReturn(12, relfname
, &relfnamelen
);
1438 CLIGetStrWithReturn(11, relfname
, &relfnamelen
);
1440 PrintChannel(channel
);
1441 uint8_t psenum
= (channel
== ECC_CONTACT
) ? 1 : 2;
1444 SetAPDULogging(showAPDU
);
1446 // current path + file name
1447 if (!strstr(crelfname
, ".json"))
1448 strcat(crelfname
, ".json");
1449 char fname
[strlen(get_my_executable_directory()) + strlen(crelfname
) + 1];
1450 strcpy(fname
, get_my_executable_directory());
1451 strcat(fname
, crelfname
);
1454 root
= json_load_file(fname
, 0, &error
);
1456 PrintAndLogEx(ERR
, "json error on line %d: %s", error
.line
, error
.text
);
1460 if (!json_is_object(root
)) {
1461 PrintAndLogEx(ERR
, "Invalid json format. root must be an object.");
1465 root
= json_object();
1468 // drop field at start
1469 DropFieldEx( channel
);
1471 JsonSaveStr(root
, "$.File.Created", "proxmark3 `emv scan`");
1473 if (channel
== ECC_CONTACTLESS
) {
1475 PrintAndLogEx(NORMAL
, "--> GET UID, ATS.");
1477 iso14a_card_select_t card
;
1478 if (Hf14443_4aGetCardData(&card
)) {
1482 PrintAndLogEx(ERR
, "get ATS error");
1486 JsonSaveStr(root
, "$.Card.Contactless.Communication", "iso14443-4a");
1487 JsonSaveBufAsHex(root
, "$.Card.Contactless.UID", (uint8_t *)&card
.uid
, card
.uidlen
);
1488 JsonSaveHex(root
, "$.Card.Contactless.ATQA", card
.atqa
[0] + (card
.atqa
[1] << 2), 2);
1489 JsonSaveHex(root
, "$.Card.Contactless.SAK", card
.sak
, 0);
1490 JsonSaveBufAsHex(root
, "$.Card.Contactless.ATS", (uint8_t *)card
.ats
, card
.ats_len
);
1492 PrintAndLogEx(NORMAL
, "--> GET ATR.");
1494 smart_card_atr_t ccard
;
1495 smart_getATR(&ccard
);
1497 if (!ccard
.atr_len
) {
1498 PrintAndLogEx(ERR
, "get ATR error");
1502 JsonSaveStr(root
, "$.Card.Contact.Communication", "iso7816");
1503 JsonSaveBufAsHex(root
, "$.Card.Contact.ATR", (uint8_t *)ccard
.atr
, ccard
.atr_len
);
1506 // init applets list tree
1507 const char *al
= "Applets list";
1508 struct tlvdb
*tlvSelect
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
);
1511 PrintAndLogEx(NORMAL
, "--> PPSE.");
1512 res
= EMVSelectPSE(channel
, true, true, 2, buf
, sizeof(buf
), &len
, &sw
);
1514 if (!res
&& sw
== 0x9000){
1516 TLVPrintFromBuffer(buf
, len
);
1518 JsonSaveBufAsHex(root
, "$.PPSE.AID", (uint8_t *)"2PAY.SYS.DDF01", 14);
1520 struct tlvdb
*fci
= tlvdb_parse_multi(buf
, len
);
1521 if (extractTLVElements
)
1522 JsonSaveTLVTree(root
, root
, "$.PPSE.FCITemplate", fci
);
1524 JsonSaveTLVTreeElm(root
, "$.PPSE.FCITemplate", fci
, true, true, false);
1525 JsonSaveTLVValue(root
, "$.Application.KernelID", tlvdb_find_full(fci
, 0x9f2a));
1529 res
= EMVSearchPSE(channel
, false, true, psenum
, decodeTLV
, tlvSelect
);
1531 // check PPSE and select application id
1533 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
1535 // EMV SEARCH with AID list
1536 SetAPDULogging(false);
1537 PrintAndLogEx(NORMAL
, "--> AID search.");
1538 if (EMVSearch(channel
, false, true, decodeTLV
, tlvSelect
)) {
1539 PrintAndLogEx(ERR
, "Can't found any of EMV AID. Exit...");
1540 tlvdb_free(tlvSelect
);
1541 DropFieldEx( channel
);
1545 // check search and select application id
1546 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
1549 // EMV SELECT application
1550 SetAPDULogging(showAPDU
);
1551 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
);
1553 tlvdb_free(tlvSelect
);
1556 PrintAndLogEx(INFO
, "Can't select AID. EMV AID not found. Exit...");
1557 DropFieldEx( channel
);
1561 JsonSaveBufAsHex(root
, "$.Application.AID", AID
, AIDlen
);
1564 const char *alr
= "Root terminal TLV tree";
1565 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
1567 // EMV SELECT applet
1569 PrintAndLogEx(NORMAL
, "\n-->Selecting AID:%s.", sprint_hex_inrow(AID
, AIDlen
));
1570 SetAPDULogging(showAPDU
);
1571 res
= EMVSelect(channel
, false, true, AID
, AIDlen
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1574 PrintAndLogEx(ERR
, "Can't select AID (%d). Exit...", res
);
1575 tlvdb_free(tlvRoot
);
1576 DropFieldEx( channel
);
1581 TLVPrintFromBuffer(buf
, len
);
1584 if (tlvdb_get(tlvRoot
, 0x9f38, NULL
)) {
1585 JsonSaveStr(root
, "$.Application.Mode", TransactionTypeStr
[TrType
]);
1588 struct tlvdb
*fci
= tlvdb_parse_multi(buf
, len
);
1589 if (extractTLVElements
)
1590 JsonSaveTLVTree(root
, root
, "$.Application.FCITemplate", fci
);
1592 JsonSaveTLVTreeElm(root
, "$.Application.FCITemplate", fci
, true, true, false);
1595 // create transaction parameters
1596 PrintAndLogEx(NORMAL
, "-->Init transaction parameters.");
1597 InitTransactionParameters(tlvRoot
, paramLoadJSON
, TrType
, GenACGPO
);
1599 PrintAndLogEx(NORMAL
, "-->Calc PDOL.");
1600 struct tlv
*pdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x9f38, NULL
), tlvRoot
, 0x83);
1601 if (!pdol_data_tlv
){
1602 PrintAndLogEx(ERR
, "Can't create PDOL TLV.");
1603 tlvdb_free(tlvRoot
);
1604 DropFieldEx( channel
);
1608 size_t pdol_data_tlv_data_len
;
1609 unsigned char *pdol_data_tlv_data
= tlv_encode(pdol_data_tlv
, &pdol_data_tlv_data_len
);
1610 if (!pdol_data_tlv_data
) {
1611 PrintAndLogEx(ERR
, "Can't create PDOL data.");
1612 tlvdb_free(tlvRoot
);
1613 DropFieldEx( channel
);
1616 PrintAndLogEx(INFO
, "PDOL data[%d]: %s", pdol_data_tlv_data_len
, sprint_hex(pdol_data_tlv_data
, pdol_data_tlv_data_len
));
1618 PrintAndLogEx(INFO
, "-->GPO.");
1619 res
= EMVGPO(channel
, true, pdol_data_tlv_data
, pdol_data_tlv_data_len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1621 free(pdol_data_tlv_data
);
1622 free(pdol_data_tlv
);
1625 PrintAndLogEx(ERR
, "GPO error(%d): %4x. Exit...", res
, sw
);
1626 tlvdb_free(tlvRoot
);
1627 DropFieldEx( channel
);
1630 ProcessGPOResponseFormat1(tlvRoot
, buf
, len
, decodeTLV
);
1632 struct tlvdb
*gpofci
= tlvdb_parse_multi(buf
, len
);
1633 if (extractTLVElements
)
1634 JsonSaveTLVTree(root
, root
, "$.Application.GPO", gpofci
);
1636 JsonSaveTLVTreeElm(root
, "$.Application.GPO", gpofci
, true, true, false);
1638 JsonSaveTLVValue(root
, "$.ApplicationData.AIP", tlvdb_find_full(gpofci
, 0x82));
1639 JsonSaveTLVValue(root
, "$.ApplicationData.AFL", tlvdb_find_full(gpofci
, 0x94));
1643 PrintAndLogEx(INFO
, "-->Read records from AFL.");
1644 const struct tlv
*AFL
= tlvdb_get(tlvRoot
, 0x94, NULL
);
1646 while(AFL
&& AFL
->len
) {
1648 PrintAndLogEx(ERR
, "Wrong AFL length: %d", AFL
->len
);
1652 json_t
*sfijson
= json_path_get(root
, "$.Application.Records");
1654 json_t
*app
= json_path_get(root
, "$.Application");
1655 json_object_set_new(app
, "Records", json_array());
1657 sfijson
= json_path_get(root
, "$.Application.Records");
1659 if (!json_is_array(sfijson
)) {
1660 PrintAndLogEx(ERR
, "Internal logic error. `$.Application.Records` is not an array.");
1663 for (int i
= 0; i
< AFL
->len
/ 4; i
++) {
1664 uint8_t SFI
= AFL
->value
[i
* 4 + 0] >> 3;
1665 uint8_t SFIstart
= AFL
->value
[i
* 4 + 1];
1666 uint8_t SFIend
= AFL
->value
[i
* 4 + 2];
1667 uint8_t SFIoffline
= AFL
->value
[i
* 4 + 3];
1669 PrintAndLogEx(INFO
, "--->SFI[%02x] start:%02x end:%02x offline:%02x", SFI
, SFIstart
, SFIend
, SFIoffline
);
1670 if (SFI
== 0 || SFI
== 31 || SFIstart
== 0 || SFIstart
> SFIend
) {
1671 PrintAndLogEx(ERR
, "SFI ERROR! Skipped...");
1675 for(int n
= SFIstart
; n
<= SFIend
; n
++) {
1676 PrintAndLogEx(INFO
, "---->SFI[%02x] %d", SFI
, n
);
1678 res
= EMVReadRecord(channel
, true, SFI
, n
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1680 PrintAndLogEx(ERR
, "SFI[%02x]. APDU error %4x", SFI
, sw
);
1685 TLVPrintFromBuffer(buf
, len
);
1686 PrintAndLogEx(NORMAL
, "");
1689 json_t
*jsonelm
= json_object();
1690 json_array_append_new(sfijson
, jsonelm
);
1692 JsonSaveHex(jsonelm
, "SFI", SFI
, 1);
1693 JsonSaveHex(jsonelm
, "RecordNum", n
, 1);
1694 JsonSaveHex(jsonelm
, "Offline", SFIoffline
, 1);
1696 struct tlvdb
*rsfi
= tlvdb_parse_multi(buf
, len
);
1697 if (extractTLVElements
)
1698 JsonSaveTLVTree(root
, jsonelm
, "$.Data", rsfi
);
1700 JsonSaveTLVTreeElm(jsonelm
, "$.Data", rsfi
, true, true, false);
1708 // getting certificates
1709 if (tlvdb_get(tlvRoot
, 0x90, NULL
)) {
1710 PrintAndLogEx(INFO
, "-->Recovering certificates.");
1711 PKISetStrictExecution(false);
1712 RecoveryCertificates(tlvRoot
, root
);
1713 PKISetStrictExecution(true);
1717 tlvdb_free(tlvRoot
);
1719 DropFieldEx( channel
);
1721 res
= json_dump_file(root
, fname
, JSON_INDENT(2));
1723 PrintAndLogEx(ERR
, "Can't save the file: %s", fname
);
1726 PrintAndLogEx(SUCCESS
, "File `%s` saved.", fname
);
1734 int CmdEMVTest(const char *cmd
) {
1735 return ExecuteCryptoTests(true);
1738 int CmdEMVRoca(const char *cmd
) {
1739 uint8_t AID
[APDU_DATA_LEN
] = {0};
1741 uint8_t buf
[APDU_RESPONSE_LEN
] = {0};
1745 uint8_t ODAiList
[4096];
1746 size_t ODAiListLen
= 0;
1748 CLIParserInit("emv roca",
1749 "Tries to extract public keys and run the ROCA test against them.\n",
1751 "\temv roca -w -> select --CONTACT-- card and run test\n"
1752 "\temv roca -> select --CONTACTLESS-- card and run test\n"
1755 void* argtable
[] = {
1757 arg_lit0("tT", "selftest", "self test"),
1758 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
1759 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
1762 CLIExecWithReturn(cmd
, argtable
, true);
1765 return roca_self_test();
1766 bool showAPDU
= arg_get_lit(2);
1768 EMVCommandChannel channel
= ECC_CONTACTLESS
;
1769 #ifdef WITH_SMARTCARD
1771 channel
= ECC_CONTACT
;
1773 PrintChannel(channel
);
1777 uint8_t psenum
= (channel
== ECC_CONTACT
) ? 1 : 2;
1778 char *PSE_or_PPSE
= psenum
== 1 ? "PSE" : "PPSE";
1780 SetAPDULogging(showAPDU
);
1782 // init applets list tree
1783 const char *al
= "Applets list";
1784 struct tlvdb
*tlvSelect
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
);
1787 PrintAndLogEx(NORMAL
, "--> %s.", PSE_or_PPSE
);
1788 res
= EMVSearchPSE(channel
, true, true, psenum
, false, tlvSelect
);
1790 // check PSE/PPSE and select application id
1792 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
1794 // EMV SEARCH with AID list
1795 PrintAndLogEx(NORMAL
, "--> AID search.");
1796 if (EMVSearch(channel
, false, true, false, tlvSelect
)) {
1797 PrintAndLogEx(ERR
, "Couldn't find any known EMV AID. Exit...");
1798 tlvdb_free(tlvSelect
);
1799 DropFieldEx( channel
);
1803 // check search and select application id
1804 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
1807 // EMV SELECT application
1808 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
);
1810 tlvdb_free(tlvSelect
);
1813 PrintAndLogEx(INFO
, "Can't select AID. EMV AID not found. Exit...");
1814 DropFieldEx( channel
);
1819 const char *alr
= "Root terminal TLV tree";
1820 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
1822 // EMV SELECT applet
1823 PrintAndLogEx(NORMAL
, "\n-->Selecting AID:%s.", sprint_hex_inrow(AID
, AIDlen
));
1824 res
= EMVSelect(channel
, false, true, AID
, AIDlen
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1827 PrintAndLogEx(ERR
, "Can't select AID (%d). Exit...", res
);
1828 tlvdb_free(tlvRoot
);
1829 DropFieldEx( channel
);
1833 PrintAndLog("\n* Init transaction parameters.");
1834 InitTransactionParameters(tlvRoot
, true, TT_QVSDCMCHIP
, false);
1836 PrintAndLogEx(NORMAL
, "-->Calc PDOL.");
1837 struct tlv
*pdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x9f38, NULL
), tlvRoot
, 0x83);
1838 if (!pdol_data_tlv
){
1839 PrintAndLogEx(ERR
, "Can't create PDOL TLV.");
1840 tlvdb_free(tlvRoot
);
1841 DropFieldEx( channel
);
1845 size_t pdol_data_tlv_data_len
;
1846 unsigned char *pdol_data_tlv_data
= tlv_encode(pdol_data_tlv
, &pdol_data_tlv_data_len
);
1847 if (!pdol_data_tlv_data
) {
1848 PrintAndLogEx(ERR
, "Can't create PDOL data.");
1849 tlvdb_free(tlvRoot
);
1850 DropFieldEx( channel
);
1853 PrintAndLogEx(INFO
, "PDOL data[%d]: %s", pdol_data_tlv_data_len
, sprint_hex(pdol_data_tlv_data
, pdol_data_tlv_data_len
));
1855 PrintAndLogEx(INFO
, "-->GPO.");
1856 res
= EMVGPO(channel
, true, pdol_data_tlv_data
, pdol_data_tlv_data_len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1858 free(pdol_data_tlv_data
);
1859 free(pdol_data_tlv
);
1862 PrintAndLogEx(ERR
, "GPO error(%d): %4x. Exit...", res
, sw
);
1863 tlvdb_free(tlvRoot
);
1864 DropFieldEx( channel
);
1867 ProcessGPOResponseFormat1(tlvRoot
, buf
, len
, false);
1869 PrintAndLogEx(INFO
, "-->Read records from AFL.");
1870 const struct tlv
*AFL
= tlvdb_get(tlvRoot
, 0x94, NULL
);
1872 while(AFL
&& AFL
->len
) {
1874 PrintAndLogEx(ERR
, "Wrong AFL length: %d", AFL
->len
);
1878 for (int i
= 0; i
< AFL
->len
/ 4; i
++) {
1879 uint8_t SFI
= AFL
->value
[i
* 4 + 0] >> 3;
1880 uint8_t SFIstart
= AFL
->value
[i
* 4 + 1];
1881 uint8_t SFIend
= AFL
->value
[i
* 4 + 2];
1882 uint8_t SFIoffline
= AFL
->value
[i
* 4 + 3];
1884 PrintAndLogEx(INFO
, "--->SFI[%02x] start:%02x end:%02x offline:%02x", SFI
, SFIstart
, SFIend
, SFIoffline
);
1885 if (SFI
== 0 || SFI
== 31 || SFIstart
== 0 || SFIstart
> SFIend
) {
1886 PrintAndLogEx(ERR
, "SFI ERROR! Skipped...");
1890 for(int n
= SFIstart
; n
<= SFIend
; n
++) {
1891 PrintAndLogEx(INFO
, "---->SFI[%02x] %d", SFI
, n
);
1893 res
= EMVReadRecord(channel
, true, SFI
, n
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1895 PrintAndLogEx(ERR
, "SFI[%02x]. APDU error %4x", SFI
, sw
);
1899 // Build Input list for Offline Data Authentication
1900 // EMV 4.3 book3 10.3, page 96
1901 if (SFIoffline
> 0) {
1903 const unsigned char *abuf
= buf
;
1904 size_t elmlen
= len
;
1906 if (tlv_parse_tl(&abuf
, &elmlen
, &e
)) {
1907 memcpy(&ODAiList
[ODAiListLen
], &buf
[len
- elmlen
], elmlen
);
1908 ODAiListLen
+= elmlen
;
1910 PrintAndLogEx(WARNING
, "Error SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI
);
1913 memcpy(&ODAiList
[ODAiListLen
], buf
, len
);
1925 // copy Input list for Offline Data Authentication
1927 struct tlvdb
*oda
= tlvdb_fixed(0x21, ODAiListLen
, ODAiList
); // not a standard tag
1928 tlvdb_add(tlvRoot
, oda
);
1929 PrintAndLogEx(NORMAL
, "* Input list for Offline Data Authentication added to TLV. len=%d \n", ODAiListLen
);
1932 // getting certificates
1933 if (tlvdb_get(tlvRoot
, 0x90, NULL
)) {
1934 PrintAndLogEx(INFO
, "-->Recovering certificates.");
1935 PKISetStrictExecution(false);
1937 struct emv_pk
*pk
= get_ca_pk(tlvRoot
);
1939 PrintAndLogEx(ERR
, "CA Public Key not found. Exit.");
1943 struct emv_pk
*issuer_pk
= emv_pki_recover_issuer_cert(pk
, tlvRoot
);
1946 PrintAndLogEx(WARNING
, "WARNING: Issuer certificate not found. Exit.");
1951 memcpy(RID
, sprint_hex(issuer_pk
->rid
, 5), 14);
1952 PrintAndLogEx(SUCCESS
, "Issuer Public Key recovered. RID %s IDX %02hhx CSN %s",
1955 sprint_hex(issuer_pk
->serial
, 3)
1958 const struct tlv
*sda_tlv
= tlvdb_get(tlvRoot
, 0x21, NULL
);
1959 struct emv_pk
*icc_pk
= emv_pki_recover_icc_cert(issuer_pk
, tlvRoot
, sda_tlv
);
1962 emv_pk_free(issuer_pk
);
1963 PrintAndLogEx(WARNING
, "WARNING: ICC certificate not found. Exit.");
1967 memcpy(RID
, sprint_hex(icc_pk
->rid
, 5), 14);
1968 PrintAndLogEx(SUCCESS
, "ICC Public Key recovered. RID %s IDX %02hhx CSN %s\n",
1971 sprint_hex(icc_pk
->serial
, 3)
1974 PrintAndLogEx(INFO
, "ICC Public Key modulus: %s\n", sprint_hex_inrow(icc_pk
->modulus
, icc_pk
->mlen
));
1976 // icc_pk->exp, icc_pk->elen
1977 // icc_pk->modulus, icc_pk->mlen
1978 if (icc_pk
->elen
> 0 && icc_pk
->mlen
> 0) {
1979 if (emv_rocacheck(icc_pk
->modulus
, icc_pk
->mlen
, false)) {
1980 PrintAndLogEx(INFO
, "ICC Public Key is subject to ROCA vulnerability (it is NOT secure).");
1982 PrintAndLogEx(INFO
, "ICC Public Key is not subject to ROCA vulnerability (it is secure)");
1986 PKISetStrictExecution(true);
1992 tlvdb_free(tlvRoot
);
1994 DropFieldEx( channel
);
1998 int CmdHelp(const char *Cmd
);
2000 static command_t CommandTable
[] = {
2001 {"help", CmdHelp
, 1, "This help"},
2002 {"exec", CmdEMVExec
, 1, "Executes EMV contactless transaction."},
2003 {"pse", CmdEMVPPSE
, 1, "Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory."},
2004 {"search", CmdEMVSearch
, 1, "Try to select all applets from applets list and print installed applets."},
2005 {"select", CmdEMVSelect
, 1, "Select applet."},
2006 {"gpo", CmdEMVGPO
, 1, "Execute GetProcessingOptions."},
2007 {"readrec", CmdEMVReadRecord
, 1, "Read files from card."},
2008 {"genac", CmdEMVAC
, 1, "Generate ApplicationCryptogram."},
2009 {"challenge", CmdEMVGenerateChallenge
, 1, "Generate challenge."},
2010 {"intauth", CmdEMVInternalAuthenticate
, 1, "Internal authentication."},
2011 {"scan", CmdEMVScan
, 1, "Scan EMV card and save it contents to json file for emulator."},
2012 {"test", CmdEMVTest
, 1, "Crypto logic test."},
2013 {"roca", CmdEMVRoca
, 1, "Extract public keys and run ROCA test"},
2014 {NULL
, NULL
, 0, NULL
}
2017 int CmdEMV(const char *Cmd
) {
2018 CmdsParse(CommandTable
, Cmd
);
2022 int CmdHelp(const char *Cmd
) {
2023 CmdsHelp(CommandTable
);