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 //-----------------------------------------------------------------------------
13 #include "test/cryptotest.h"
14 #include "cliparser/cliparser.h"
17 bool HexToBuffer(const char *errormsg
, const char *hexvalue
, uint8_t * buffer
, size_t maxbufferlen
, size_t *bufferlen
) {
20 switch(param_gethex_to_eol(hexvalue
, 0, buffer
, maxbufferlen
, &buflen
)) {
22 PrintAndLog("%s Invalid HEX value.", errormsg
);
25 PrintAndLog("%s Hex value too large.", errormsg
);
28 PrintAndLog("%s Hex value must have even number of digits.", errormsg
);
32 if (buflen
> maxbufferlen
) {
33 PrintAndLog("%s HEX length (%d) more than %d", errormsg
, *bufferlen
, maxbufferlen
);
42 #define TLV_ADD(tag, value)( tlvdb_change_or_add_node(tlvRoot, tag, sizeof(value) - 1, (const unsigned char *)value) )
43 void ParamLoadDefaults(struct tlvdb
*tlvRoot
) {
44 //9F02:(Amount, authorized (Numeric)) len:6
45 TLV_ADD(0x9F02, "\x00\x00\x00\x00\x01\x00");
46 //9F1A:(Terminal Country Code) len:2
47 TLV_ADD(0x9F1A, "ru");
48 //5F2A:(Transaction Currency Code) len:2
49 // USD 840, EUR 978, RUR 810, RUB 643, RUR 810(old), UAH 980, AZN 031, n/a 999
50 TLV_ADD(0x5F2A, "\x09\x80");
51 //9A:(Transaction Date) len:3
52 TLV_ADD(0x9A, "\x00\x00\x00");
53 //9C:(Transaction Type) len:1 | 00 => Goods and service #01 => Cash
54 TLV_ADD(0x9C, "\x00");
55 // 9F37 Unpredictable Number len:4
56 TLV_ADD(0x9F37, "\x01\x02\x03\x04");
57 // 9F6A Unpredictable Number (MSD for UDOL) len:4
58 TLV_ADD(0x9F6A, "\x01\x02\x03\x04");
59 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
60 TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC
63 bool ParamLoadFromJson(struct tlvdb
*tlv
) {
68 PrintAndLog("ERROR load params: tlv tree is NULL.");
72 // current path + file name
73 const char *relfname
= "emv/defparams.json";
74 char fname
[strlen(get_my_executable_directory()) + strlen(relfname
) + 1];
75 strcpy(fname
, get_my_executable_directory());
76 strcat(fname
, relfname
);
78 root
= json_load_file(fname
, 0, &error
);
80 PrintAndLog("Load params: json error on line %d: %s", error
.line
, error
.text
);
84 if (!json_is_array(root
)) {
85 PrintAndLog("Load params: Invalid json format. root must be array.");
89 PrintAndLog("Load params: json OK");
91 for(int i
= 0; i
< json_array_size(root
); i
++) {
92 json_t
*data
, *jtype
, *jlength
, *jvalue
;
94 data
= json_array_get(root
, i
);
95 if(!json_is_object(data
))
97 PrintAndLog("Load params: data [%d] is not an object", i
+ 1);
102 jtype
= json_object_get(data
, "type");
103 if(!json_is_string(jtype
))
105 PrintAndLog("Load params: data [%d] type is not a string", i
+ 1);
109 const char *tlvType
= json_string_value(jtype
);
111 jvalue
= json_object_get(data
, "value");
112 if(!json_is_string(jvalue
))
114 PrintAndLog("Load params: data [%d] value is not a string", i
+ 1);
118 const char *tlvValue
= json_string_value(jvalue
);
120 jlength
= json_object_get(data
, "length");
121 if(!json_is_number(jlength
))
123 PrintAndLog("Load params: data [%d] length is not a number", i
+ 1);
128 int tlvLength
= json_integer_value(jlength
);
129 if (tlvLength
> 250) {
130 PrintAndLog("Load params: data [%d] length more than 250", i
+ 1);
135 PrintAndLog("TLV param: %s[%d]=%s", tlvType
, tlvLength
, tlvValue
);
136 uint8_t buf
[251] = {0};
139 // here max length must be 4, but now tlv_tag_t is 2-byte var. so let it be 2 by now... TODO: needs refactoring tlv_tag_t...
140 if (!HexToBuffer("TLV Error type:", tlvType
, buf
, 2, &buflen
)) {
145 for (int i
= 0; i
< buflen
; i
++) {
146 tag
= (tag
<< 8) + buf
[i
];
149 if (!HexToBuffer("TLV Error value:", tlvValue
, buf
, sizeof(buf
) - 1, &buflen
)) {
154 if (buflen
!= tlvLength
) {
155 PrintAndLog("Load params: data [%d] length of HEX must(%d) be identical to length in TLV param(%d)", i
+ 1, buflen
, tlvLength
);
160 tlvdb_change_or_add_node(tlv
, tag
, tlvLength
, (const unsigned char *)buf
);
168 int CmdHFEMVSelect(const char *cmd
) {
169 uint8_t data
[APDU_AID_LEN
] = {0};
172 CLIParserInit("hf emv select",
173 "Executes select applet command",
174 "Usage:\n\thf emv select -s a00000000101 -> select card, select applet\n\thf emv select -st a00000000101 -> select card, select applet, show result in TLV\n");
178 arg_lit0("sS", "select", "activate field and select card"),
179 arg_lit0("kK", "keep", "keep field for next command"),
180 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
181 arg_lit0("tT", "tlv", "TLV decode results"),
182 arg_strx0(NULL
, NULL
, "<HEX applet AID>", NULL
),
185 CLIExecWithReturn(cmd
, argtable
, true);
187 bool activateField
= arg_get_lit(1);
188 bool leaveSignalON
= arg_get_lit(2);
189 bool APDULogging
= arg_get_lit(3);
190 bool decodeTLV
= arg_get_lit(4);
191 CLIGetStrWithReturn(5, data
, &datalen
);
194 SetAPDULogging(APDULogging
);
197 uint8_t buf
[APDU_RES_LEN
] = {0};
200 int res
= EMVSelect(activateField
, leaveSignalON
, data
, datalen
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
203 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
209 TLVPrintFromBuffer(buf
, len
);
214 int CmdHFEMVSearch(const char *cmd
) {
216 CLIParserInit("hf emv search",
217 "Tries to select all applets from applet list:\n",
218 "Usage:\n\thf emv search -s -> select card and search\n\thf emv search -st -> select card, search and show result in TLV\n");
222 arg_lit0("sS", "select", "activate field and select card"),
223 arg_lit0("kK", "keep", "keep field ON for next command"),
224 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
225 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
228 CLIExecWithReturn(cmd
, argtable
, true);
230 bool activateField
= arg_get_lit(1);
231 bool leaveSignalON
= arg_get_lit(2);
232 bool APDULogging
= arg_get_lit(3);
233 bool decodeTLV
= arg_get_lit(4);
236 SetAPDULogging(APDULogging
);
238 struct tlvdb
*t
= NULL
;
239 const char *al
= "Applets list";
240 t
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
);
242 if (EMVSearch(activateField
, leaveSignalON
, decodeTLV
, t
)) {
247 PrintAndLog("Search completed.");
251 TLVPrintAIDlistFromSelectTLV(t
);
259 int CmdHFEMVPPSE(const char *cmd
) {
261 CLIParserInit("hf emv pse",
262 "Executes PSE/PPSE select command. It returns list of applet on the card:\n",
263 "Usage:\n\thf emv pse -s1 -> select, get pse\n\thf emv pse -st2 -> select, get ppse, show result in TLV\n");
267 arg_lit0("sS", "select", "activate field and select card"),
268 arg_lit0("kK", "keep", "keep field ON for next command"),
269 arg_lit0("1", "pse", "pse (1PAY.SYS.DDF01) mode"),
270 arg_lit0("2", "ppse", "ppse (2PAY.SYS.DDF01) mode (default mode)"),
271 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
272 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
275 CLIExecWithReturn(cmd
, argtable
, true);
277 bool activateField
= arg_get_lit(1);
278 bool leaveSignalON
= arg_get_lit(2);
284 bool APDULogging
= arg_get_lit(5);
285 bool decodeTLV
= arg_get_lit(6);
288 SetAPDULogging(APDULogging
);
291 uint8_t buf
[APDU_RES_LEN
] = {0};
294 int res
= EMVSelectPSE(activateField
, leaveSignalON
, PSENum
, buf
, sizeof(buf
), &len
, &sw
);
297 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
304 TLVPrintFromBuffer(buf
, len
);
309 int CmdHFEMVGPO(const char *cmd
) {
310 uint8_t data
[APDU_RES_LEN
] = {0};
313 CLIParserInit("hf emv gpo",
314 "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.",
315 "Usage:\n\thf emv gpo -k -> execute GPO\n"
316 "\thf emv gpo -t 01020304 -> execute GPO with 4-byte PDOL data, show result in TLV\n"
317 "\thf emv gpo -pmt 9F 37 04 -> load params from file, make PDOL data from PDOL, execute GPO with PDOL, show result in TLV\n");
321 arg_lit0("kK", "keep", "keep field ON for next command"),
322 arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for PDOLdata making from PDOL and parameters"),
323 arg_lit0("mM", "make", "make PDOLdata from PDOL (tag 9F38) and parameters (by default uses default parameters)"),
324 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
325 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
326 arg_strx0(NULL
, NULL
, "<HEX PDOLdata/PDOL>", NULL
),
329 CLIExecWithReturn(cmd
, argtable
, true);
331 bool leaveSignalON
= arg_get_lit(1);
332 bool paramsLoadFromFile
= arg_get_lit(2);
333 bool dataMakeFromPDOL
= arg_get_lit(3);
334 bool APDULogging
= arg_get_lit(4);
335 bool decodeTLV
= arg_get_lit(5);
336 CLIGetStrWithReturn(6, data
, &datalen
);
339 SetAPDULogging(APDULogging
);
342 const char *alr
= "Root terminal TLV tree";
343 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
346 struct tlv
*pdol_data_tlv
= NULL
;
347 struct tlv data_tlv
= {
350 .value
= (uint8_t *)data
,
352 if (dataMakeFromPDOL
) {
353 ParamLoadDefaults(tlvRoot
);
355 if (paramsLoadFromFile
) {
356 PrintAndLog("Params loading from file...");
357 ParamLoadFromJson(tlvRoot
);
360 pdol_data_tlv
= dol_process((const struct tlv
*)tlvdb_external(0x9f38, datalen
, data
), tlvRoot
, 0x83);
362 PrintAndLog("ERROR: can't create PDOL TLV.");
367 if (paramsLoadFromFile
) {
368 PrintAndLog("WARNING: don't need to load parameters. Sending plain PDOL data...");
370 pdol_data_tlv
= &data_tlv
;
373 size_t pdol_data_tlv_data_len
= 0;
374 unsigned char *pdol_data_tlv_data
= tlv_encode(pdol_data_tlv
, &pdol_data_tlv_data_len
);
375 if (!pdol_data_tlv_data
) {
376 PrintAndLog("ERROR: can't create PDOL data.");
380 PrintAndLog("PDOL data[%d]: %s", pdol_data_tlv_data_len
, sprint_hex(pdol_data_tlv_data
, pdol_data_tlv_data_len
));
383 uint8_t buf
[APDU_RES_LEN
] = {0};
386 int res
= EMVGPO(leaveSignalON
, pdol_data_tlv_data
, pdol_data_tlv_data_len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
388 if (pdol_data_tlv
!= &data_tlv
)
393 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
399 TLVPrintFromBuffer(buf
, len
);
404 int CmdHFEMVReadRecord(const char *cmd
) {
405 uint8_t data
[APDU_RES_LEN
] = {0};
408 CLIParserInit("hf emv readrec",
409 "Executes Read Record command. It returns data in TLV format.\nNeeds a bank applet to be selected and sometimes needs GPO to be executed.",
410 "Usage:\n\thf emv readrec -k 0101 -> read file SFI=01, SFIrec=01\n\thf emv readrec -kt 0201-> read file 0201 and show result in TLV\n");
414 arg_lit0("kK", "keep", "keep field ON for next command"),
415 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
416 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
417 arg_strx1(NULL
, NULL
, "<SFI 1byte HEX><SFIrec 1byte HEX>", NULL
),
420 CLIExecWithReturn(cmd
, argtable
, true);
422 bool leaveSignalON
= arg_get_lit(1);
423 bool APDULogging
= arg_get_lit(2);
424 bool decodeTLV
= arg_get_lit(3);
425 CLIGetStrWithReturn(4, data
, &datalen
);
429 PrintAndLog("ERROR: Command needs to have 2 bytes of data");
433 SetAPDULogging(APDULogging
);
436 uint8_t buf
[APDU_RES_LEN
] = {0};
439 int res
= EMVReadRecord(leaveSignalON
, data
[0], data
[1], buf
, sizeof(buf
), &len
, &sw
, NULL
);
442 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
449 TLVPrintFromBuffer(buf
, len
);
454 int CmdHFEMVAC(const char *cmd
) {
455 uint8_t data
[APDU_RES_LEN
] = {0};
458 CLIParserInit("hf emv genac",
459 "Generate Application Cryptogram command. It returns data in TLV format .\nNeeds a EMV applet to be selected and GPO to be executed.",
460 "Usage:\n\thf emv genac -k 0102 -> generate AC with 2-byte CDOLdata and keep field ON after command\n"
461 "\thf emv genac -t 01020304 -> generate AC with 4-byte CDOL data, show result in TLV\n"
462 "\thf emv genac -Daac 01020304 -> generate AC with 4-byte CDOL data and terminal decision 'declined'\n"
463 "\thf emv genac -pmt 9F 37 04 -> load params from file, make CDOL data from CDOL, generate AC with CDOL, show result in TLV");
467 arg_lit0("kK", "keep", "keep field ON for next command"),
468 arg_lit0("cC", "cda", "executes CDA transaction. Needs to get SDAD in results."),
469 arg_str0("dD", "decision", "<aac|tc|arqc>", "Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested"),
470 arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for CDOLdata making from CDOL and parameters"),
471 arg_lit0("mM", "make", "make CDOLdata from CDOL (tag 8C and 8D) and parameters (by default uses default parameters)"),
472 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
473 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
474 arg_strx1(NULL
, NULL
, "<HEX CDOLdata/CDOL>", NULL
),
477 CLIExecWithReturn(cmd
, argtable
, false);
479 bool leaveSignalON
= arg_get_lit(1);
480 bool trTypeCDA
= arg_get_lit(2);
481 uint8_t termDecision
= 0xff;
482 if (arg_get_str_len(3)) {
483 if (!strncmp(arg_get_str(3)->sval
[0], "aac", 4))
484 termDecision
= EMVAC_AAC
;
485 if (!strncmp(arg_get_str(3)->sval
[0], "tc", 4))
486 termDecision
= EMVAC_TC
;
487 if (!strncmp(arg_get_str(3)->sval
[0], "arqc", 4))
488 termDecision
= EMVAC_ARQC
;
490 if (termDecision
== 0xff) {
491 PrintAndLog("ERROR: can't find terminal decision '%s'", arg_get_str(3)->sval
[0]);
495 termDecision
= EMVAC_TC
;
498 termDecision
= termDecision
| EMVAC_CDAREQ
;
499 bool paramsLoadFromFile
= arg_get_lit(4);
500 bool dataMakeFromCDOL
= arg_get_lit(5);
501 bool APDULogging
= arg_get_lit(6);
502 bool decodeTLV
= arg_get_lit(7);
503 CLIGetStrWithReturn(8, data
, &datalen
);
506 SetAPDULogging(APDULogging
);
509 const char *alr
= "Root terminal TLV tree";
510 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
513 struct tlv
*cdol_data_tlv
= NULL
;
514 struct tlv data_tlv
= {
517 .value
= (uint8_t *)data
,
520 if (dataMakeFromCDOL
) {
521 ParamLoadDefaults(tlvRoot
);
523 if (paramsLoadFromFile
) {
524 PrintAndLog("Params loading from file...");
525 ParamLoadFromJson(tlvRoot
);
528 cdol_data_tlv
= dol_process((const struct tlv
*)tlvdb_external(0x8c, datalen
, data
), tlvRoot
, 0x01); // 0x01 - dummy tag
530 PrintAndLog("ERROR: can't create CDOL TLV.");
535 if (paramsLoadFromFile
) {
536 PrintAndLog("WARNING: don't need to load parameters. Sending plain CDOL data...");
538 cdol_data_tlv
= &data_tlv
;
541 PrintAndLog("CDOL data[%d]: %s", cdol_data_tlv
->len
, sprint_hex(cdol_data_tlv
->value
, cdol_data_tlv
->len
));
544 uint8_t buf
[APDU_RES_LEN
] = {0};
547 int res
= EMVAC(leaveSignalON
, termDecision
, (uint8_t *)cdol_data_tlv
->value
, cdol_data_tlv
->len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
549 if (cdol_data_tlv
!= &data_tlv
)
554 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
560 TLVPrintFromBuffer(buf
, len
);
565 int CmdHFEMVGenerateChallenge(const char *cmd
) {
567 CLIParserInit("hf emv challenge",
568 "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.",
569 "Usage:\n\thf emv challenge -> get challenge\n\thf emv challenge -k -> get challenge, keep fileld ON\n");
573 arg_lit0("kK", "keep", "keep field ON for next command"),
574 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
577 CLIExecWithReturn(cmd
, argtable
, true);
579 bool leaveSignalON
= arg_get_lit(1);
580 bool APDULogging
= arg_get_lit(2);
583 SetAPDULogging(APDULogging
);
586 uint8_t buf
[APDU_RES_LEN
] = {0};
589 int res
= EMVGenerateChallenge(leaveSignalON
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
592 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
597 PrintAndLog("Challenge: %s", sprint_hex(buf
, len
));
599 if (len
!= 4 && len
!= 8)
600 PrintAndLog("WARNING: length of challenge must be 4 or 8, but it %d", len
);
605 int CmdHFEMVInternalAuthenticate(const char *cmd
) {
606 uint8_t data
[APDU_RES_LEN
] = {0};
609 CLIParserInit("hf emv intauth",
610 "Generate Internal Authenticate command. Usually needs 4-byte random number. It returns data in TLV format .\nNeeds a EMV applet to be selected and GPO to be executed.",
611 "Usage:\n\thf emv intauth -k 01020304 -> execute Internal Authenticate with 4-byte DDOLdata and keep field ON after command\n"
612 "\thf emv intauth -t 01020304 -> execute Internal Authenticate with 4-byte DDOL data, show result in TLV\n"
613 "\thf emv intauth -pmt 9F 37 04 -> load params from file, make DDOL data from DDOL, Internal Authenticate with DDOL, show result in TLV");
617 arg_lit0("kK", "keep", "keep field ON for next command"),
618 arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for DDOLdata making from DDOL and parameters"),
619 arg_lit0("mM", "make", "make DDOLdata from DDOL (tag 9F49) and parameters (by default uses default parameters)"),
620 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
621 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
622 arg_strx1(NULL
, NULL
, "<HEX DDOLdata/DDOL>", NULL
),
625 CLIExecWithReturn(cmd
, argtable
, false);
627 bool leaveSignalON
= arg_get_lit(1);
628 bool paramsLoadFromFile
= arg_get_lit(2);
629 bool dataMakeFromDDOL
= arg_get_lit(3);
630 bool APDULogging
= arg_get_lit(4);
631 bool decodeTLV
= arg_get_lit(5);
632 CLIGetStrWithReturn(6, data
, &datalen
);
635 SetAPDULogging(APDULogging
);
638 const char *alr
= "Root terminal TLV tree";
639 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
642 struct tlv
*ddol_data_tlv
= NULL
;
643 struct tlv data_tlv
= {
646 .value
= (uint8_t *)data
,
649 if (dataMakeFromDDOL
) {
650 ParamLoadDefaults(tlvRoot
);
652 if (paramsLoadFromFile
) {
653 PrintAndLog("Params loading from file...");
654 ParamLoadFromJson(tlvRoot
);
657 ddol_data_tlv
= dol_process((const struct tlv
*)tlvdb_external(0x9f49, datalen
, data
), tlvRoot
, 0x01); // 0x01 - dummy tag
659 PrintAndLog("ERROR: can't create DDOL TLV.");
664 if (paramsLoadFromFile
) {
665 PrintAndLog("WARNING: don't need to load parameters. Sending plain DDOL data...");
667 ddol_data_tlv
= &data_tlv
;
670 PrintAndLog("DDOL data[%d]: %s", ddol_data_tlv
->len
, sprint_hex(ddol_data_tlv
->value
, ddol_data_tlv
->len
));
673 uint8_t buf
[APDU_RES_LEN
] = {0};
676 int res
= EMVInternalAuthenticate(leaveSignalON
, data
, datalen
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
678 if (ddol_data_tlv
!= &data_tlv
)
683 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
689 TLVPrintFromBuffer(buf
, len
);
694 #define dreturn(n) {free(pdol_data_tlv);tlvdb_free(tlvSelect);tlvdb_free(tlvRoot);DropField();return n;}
696 int CmdHFEMVExec(const char *cmd
) {
697 uint8_t buf
[APDU_RES_LEN
] = {0};
700 uint8_t AID
[APDU_AID_LEN
] = {0};
702 uint8_t ODAiList
[4096];
703 size_t ODAiListLen
= 0;
707 struct tlvdb
*tlvSelect
= NULL
;
708 struct tlvdb
*tlvRoot
= NULL
;
709 struct tlv
*pdol_data_tlv
= NULL
;
711 CLIParserInit("hf emv exec",
712 "Executes EMV contactless transaction",
713 "Usage:\n\thf emv exec -sat -> select card, execute MSD transaction, show APDU and TLV\n"
714 "\thf emv exec -satc -> select card, execute CDA transaction, show APDU and TLV\n");
718 arg_lit0("sS", "select", "activate field and select card."),
719 arg_lit0("aA", "apdu", "show APDU reqests and responses."),
720 arg_lit0("tT", "tlv", "TLV decode results."),
721 arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."),
722 arg_lit0("fF", "forceaid", "Force search AID. Search AID instead of execute PPSE."),
723 arg_rem("By default:", "Transaction type - MSD"),
724 arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
725 arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
726 arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standart behavior."),
727 arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."),
730 CLIExecWithReturn(cmd
, argtable
, true);
732 bool activateField
= arg_get_lit(1);
733 bool showAPDU
= arg_get_lit(2);
734 bool decodeTLV
= arg_get_lit(3);
735 bool paramLoadJSON
= arg_get_lit(4);
736 bool forceSearch
= arg_get_lit(5);
738 enum TransactionType TrType
= TT_MSD
;
740 TrType
= TT_QVSDCMCHIP
;
746 bool GenACGPO
= arg_get_lit(9);
749 SetAPDULogging(showAPDU
);
751 // init applets list tree
752 const char *al
= "Applets list";
753 tlvSelect
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
);
755 // Application Selection
756 // https://www.openscdp.org/scripts/tutorial/emv/applicationselection.html
759 PrintAndLog("\n* PPSE.");
760 SetAPDULogging(showAPDU
);
761 res
= EMVSearchPSE(activateField
, true, decodeTLV
, tlvSelect
);
763 // check PPSE and select application id
765 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
766 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
);
772 PrintAndLog("\n* Search AID in list.");
773 SetAPDULogging(false);
774 if (EMVSearch(activateField
, true, decodeTLV
, tlvSelect
)) {
778 // check search and select application id
779 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
780 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
);
784 const char *alr
= "Root terminal TLV tree";
785 tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
787 // check if we found EMV application on card
789 PrintAndLog("Can't select AID. EMV AID not found");
794 PrintAndLog("\n* Selecting AID:%s", sprint_hex_inrow(AID
, AIDlen
));
795 SetAPDULogging(showAPDU
);
796 res
= EMVSelect(false, true, AID
, AIDlen
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
799 PrintAndLog("Can't select AID (%d). Exit...", res
);
804 TLVPrintFromBuffer(buf
, len
);
805 PrintAndLog("* Selected.");
807 PrintAndLog("\n* Init transaction parameters.");
809 ParamLoadDefaults(tlvRoot
);
812 PrintAndLog("* * Transaction parameters loading from JSON...");
813 ParamLoadFromJson(tlvRoot
);
816 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
817 char *qVSDC
= "\x26\x00\x00\x00";
819 qVSDC
= "\x26\x80\x00\x00";
823 TLV_ADD(0x9F66, "\x86\x00\x00\x00"); // MSD
825 // not standard for contactless. just for test.
827 TLV_ADD(0x9F66, "\x46\x00\x00\x00"); // VSDC
830 TLV_ADD(0x9F66, qVSDC
); // qVSDC
833 TLV_ADD(0x9F66, qVSDC
); // qVSDC (VISA CDA not enabled)
839 TLVPrintFromTLV(tlvRoot
); // TODO delete!!!
841 PrintAndLog("\n* Calc PDOL.");
842 pdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x9f38, NULL
), tlvRoot
, 0x83);
844 PrintAndLog("ERROR: can't create PDOL TLV.");
848 size_t pdol_data_tlv_data_len
;
849 unsigned char *pdol_data_tlv_data
= tlv_encode(pdol_data_tlv
, &pdol_data_tlv_data_len
);
850 if (!pdol_data_tlv_data
) {
851 PrintAndLog("ERROR: can't create PDOL data.");
854 PrintAndLog("PDOL data[%d]: %s", pdol_data_tlv_data_len
, sprint_hex(pdol_data_tlv_data
, pdol_data_tlv_data_len
));
856 PrintAndLog("\n* GPO.");
857 res
= EMVGPO(true, pdol_data_tlv_data
, pdol_data_tlv_data_len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
859 free(pdol_data_tlv_data
);
860 //free(pdol_data_tlv); --- free on exit.
863 PrintAndLog("GPO error(%d): %4x. Exit...", res
, sw
);
867 // process response template format 1 [id:80 2b AIP + x4b AFL] and format 2 [id:77 TLV]
868 if (buf
[0] == 0x80) {
870 PrintAndLog("GPO response format1:");
871 TLVPrintFromBuffer(buf
, len
);
874 if (len
< 4 || (len
- 4) % 4) {
875 PrintAndLog("ERROR: GPO response format1 parsing error. length=%d", len
);
878 struct tlvdb
* f1AIP
= tlvdb_fixed(0x82, 2, buf
+ 2);
879 tlvdb_add(tlvRoot
, f1AIP
);
881 PrintAndLog("\n* * Decode response format 1 (0x80) AIP and AFL:");
882 TLVPrintFromTLV(f1AIP
);
886 struct tlvdb
* f1AFL
= tlvdb_fixed(0x94, len
- 4, buf
+ 2 + 2);
887 tlvdb_add(tlvRoot
, f1AFL
);
889 TLVPrintFromTLV(f1AFL
);
893 TLVPrintFromBuffer(buf
, len
);
896 // extract PAN from track2
898 const struct tlv
*track2
= tlvdb_get(tlvRoot
, 0x57, NULL
);
899 if (!tlvdb_get(tlvRoot
, 0x5a, NULL
) && track2
&& track2
->len
>= 8) {
900 struct tlvdb
*pan
= GetPANFromTrack2(track2
);
902 tlvdb_add(tlvRoot
, pan
);
904 const struct tlv
*pantlv
= tlvdb_get(tlvRoot
, 0x5a, NULL
);
905 PrintAndLog("\n* * Extracted PAN from track2: %s", sprint_hex(pantlv
->value
, pantlv
->len
));
907 PrintAndLog("\n* * WARNING: Can't extract PAN from track2.");
912 PrintAndLog("\n* Read records from AFL.");
913 const struct tlv
*AFL
= tlvdb_get(tlvRoot
, 0x94, NULL
);
914 if (!AFL
|| !AFL
->len
) {
915 PrintAndLog("WARNING: AFL not found.");
918 while(AFL
&& AFL
->len
) {
920 PrintAndLog("ERROR: Wrong AFL length: %d", AFL
->len
);
924 for (int i
= 0; i
< AFL
->len
/ 4; i
++) {
925 uint8_t SFI
= AFL
->value
[i
* 4 + 0] >> 3;
926 uint8_t SFIstart
= AFL
->value
[i
* 4 + 1];
927 uint8_t SFIend
= AFL
->value
[i
* 4 + 2];
928 uint8_t SFIoffline
= AFL
->value
[i
* 4 + 3];
930 PrintAndLog("* * SFI[%02x] start:%02x end:%02x offline:%02x", SFI
, SFIstart
, SFIend
, SFIoffline
);
931 if (SFI
== 0 || SFI
== 31 || SFIstart
== 0 || SFIstart
> SFIend
) {
932 PrintAndLog("SFI ERROR! Skipped...");
936 for(int n
= SFIstart
; n
<= SFIend
; n
++) {
937 PrintAndLog("* * * SFI[%02x] %d", SFI
, n
);
939 res
= EMVReadRecord(true, SFI
, n
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
941 PrintAndLog("ERROR SFI[%02x]. APDU error %4x", SFI
, sw
);
946 TLVPrintFromBuffer(buf
, len
);
950 // Build Input list for Offline Data Authentication
951 // EMV 4.3 book3 10.3, page 96
954 const unsigned char *abuf
= buf
;
957 if (tlv_parse_tl(&abuf
, &elmlen
, &e
)) {
958 memcpy(&ODAiList
[ODAiListLen
], &buf
[len
- elmlen
], elmlen
);
959 ODAiListLen
+= elmlen
;
961 PrintAndLog("ERROR SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI
);
964 memcpy(&ODAiList
[ODAiListLen
], buf
, len
);
974 // copy Input list for Offline Data Authentication
976 struct tlvdb
*oda
= tlvdb_fixed(0x21, ODAiListLen
, ODAiList
); // not a standard tag
977 tlvdb_add(tlvRoot
, oda
);
978 PrintAndLog("* Input list for Offline Data Authentication added to TLV. len=%d \n", ODAiListLen
);
982 const struct tlv
*AIPtlv
= tlvdb_get(tlvRoot
, 0x82, NULL
);
983 uint16_t AIP
= AIPtlv
->value
[0] + AIPtlv
->value
[1] * 0x100;
984 PrintAndLog("* * AIP=%04x", AIP
);
988 PrintAndLog("\n* SDA");
994 PrintAndLog("\n* DDA");
995 trDDA(decodeTLV
, tlvRoot
);
1001 if (TrType
== TT_QVSDCMCHIP
|| TrType
== TT_CDA
){
1002 // 9F26: Application Cryptogram
1003 const struct tlv
*AC
= tlvdb_get(tlvRoot
, 0x9F26, NULL
);
1005 PrintAndLog("\n--> qVSDC transaction.");
1006 PrintAndLog("* AC path");
1008 // 9F36: Application Transaction Counter (ATC)
1009 const struct tlv
*ATC
= tlvdb_get(tlvRoot
, 0x9F36, NULL
);
1012 // 9F10: Issuer Application Data - optional
1013 const struct tlv
*IAD
= tlvdb_get(tlvRoot
, 0x9F10, NULL
);
1016 PrintAndLog("ATC: %s", sprint_hex(ATC
->value
, ATC
->len
));
1017 PrintAndLog("AC: %s", sprint_hex(AC
->value
, AC
->len
));
1019 PrintAndLog("IAD: %s", sprint_hex(IAD
->value
, IAD
->len
));
1021 if (IAD
->len
>= IAD
->value
[0] + 1) {
1022 PrintAndLog("\tKey index: 0x%02x", IAD
->value
[1]);
1023 PrintAndLog("\tCrypto ver: 0x%02x(%03d)", IAD
->value
[2], IAD
->value
[2]);
1024 PrintAndLog("\tCVR:", sprint_hex(&IAD
->value
[3], IAD
->value
[0] - 2));
1025 struct tlvdb
* cvr
= tlvdb_fixed(0x20, IAD
->value
[0] - 2, &IAD
->value
[3]);
1026 TLVPrintFromTLVLev(cvr
, 1);
1029 PrintAndLog("WARNING: IAD not found.");
1033 PrintAndLog("ERROR AC: Application Transaction Counter (ATC) not found.");
1038 // Mastercard M/CHIP
1039 if (GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
&& (TrType
== TT_QVSDCMCHIP
|| TrType
== TT_CDA
)){
1040 const struct tlv
*CDOL1
= tlvdb_get(tlvRoot
, 0x8c, NULL
);
1041 if (CDOL1
&& GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
) { // and m/chip transaction flag
1042 PrintAndLog("\n--> Mastercard M/Chip transaction.");
1044 PrintAndLog("* * Generate challenge");
1045 res
= EMVGenerateChallenge(true, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1047 PrintAndLog("ERROR GetChallenge. APDU error %4x", sw
);
1051 PrintAndLog("ERROR GetChallenge. Wrong challenge length %d", len
);
1055 // ICC Dynamic Number
1056 struct tlvdb
* ICCDynN
= tlvdb_fixed(0x9f4c, len
, buf
);
1057 tlvdb_add(tlvRoot
, ICCDynN
);
1059 PrintAndLog("\n* * ICC Dynamic Number:");
1060 TLVPrintFromTLV(ICCDynN
);
1063 PrintAndLog("* * Calc CDOL1");
1064 struct tlv
*cdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x8c, NULL
), tlvRoot
, 0x01); // 0x01 - dummy tag
1065 if (!cdol_data_tlv
){
1066 PrintAndLog("ERROR: can't create CDOL1 TLV.");
1069 PrintAndLog("CDOL1 data[%d]: %s", cdol_data_tlv
->len
, sprint_hex(cdol_data_tlv
->value
, cdol_data_tlv
->len
));
1071 PrintAndLog("* * AC1");
1072 // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD
1073 res
= EMVAC(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
);
1076 PrintAndLog("AC1 error(%d): %4x. Exit...", res
, sw
);
1081 TLVPrintFromBuffer(buf
, len
);
1084 PrintAndLog("\n* CDA:");
1085 struct tlvdb
*ac_tlv
= tlvdb_parse_multi(buf
, len
);
1086 res
= trCDA(tlvRoot
, ac_tlv
, pdol_data_tlv
, cdol_data_tlv
);
1088 PrintAndLog("CDA error (%d)", res
);
1091 free(cdol_data_tlv
);
1093 PrintAndLog("\n* M/Chip transaction result:");
1094 // 9F27: Cryptogram Information Data (CID)
1095 const struct tlv
*CID
= tlvdb_get(tlvRoot
, 0x9F27, NULL
);
1097 emv_tag_dump(CID
, stdout
, 0);
1098 PrintAndLog("------------------------------");
1100 switch(CID
->value
[0] & EMVAC_AC_MASK
){
1102 PrintAndLog("Transaction DECLINED.");
1105 PrintAndLog("Transaction approved OFFLINE.");
1108 PrintAndLog("Transaction approved ONLINE.");
1111 PrintAndLog("ERROR: CID transaction code error %2x", CID
->value
[0] & EMVAC_AC_MASK
);
1115 PrintAndLog("ERROR: Wrong CID length %d", CID
->len
);
1118 PrintAndLog("ERROR: CID(9F27) not found.");
1125 if (AIP
& 0x8000 && TrType
== TT_MSD
) {
1126 PrintAndLog("\n--> MSD transaction.");
1128 PrintAndLog("* MSD dCVV path. Check dCVV");
1130 const struct tlv
*track2
= tlvdb_get(tlvRoot
, 0x57, NULL
);
1132 PrintAndLog("Track2: %s", sprint_hex(track2
->value
, track2
->len
));
1134 struct tlvdb
*dCVV
= GetdCVVRawFromTrack2(track2
);
1135 PrintAndLog("dCVV raw data:");
1136 TLVPrintFromTLV(dCVV
);
1138 if (GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
) {
1139 PrintAndLog("\n* Mastercard calculate UDOL");
1142 const struct tlv
*UDOL
= tlvdb_get(tlvRoot
, 0x9F69, NULL
);
1143 // UDOL(9F69) default: 9F6A (Unpredictable number) 4 bytes
1144 const struct tlv defUDOL
= {
1147 .value
= (uint8_t *)"\x9f\x6a\x04",
1150 PrintAndLog("Use default UDOL.");
1152 struct tlv
*udol_data_tlv
= dol_process(UDOL
? UDOL
: &defUDOL
, tlvRoot
, 0x01); // 0x01 - dummy tag
1153 if (!udol_data_tlv
){
1154 PrintAndLog("ERROR: can't create UDOL TLV.");
1158 PrintAndLog("UDOL data[%d]: %s", udol_data_tlv
->len
, sprint_hex(udol_data_tlv
->value
, udol_data_tlv
->len
));
1160 PrintAndLog("\n* Mastercard compute cryptographic checksum(UDOL)");
1162 res
= MSCComputeCryptoChecksum(true, (uint8_t *)udol_data_tlv
->value
, udol_data_tlv
->len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1164 PrintAndLog("ERROR Compute Crypto Checksum. APDU error %4x", sw
);
1165 free(udol_data_tlv
);
1170 TLVPrintFromBuffer(buf
, len
);
1173 free(udol_data_tlv
);
1177 PrintAndLog("ERROR MSD: Track2 data not found.");
1185 free(pdol_data_tlv
);
1186 tlvdb_free(tlvSelect
);
1187 tlvdb_free(tlvRoot
);
1189 PrintAndLog("\n* Transaction completed.");
1194 int UsageCmdHFEMVScan(void) {
1195 PrintAndLog("HELP : Scan EMV card and save it contents to a file. \n");
1196 PrintAndLog(" It executes EMV contactless transaction and saves result to a file which can be used for emulation.\n");
1197 PrintAndLog("Usage: hf emv scan [-a][-t][-v][-c][-x][-g] <file_name>\n");
1198 PrintAndLog(" Options:");
1199 PrintAndLog(" -a : show APDU reqests and responses\n");
1200 PrintAndLog(" -t : TLV decode results\n");
1201 PrintAndLog(" -v : transaction type - qVSDC or M/Chip.\n");
1202 PrintAndLog(" -c : transaction type - qVSDC or M/Chip plus CDA (SDAD generation).\n");
1203 PrintAndLog(" -x : transaction type - VSDC. For test only. Not a standart behavior.\n");
1204 PrintAndLog(" -g : VISA. generate AC from GPO\n");
1205 PrintAndLog("By default : transaction type - MSD.\n");
1206 PrintAndLog("Samples:");
1207 PrintAndLog(" hf emv scan -a -t -> scan MSD transaction mode");
1208 PrintAndLog(" hf emv scan -a -t -c -> scan CDA transaction mode");
1212 int CmdHFEMVScan(const char *cmd
) {
1213 UsageCmdHFEMVScan();
1218 int CmdHFEMVTest(const char *cmd
) {
1219 return ExecuteCryptoTests(true);
1222 int CmdHelp(const char *Cmd
);
1223 static command_t CommandTable
[] = {
1224 {"help", CmdHelp
, 1, "This help"},
1225 {"exec", CmdHFEMVExec
, 0, "Executes EMV contactless transaction."},
1226 {"pse", CmdHFEMVPPSE
, 0, "Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory."},
1227 {"search", CmdHFEMVSearch
, 0, "Try to select all applets from applets list and print installed applets."},
1228 {"select", CmdHFEMVSelect
, 0, "Select applet."},
1229 {"gpo", CmdHFEMVGPO
, 0, "Execute GetProcessingOptions."},
1230 {"readrec", CmdHFEMVReadRecord
, 0, "Read files from card."},
1231 {"genac", CmdHFEMVAC
, 0, "Generate ApplicationCryptogram."},
1232 {"challenge", CmdHFEMVGenerateChallenge
, 0, "Generate challenge."},
1233 {"intauth", CmdHFEMVInternalAuthenticate
, 0, "Internal authentication."},
1234 // {"scan", CmdHFEMVScan, 0, "Scan EMV card and save it contents to json file for emulator."},
1235 {"test", CmdHFEMVTest
, 0, "Crypto logic test."},
1236 {NULL
, NULL
, 0, NULL
}
1239 int CmdHFEMV(const char *Cmd
) {
1240 CmdsParse(CommandTable
, Cmd
);
1244 int CmdHelp(const char *Cmd
) {
1245 CmdsHelp(CommandTable
);