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"
16 int CmdHFEMVSelect(const char *cmd
) {
17 uint8_t data
[APDU_AID_LEN
] = {0};
21 CLIParserInit("hf emv select",
22 "Executes select applet command",
23 "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");
27 arg_lit0("sS", "select", "activate field and select card"),
28 arg_lit0("kK", "keep", "keep field for next command"),
29 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
30 arg_lit0("tT", "tlv", "TLV decode results"),
31 arg_str0(NULL
, NULL
, "<HEX applet AID>", NULL
),
34 CLIExecWithReturn(cmd
, argtable
, true);
36 bool activateField
= arg_get_lit(1);
37 bool leaveSignalON
= arg_get_lit(2);
38 bool APDULogging
= arg_get_lit(3);
39 bool decodeTLV
= arg_get_lit(4);
40 CLIGetStrWithReturn(5, data
, &datalen
);
43 SetAPDULogging(APDULogging
);
46 uint8_t buf
[APDU_RES_LEN
] = {0};
49 int res
= EMVSelect(activateField
, leaveSignalON
, data
, datalen
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
52 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
58 TLVPrintFromBuffer(buf
, len
);
63 int CmdHFEMVSearch(const char *cmd
) {
65 CLIParserInit("hf emv search",
66 "Tries to select all applets from applet list:\n",
67 "Usage:\n\thf emv search -s -> select card and search\n\thf emv search -st -> select card, search and show result in TLV\n");
71 arg_lit0("sS", "select", "activate field and select card"),
72 arg_lit0("kK", "keep", "keep field ON for next command"),
73 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
74 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
77 CLIExecWithReturn(cmd
, argtable
, true);
79 bool activateField
= arg_get_lit(1);
80 bool leaveSignalON
= arg_get_lit(2);
81 bool APDULogging
= arg_get_lit(3);
82 bool decodeTLV
= arg_get_lit(4);
85 SetAPDULogging(APDULogging
);
87 struct tlvdb
*t
= NULL
;
88 const char *al
= "Applets list";
89 t
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
);
91 if (EMVSearch(activateField
, leaveSignalON
, decodeTLV
, t
)) {
96 PrintAndLog("Search completed.");
100 TLVPrintAIDlistFromSelectTLV(t
);
108 int CmdHFEMVPPSE(const char *cmd
) {
110 CLIParserInit("hf emv pse",
111 "Executes PSE/PPSE select command. It returns list of applet on the card:\n",
112 "Usage:\n\thf emv pse -s1 -> select, get pse\n\thf emv pse -st2 -> select, get ppse, show result in TLV\n");
116 arg_lit0("sS", "select", "activate field and select card"),
117 arg_lit0("kK", "keep", "keep field ON for next command"),
118 arg_lit0("1", "pse", "pse (1PAY.SYS.DDF01) mode"),
119 arg_lit0("2", "ppse", "ppse (2PAY.SYS.DDF01) mode (default mode)"),
120 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
121 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
124 CLIExecWithReturn(cmd
, argtable
, true);
126 bool activateField
= arg_get_lit(1);
127 bool leaveSignalON
= arg_get_lit(2);
133 bool APDULogging
= arg_get_lit(5);
134 bool decodeTLV
= arg_get_lit(6);
137 SetAPDULogging(APDULogging
);
140 uint8_t buf
[APDU_RES_LEN
] = {0};
143 int res
= EMVSelectPSE(activateField
, leaveSignalON
, PSENum
, buf
, sizeof(buf
), &len
, &sw
);
146 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
153 TLVPrintFromBuffer(buf
, len
);
158 #define TLV_ADD(tag, value)( tlvdb_add(tlvRoot, tlvdb_fixed(tag, sizeof(value) - 1, (const unsigned char *)value)) )
160 int CmdHFEMVGPO(const char *cmd
) {
161 uint8_t data
[APDU_RES_LEN
] = {0};
164 CLIParserInit("hf emv gpo",
165 "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.",
166 "Usage:\n\thf emv gpo -k -> execute GPO\n"
167 "\thf emv gpo -st 01020304 -> execute GPO with 4-byte PDOL data, show result in TLV\n");
168 // here need to add load params from file and gen pdol
172 arg_lit0("kK", "keep", "keep field ON for next command"),
173 arg_lit0("pP", "params", "load parameters for PDOL making from `emv/defparams.json` file (by default uses default parameters) (NOT WORK!!!)"),
174 arg_lit0("mM", "make", "make PDOLdata from PDOL (tag 9F38) and parameters (NOT WORK!!!)"),
175 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
176 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
177 arg_str0(NULL
, NULL
, "<HEX PDOLdata/PDOL>", NULL
),
180 CLIExecWithReturn(cmd
, argtable
, true);
182 bool leaveSignalON
= arg_get_lit(1);
183 bool paramsLoadFromFile
= arg_get_lit(2);
184 bool dataMakeFromPDOL
= arg_get_lit(3);
185 bool APDULogging
= arg_get_lit(4);
186 bool decodeTLV
= arg_get_lit(5);
187 CLIGetStrWithReturn(6, data
, &datalen
);
190 SetAPDULogging(APDULogging
);
193 const char *alr
= "Root terminal TLV tree";
194 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
197 struct tlv
*pdol_data_tlv
= NULL
;
198 struct tlv data_tlv
= {
201 .value
= (uint8_t *)data
,
203 if (dataMakeFromPDOL
) {
205 PrintAndLog("Make PDOL data not implemented!");
207 //9F02:(Amount, authorized (Numeric)) len:6
208 TLV_ADD(0x9F02, "\x00\x00\x00\x00\x01\x00");
209 //9F1A:(Terminal Country Code) len:2
210 TLV_ADD(0x9F1A, "ru");
211 //5F2A:(Transaction Currency Code) len:2
212 // USD 840, EUR 978, RUR 810, RUB 643, RUR 810(old), UAH 980, AZN 031, n/a 999
213 TLV_ADD(0x5F2A, "\x09\x80");
214 //9A:(Transaction Date) len:3
215 TLV_ADD(0x9A, "\x00\x00\x00");
216 //9C:(Transaction Type) len:1 | 00 => Goods and service #01 => Cash
217 TLV_ADD(0x9C, "\x00");
218 // 9F37 Unpredictable Number len:4
219 TLV_ADD(0x9F37, "\x01\x02\x03\x04");
220 // 9F6A Unpredictable Number (MSD for UDOL) len:4
221 TLV_ADD(0x9F6A, "\x01\x02\x03\x04");
222 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
223 TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC
225 if (paramsLoadFromFile
) {
227 /* pdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x9f38, NULL), tlvRoot, 0x83);
229 PrintAndLog("ERROR: can't create PDOL TLV.");
235 pdol_data_tlv
= &data_tlv
;
238 size_t pdol_data_tlv_data_len
= 0;
239 unsigned char *pdol_data_tlv_data
= tlv_encode(pdol_data_tlv
, &pdol_data_tlv_data_len
);
240 if (!pdol_data_tlv_data
) {
241 PrintAndLog("ERROR: can't create PDOL data.");
245 PrintAndLog("PDOL data[%d]: %s", pdol_data_tlv_data_len
, sprint_hex(pdol_data_tlv_data
, pdol_data_tlv_data_len
));
248 uint8_t buf
[APDU_RES_LEN
] = {0};
251 int res
= EMVGPO(leaveSignalON
, pdol_data_tlv_data
, pdol_data_tlv_data_len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
253 free(pdol_data_tlv_data
);
257 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
263 TLVPrintFromBuffer(buf
, len
);
268 int CmdHFEMVReadRecord(const char *cmd
) {
269 uint8_t data
[APDU_RES_LEN
] = {0};
272 CLIParserInit("hf emv readrec",
273 "Executes Read Record command. It returns data in TLV format.\nNeeds a bank applet to be selected and sometimes needs GPO to be executed.",
274 "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");
278 arg_lit0("kK", "keep", "keep field ON for next command"),
279 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
280 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
281 arg_str1(NULL
, NULL
, "<SFI 1byte HEX><SFIrec 1byte HEX>", NULL
),
284 CLIExecWithReturn(cmd
, argtable
, true);
286 bool leaveSignalON
= arg_get_lit(1);
287 bool APDULogging
= arg_get_lit(2);
288 bool decodeTLV
= arg_get_lit(3);
289 CLIGetStrWithReturn(4, data
, &datalen
);
293 PrintAndLog("ERROR: Command needs to have 2 bytes of data");
297 SetAPDULogging(APDULogging
);
300 uint8_t buf
[APDU_RES_LEN
] = {0};
303 int res
= EMVReadRecord(leaveSignalON
, data
[0], data
[1], buf
, sizeof(buf
), &len
, &sw
, NULL
);
306 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
313 TLVPrintFromBuffer(buf
, len
);
318 int CmdHFEMVAC(const char *cmd
) {
319 uint8_t data
[APDU_RES_LEN
] = {0};
322 CLIParserInit("hf emv genac",
323 "Generate Application Cryptogram command. It returns data in TLV format .\nNeeds a EMV applet to be selected and GPO to be executed.",
324 "Usage:\n\thf emv genac -k 0102 -> generate AC with 2-byte CDOLdata and keep field ON after command\n"
325 "\thf emv genac -t 01020304 -> generate AC with 4-byte CDOL data, show result in TLV\n"
326 "\thf emv genac -Daac 01020304 -> generate AC with 4-byte CDOL data and terminal decision 'declined'\n");
330 arg_lit0("kK", "keep", "keep field ON for next command"),
331 arg_lit0("cC", "cda", "executes CDA transaction. Needs to get SDAD in results."),
332 arg_str0("dD", "decision", "<aac|tc|arqc>", "Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested"),
333 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
334 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
335 arg_str1(NULL
, NULL
, "<HEX CDOLdata>", NULL
),
338 CLIExecWithReturn(cmd
, argtable
, false);
340 bool leaveSignalON
= arg_get_lit(1);
341 bool trTypeCDA
= arg_get_lit(2);
342 uint8_t termDecision
= 0xff;
343 if (arg_get_str_len(3)) {
344 if (!strncmp(arg_get_str(3)->sval
[0], "aac", 4))
345 termDecision
= EMVAC_AAC
;
346 if (!strncmp(arg_get_str(3)->sval
[0], "tc", 4))
347 termDecision
= EMVAC_TC
;
348 if (!strncmp(arg_get_str(3)->sval
[0], "arqc", 4))
349 termDecision
= EMVAC_ARQC
;
351 if (termDecision
== 0xff) {
352 PrintAndLog("ERROR: can't find terminal decision '%s'", arg_get_str(3)->sval
[0]);
356 termDecision
= EMVAC_TC
;
359 termDecision
= termDecision
| EMVAC_CDAREQ
;
360 bool APDULogging
= arg_get_lit(4);
361 bool decodeTLV
= arg_get_lit(5);
362 CLIGetStrWithReturn(6, data
, &datalen
);
365 SetAPDULogging(APDULogging
);
368 const char *alr
= "Root terminal TLV tree";
369 struct tlvdb
*tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
372 struct tlv
*cdol_data_tlv
= NULL
;
373 // struct tlv *cdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8c, NULL), tlvRoot, 0x01); // 0x01 - dummy tag
374 struct tlv data_tlv
= {
377 .value
= (uint8_t *)data
,
379 cdol_data_tlv
= &data_tlv
;
380 PrintAndLog("CDOL data[%d]: %s", cdol_data_tlv
->len
, sprint_hex(cdol_data_tlv
->value
, cdol_data_tlv
->len
));
383 uint8_t buf
[APDU_RES_LEN
] = {0};
386 int res
= EMVAC(leaveSignalON
, termDecision
, (uint8_t *)cdol_data_tlv
->value
, cdol_data_tlv
->len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
388 // free(cdol_data_tlv);
392 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
398 TLVPrintFromBuffer(buf
, len
);
403 int CmdHFEMVGenerateChallenge(const char *cmd
) {
405 CLIParserInit("hf emv challenge",
406 "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.",
407 "Usage:\n\thf emv challenge -> get challenge\n\thf emv challenge -k -> get challenge, keep fileld ON\n");
411 arg_lit0("kK", "keep", "keep field ON for next command"),
412 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
415 CLIExecWithReturn(cmd
, argtable
, true);
417 bool leaveSignalON
= arg_get_lit(1);
418 bool APDULogging
= arg_get_lit(2);
421 SetAPDULogging(APDULogging
);
424 uint8_t buf
[APDU_RES_LEN
] = {0};
427 int res
= EMVGenerateChallenge(leaveSignalON
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
430 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
435 PrintAndLog("Challenge: %s", sprint_hex(buf
, len
));
437 if (len
!= 4 && len
!= 8)
438 PrintAndLog("WARNING: length of challenge must be 4 or 8, but it %d", len
);
443 int CmdHFEMVInternalAuthenticate(const char *cmd
) {
444 uint8_t data
[APDU_RES_LEN
] = {0};
447 CLIParserInit("hf emv intauth",
448 "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.",
449 "Usage:\n\thf emv intauth -k 01020304 -> execute Internal Authenticate with 4-byte DDOLdata and keep field ON after command\n"
450 "\thf emv intauth -t 01020304 -> execute Internal Authenticate with 4-byte DDOL data, show result in TLV\n");
454 arg_lit0("kK", "keep", "keep field ON for next command"),
455 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
456 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
457 arg_str1(NULL
, NULL
, "<HEX DDOLdata>", NULL
),
460 CLIExecWithReturn(cmd
, argtable
, false);
462 bool leaveSignalON
= arg_get_lit(1);
463 bool APDULogging
= arg_get_lit(2);
464 bool decodeTLV
= arg_get_lit(3);
465 CLIGetStrWithReturn(4, data
, &datalen
);
468 SetAPDULogging(APDULogging
);
471 PrintAndLog("DDOL data[%d]: %s", datalen
, sprint_hex(data
, datalen
));
474 uint8_t buf
[APDU_RES_LEN
] = {0};
477 int res
= EMVInternalAuthenticate(leaveSignalON
, data
, datalen
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
480 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
486 TLVPrintFromBuffer(buf
, len
);
491 int UsageCmdHFEMVExec(void) {
492 PrintAndLog("HELP : Executes EMV contactless transaction:\n");
493 PrintAndLog("Usage: hf emv exec [-s][-a][-t][-f][-v][-c][-x][-g]\n");
494 PrintAndLog(" Options:");
495 PrintAndLog(" -s : select card");
496 PrintAndLog(" -a : show APDU reqests and responses\n");
497 PrintAndLog(" -t : TLV decode results\n");
498 PrintAndLog(" -f : force search AID. Search AID instead of execute PPSE.\n");
499 PrintAndLog(" -v : transaction type - qVSDC or M/Chip.\n");
500 PrintAndLog(" -c : transaction type - qVSDC or M/Chip plus CDA (SDAD generation).\n");
501 PrintAndLog(" -x : transaction type - VSDC. For test only. Not a standart behavior.\n");
502 PrintAndLog(" -g : VISA. generate AC from GPO\n");
503 PrintAndLog("By default : transaction type - MSD.\n");
504 PrintAndLog("Samples:");
505 PrintAndLog(" hf emv exec -s -a -t -> execute MSD transaction");
506 PrintAndLog(" hf emv exec -s -a -t -c -> execute CDA transaction");
510 #define dreturn(n) {free(pdol_data_tlv);tlvdb_free(tlvSelect);tlvdb_free(tlvRoot);DropField();return n;}
512 int CmdHFEMVExec(const char *cmd
) {
513 bool activateField
= false;
514 bool showAPDU
= false;
515 bool decodeTLV
= false;
516 bool forceSearch
= false;
517 enum TransactionType TrType
= TT_MSD
;
518 bool GenACGPO
= false;
520 uint8_t buf
[APDU_RES_LEN
] = {0};
523 uint8_t AID
[APDU_AID_LEN
] = {0};
525 uint8_t ODAiList
[4096];
526 size_t ODAiListLen
= 0;
530 struct tlvdb
*tlvSelect
= NULL
;
531 struct tlvdb
*tlvRoot
= NULL
;
532 struct tlv
*pdol_data_tlv
= NULL
;
534 if (strlen(cmd
) < 1) {
540 while(param_getchar(cmd
, cmdp
) != 0x00) {
541 char c
= param_getchar(cmd
, cmdp
);
542 if ((c
== '-') && (param_getlength(cmd
, cmdp
) == 2))
543 switch (param_getchar_indx(cmd
, 1, cmdp
)) {
550 activateField
= true;
570 TrType
= TT_QVSDCMCHIP
;
581 PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd
, 1, cmdp
));
588 // init applets list tree
589 const char *al
= "Applets list";
590 tlvSelect
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
);
592 // Application Selection
593 // https://www.openscdp.org/scripts/tutorial/emv/applicationselection.html
596 PrintAndLog("\n* PPSE.");
597 SetAPDULogging(showAPDU
);
598 res
= EMVSearchPSE(activateField
, true, decodeTLV
, tlvSelect
);
600 // check PPSE and select application id
602 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
603 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
);
609 PrintAndLog("\n* Search AID in list.");
610 SetAPDULogging(false);
611 if (EMVSearch(activateField
, true, decodeTLV
, tlvSelect
)) {
615 // check search and select application id
616 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
617 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
);
621 const char *alr
= "Root terminal TLV tree";
622 tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
624 // check if we found EMV application on card
626 PrintAndLog("Can't select AID. EMV AID not found");
631 PrintAndLog("\n* Selecting AID:%s", sprint_hex_inrow(AID
, AIDlen
));
632 SetAPDULogging(showAPDU
);
633 res
= EMVSelect(false, true, AID
, AIDlen
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
636 PrintAndLog("Can't select AID (%d). Exit...", res
);
641 TLVPrintFromBuffer(buf
, len
);
642 PrintAndLog("* Selected.");
644 PrintAndLog("\n* Init transaction parameters.");
646 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
647 char *qVSDC
= "\x26\x00\x00\x00";
649 qVSDC
= "\x26\x80\x00\x00";
653 TLV_ADD(0x9F66, "\x86\x00\x00\x00"); // MSD
655 // not standard for contactless. just for test.
657 TLV_ADD(0x9F66, "\x46\x00\x00\x00"); // VSDC
660 TLV_ADD(0x9F66, qVSDC
); // qVSDC
663 TLV_ADD(0x9F66, qVSDC
); // qVSDC (VISA CDA not enabled)
666 TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC
670 //9F02:(Amount, authorized (Numeric)) len:6
671 TLV_ADD(0x9F02, "\x00\x00\x00\x00\x01\x00");
672 //9F1A:(Terminal Country Code) len:2
673 TLV_ADD(0x9F1A, "ru");
674 //5F2A:(Transaction Currency Code) len:2
675 // USD 840, EUR 978, RUR 810, RUB 643, RUR 810(old), UAH 980, AZN 031, n/a 999
676 TLV_ADD(0x5F2A, "\x09\x80");
677 //9A:(Transaction Date) len:3
678 TLV_ADD(0x9A, "\x00\x00\x00");
679 //9C:(Transaction Type) len:1 | 00 => Goods and service #01 => Cash
680 TLV_ADD(0x9C, "\x00");
681 // 9F37 Unpredictable Number len:4
682 TLV_ADD(0x9F37, "\x01\x02\x03\x04");
683 // 9F6A Unpredictable Number (MSD for UDOL) len:4
684 TLV_ADD(0x9F6A, "\x01\x02\x03\x04");
686 TLVPrintFromTLV(tlvRoot
); // TODO delete!!!
688 PrintAndLog("\n* Calc PDOL.");
689 pdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x9f38, NULL
), tlvRoot
, 0x83);
691 PrintAndLog("ERROR: can't create PDOL TLV.");
695 size_t pdol_data_tlv_data_len
;
696 unsigned char *pdol_data_tlv_data
= tlv_encode(pdol_data_tlv
, &pdol_data_tlv_data_len
);
697 if (!pdol_data_tlv_data
) {
698 PrintAndLog("ERROR: can't create PDOL data.");
701 PrintAndLog("PDOL data[%d]: %s", pdol_data_tlv_data_len
, sprint_hex(pdol_data_tlv_data
, pdol_data_tlv_data_len
));
703 PrintAndLog("\n* GPO.");
704 res
= EMVGPO(true, pdol_data_tlv_data
, pdol_data_tlv_data_len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
706 free(pdol_data_tlv_data
);
707 //free(pdol_data_tlv); --- free on exit.
710 PrintAndLog("GPO error(%d): %4x. Exit...", res
, sw
);
714 // process response template format 1 [id:80 2b AIP + x4b AFL] and format 2 [id:77 TLV]
715 if (buf
[0] == 0x80) {
717 PrintAndLog("GPO response format1:");
718 TLVPrintFromBuffer(buf
, len
);
721 if (len
< 4 || (len
- 4) % 4) {
722 PrintAndLog("ERROR: GPO response format1 parsing error. length=%d", len
);
725 struct tlvdb
* f1AIP
= tlvdb_fixed(0x82, 2, buf
+ 2);
726 tlvdb_add(tlvRoot
, f1AIP
);
728 PrintAndLog("\n* * Decode response format 1 (0x80) AIP and AFL:");
729 TLVPrintFromTLV(f1AIP
);
733 struct tlvdb
* f1AFL
= tlvdb_fixed(0x94, len
- 4, buf
+ 2 + 2);
734 tlvdb_add(tlvRoot
, f1AFL
);
736 TLVPrintFromTLV(f1AFL
);
740 TLVPrintFromBuffer(buf
, len
);
743 // extract PAN from track2
745 const struct tlv
*track2
= tlvdb_get(tlvRoot
, 0x57, NULL
);
746 if (!tlvdb_get(tlvRoot
, 0x5a, NULL
) && track2
&& track2
->len
>= 8) {
747 struct tlvdb
*pan
= GetPANFromTrack2(track2
);
749 tlvdb_add(tlvRoot
, pan
);
751 const struct tlv
*pantlv
= tlvdb_get(tlvRoot
, 0x5a, NULL
);
752 PrintAndLog("\n* * Extracted PAN from track2: %s", sprint_hex(pantlv
->value
, pantlv
->len
));
754 PrintAndLog("\n* * WARNING: Can't extract PAN from track2.");
759 PrintAndLog("\n* Read records from AFL.");
760 const struct tlv
*AFL
= tlvdb_get(tlvRoot
, 0x94, NULL
);
761 if (!AFL
|| !AFL
->len
) {
762 PrintAndLog("WARNING: AFL not found.");
765 while(AFL
&& AFL
->len
) {
767 PrintAndLog("ERROR: Wrong AFL length: %d", AFL
->len
);
771 for (int i
= 0; i
< AFL
->len
/ 4; i
++) {
772 uint8_t SFI
= AFL
->value
[i
* 4 + 0] >> 3;
773 uint8_t SFIstart
= AFL
->value
[i
* 4 + 1];
774 uint8_t SFIend
= AFL
->value
[i
* 4 + 2];
775 uint8_t SFIoffline
= AFL
->value
[i
* 4 + 3];
777 PrintAndLog("* * SFI[%02x] start:%02x end:%02x offline:%02x", SFI
, SFIstart
, SFIend
, SFIoffline
);
778 if (SFI
== 0 || SFI
== 31 || SFIstart
== 0 || SFIstart
> SFIend
) {
779 PrintAndLog("SFI ERROR! Skipped...");
783 for(int n
= SFIstart
; n
<= SFIend
; n
++) {
784 PrintAndLog("* * * SFI[%02x] %d", SFI
, n
);
786 res
= EMVReadRecord(true, SFI
, n
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
788 PrintAndLog("ERROR SFI[%02x]. APDU error %4x", SFI
, sw
);
793 TLVPrintFromBuffer(buf
, len
);
797 // Build Input list for Offline Data Authentication
798 // EMV 4.3 book3 10.3, page 96
801 const unsigned char *abuf
= buf
;
804 if (tlv_parse_tl(&abuf
, &elmlen
, &e
)) {
805 memcpy(&ODAiList
[ODAiListLen
], &buf
[len
- elmlen
], elmlen
);
806 ODAiListLen
+= elmlen
;
808 PrintAndLog("ERROR SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI
);
811 memcpy(&ODAiList
[ODAiListLen
], buf
, len
);
821 // copy Input list for Offline Data Authentication
823 struct tlvdb
*oda
= tlvdb_fixed(0x21, ODAiListLen
, ODAiList
); // not a standard tag
824 tlvdb_add(tlvRoot
, oda
);
825 PrintAndLog("* Input list for Offline Data Authentication added to TLV. len=%d \n", ODAiListLen
);
829 const struct tlv
*AIPtlv
= tlvdb_get(tlvRoot
, 0x82, NULL
);
830 uint16_t AIP
= AIPtlv
->value
[0] + AIPtlv
->value
[1] * 0x100;
831 PrintAndLog("* * AIP=%04x", AIP
);
835 PrintAndLog("\n* SDA");
841 PrintAndLog("\n* DDA");
842 trDDA(decodeTLV
, tlvRoot
);
848 if (TrType
== TT_QVSDCMCHIP
|| TrType
== TT_CDA
){
849 // 9F26: Application Cryptogram
850 const struct tlv
*AC
= tlvdb_get(tlvRoot
, 0x9F26, NULL
);
852 PrintAndLog("\n--> qVSDC transaction.");
853 PrintAndLog("* AC path");
855 // 9F36: Application Transaction Counter (ATC)
856 const struct tlv
*ATC
= tlvdb_get(tlvRoot
, 0x9F36, NULL
);
859 // 9F10: Issuer Application Data - optional
860 const struct tlv
*IAD
= tlvdb_get(tlvRoot
, 0x9F10, NULL
);
863 PrintAndLog("ATC: %s", sprint_hex(ATC
->value
, ATC
->len
));
864 PrintAndLog("AC: %s", sprint_hex(AC
->value
, AC
->len
));
866 PrintAndLog("IAD: %s", sprint_hex(IAD
->value
, IAD
->len
));
868 if (IAD
->len
>= IAD
->value
[0] + 1) {
869 PrintAndLog("\tKey index: 0x%02x", IAD
->value
[1]);
870 PrintAndLog("\tCrypto ver: 0x%02x(%03d)", IAD
->value
[2], IAD
->value
[2]);
871 PrintAndLog("\tCVR:", sprint_hex(&IAD
->value
[3], IAD
->value
[0] - 2));
872 struct tlvdb
* cvr
= tlvdb_fixed(0x20, IAD
->value
[0] - 2, &IAD
->value
[3]);
873 TLVPrintFromTLVLev(cvr
, 1);
876 PrintAndLog("WARNING: IAD not found.");
880 PrintAndLog("ERROR AC: Application Transaction Counter (ATC) not found.");
886 if (GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
&& (TrType
== TT_QVSDCMCHIP
|| TrType
== TT_CDA
)){
887 const struct tlv
*CDOL1
= tlvdb_get(tlvRoot
, 0x8c, NULL
);
888 if (CDOL1
&& GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
) { // and m/chip transaction flag
889 PrintAndLog("\n--> Mastercard M/Chip transaction.");
891 PrintAndLog("* * Generate challenge");
892 res
= EMVGenerateChallenge(true, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
894 PrintAndLog("ERROR GetChallenge. APDU error %4x", sw
);
898 PrintAndLog("ERROR GetChallenge. Wrong challenge length %d", len
);
902 // ICC Dynamic Number
903 struct tlvdb
* ICCDynN
= tlvdb_fixed(0x9f4c, len
, buf
);
904 tlvdb_add(tlvRoot
, ICCDynN
);
906 PrintAndLog("\n* * ICC Dynamic Number:");
907 TLVPrintFromTLV(ICCDynN
);
910 PrintAndLog("* * Calc CDOL1");
911 struct tlv
*cdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x8c, NULL
), tlvRoot
, 0x01); // 0x01 - dummy tag
913 PrintAndLog("ERROR: can't create CDOL1 TLV.");
916 PrintAndLog("CDOL1 data[%d]: %s", cdol_data_tlv
->len
, sprint_hex(cdol_data_tlv
->value
, cdol_data_tlv
->len
));
918 PrintAndLog("* * AC1");
919 // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD
920 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
);
923 PrintAndLog("AC1 error(%d): %4x. Exit...", res
, sw
);
928 TLVPrintFromBuffer(buf
, len
);
931 PrintAndLog("\n* CDA:");
932 struct tlvdb
*ac_tlv
= tlvdb_parse_multi(buf
, len
);
933 res
= trCDA(tlvRoot
, ac_tlv
, pdol_data_tlv
, cdol_data_tlv
);
935 PrintAndLog("CDA error (%d)", res
);
940 PrintAndLog("\n* M/Chip transaction result:");
941 // 9F27: Cryptogram Information Data (CID)
942 const struct tlv
*CID
= tlvdb_get(tlvRoot
, 0x9F27, NULL
);
944 emv_tag_dump(CID
, stdout
, 0);
945 PrintAndLog("------------------------------");
947 switch(CID
->value
[0] & EMVAC_AC_MASK
){
949 PrintAndLog("Transaction DECLINED.");
952 PrintAndLog("Transaction approved OFFLINE.");
955 PrintAndLog("Transaction approved ONLINE.");
958 PrintAndLog("ERROR: CID transaction code error %2x", CID
->value
[0] & EMVAC_AC_MASK
);
962 PrintAndLog("ERROR: Wrong CID length %d", CID
->len
);
965 PrintAndLog("ERROR: CID(9F27) not found.");
972 if (AIP
& 0x8000 && TrType
== TT_MSD
) {
973 PrintAndLog("\n--> MSD transaction.");
975 PrintAndLog("* MSD dCVV path. Check dCVV");
977 const struct tlv
*track2
= tlvdb_get(tlvRoot
, 0x57, NULL
);
979 PrintAndLog("Track2: %s", sprint_hex(track2
->value
, track2
->len
));
981 struct tlvdb
*dCVV
= GetdCVVRawFromTrack2(track2
);
982 PrintAndLog("dCVV raw data:");
983 TLVPrintFromTLV(dCVV
);
985 if (GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
) {
986 PrintAndLog("\n* Mastercard calculate UDOL");
989 const struct tlv
*UDOL
= tlvdb_get(tlvRoot
, 0x9F69, NULL
);
990 // UDOL(9F69) default: 9F6A (Unpredictable number) 4 bytes
991 const struct tlv defUDOL
= {
994 .value
= (uint8_t *)"\x9f\x6a\x04",
997 PrintAndLog("Use default UDOL.");
999 struct tlv
*udol_data_tlv
= dol_process(UDOL
? UDOL
: &defUDOL
, tlvRoot
, 0x01); // 0x01 - dummy tag
1000 if (!udol_data_tlv
){
1001 PrintAndLog("ERROR: can't create UDOL TLV.");
1005 PrintAndLog("UDOL data[%d]: %s", udol_data_tlv
->len
, sprint_hex(udol_data_tlv
->value
, udol_data_tlv
->len
));
1007 PrintAndLog("\n* Mastercard compute cryptographic checksum(UDOL)");
1009 res
= MSCComputeCryptoChecksum(true, (uint8_t *)udol_data_tlv
->value
, udol_data_tlv
->len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
1011 PrintAndLog("ERROR Compute Crypto Checksum. APDU error %4x", sw
);
1012 free(udol_data_tlv
);
1017 TLVPrintFromBuffer(buf
, len
);
1020 free(udol_data_tlv
);
1024 PrintAndLog("ERROR MSD: Track2 data not found.");
1032 free(pdol_data_tlv
);
1033 tlvdb_free(tlvSelect
);
1034 tlvdb_free(tlvRoot
);
1036 PrintAndLog("\n* Transaction completed.");
1041 int CmdHFEMVTest(const char *cmd
) {
1042 return ExecuteCryptoTests(true);
1045 int CmdHelp(const char *Cmd
);
1046 static command_t CommandTable
[] = {
1047 {"help", CmdHelp
, 1, "This help"},
1048 {"exec", CmdHFEMVExec
, 0, "Executes EMV contactless transaction."},
1049 {"pse", CmdHFEMVPPSE
, 0, "Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory."},
1050 {"search", CmdHFEMVSearch
, 0, "Try to select all applets from applets list and print installed applets."},
1051 {"select", CmdHFEMVSelect
, 0, "Select applet."},
1052 {"gpo", CmdHFEMVGPO
, 0, "Execute GetProcessingOptions."},
1053 {"readrec", CmdHFEMVReadRecord
, 0, "Read files from card."},
1054 {"genac", CmdHFEMVAC
, 0, "Generate ApplicationCryptogram."},
1055 {"challenge", CmdHFEMVGenerateChallenge
, 0, "Generate challenge."},
1056 {"intauth", CmdHFEMVInternalAuthenticate
, 0, "Internal authentication."},
1057 {"test", CmdHFEMVTest
, 0, "Crypto logic test."},
1058 {NULL
, NULL
, 0, NULL
}
1061 int CmdHFEMV(const char *Cmd
) {
1062 CmdsParse(CommandTable
, Cmd
);
1066 int CmdHelp(const char *Cmd
) {
1067 CmdsHelp(CommandTable
);