]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/emv/cmdemv.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2017 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"
16 int UsageCmdHFEMVSelect(void) {
17 PrintAndLog("HELP : Executes select applet command:\n");
18 PrintAndLog("Usage: hf emv select [-s][-k][-a][-t] <HEX applet AID>\n");
19 PrintAndLog(" Options:");
20 PrintAndLog(" -s : select card");
21 PrintAndLog(" -k : keep field for next command");
22 PrintAndLog(" -a : show APDU reqests and responses\n");
23 PrintAndLog(" -t : TLV decode results\n");
24 PrintAndLog("Samples:");
25 PrintAndLog(" hf emv select -s a00000000101 -> select card, select applet");
26 PrintAndLog(" hf emv select -s -t a00000000101 -> select card, select applet, show result in TLV");
30 int CmdHFEMVSelect(const char *cmd
) {
31 uint8_t data
[APDU_AID_LEN
] = {0};
33 bool activateField
= false;
34 bool leaveSignalON
= false;
35 bool decodeTLV
= false;
37 if (strlen(cmd
) < 1) {
38 UsageCmdHFEMVSelect();
42 SetAPDULogging(false);
45 while(param_getchar(cmd
, cmdp
) != 0x00) {
46 char c
= param_getchar(cmd
, cmdp
);
47 if ((c
== '-') && (param_getlength(cmd
, cmdp
) == 2))
48 switch (param_getchar_indx(cmd
, 1, cmdp
)) {
51 UsageCmdHFEMVSelect();
70 PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd
, 1, cmdp
));
74 if (isxdigit((unsigned char)c
)) {
75 switch(param_gethex_to_eol(cmd
, cmdp
, data
, sizeof(data
), &datalen
)) {
77 PrintAndLog("Invalid HEX value.");
80 PrintAndLog("AID too large.");
83 PrintAndLog("Hex must have even number of digits.");
87 // we get all the hex to end of line with spaces
96 uint8_t buf
[APDU_RES_LEN
] = {0};
99 int res
= EMVSelect(activateField
, leaveSignalON
, data
, datalen
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
102 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
108 TLVPrintFromBuffer(buf
, len
);
113 int UsageCmdHFEMVSearch(void) {
114 PrintAndLog("HELP : Tries to select all applets from applet list:\n");
115 PrintAndLog("Usage: hf emv search [-s][-k][-a][-t]\n");
116 PrintAndLog(" Options:");
117 PrintAndLog(" -s : select card");
118 PrintAndLog(" -k : keep field for next command");
119 PrintAndLog(" -a : show APDU reqests and responses\n");
120 PrintAndLog(" -t : TLV decode results of selected applets\n");
121 PrintAndLog("Samples:");
122 PrintAndLog(" hf emv search -s -> select card and search");
123 PrintAndLog(" hf emv search -s -t -> select card, search and show result in TLV");
127 int CmdHFEMVSearch(const char *cmd
) {
129 bool activateField
= false;
130 bool leaveSignalON
= false;
131 bool decodeTLV
= false;
133 if (strlen(cmd
) < 1) {
134 UsageCmdHFEMVSearch();
138 SetAPDULogging(false);
141 while(param_getchar(cmd
, cmdp
) != 0x00) {
142 char c
= param_getchar(cmd
, cmdp
);
143 if ((c
== '-') && (param_getlength(cmd
, cmdp
) == 2))
144 switch (param_getchar_indx(cmd
, 1, cmdp
)) {
147 UsageCmdHFEMVSearch();
151 activateField
= true;
155 leaveSignalON
= true;
159 SetAPDULogging(true);
166 PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd
, 1, cmdp
));
172 struct tlvdb
*t
= NULL
;
173 const char *al
= "Applets list";
174 t
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
);
176 if (EMVSearch(activateField
, leaveSignalON
, decodeTLV
, t
)) {
181 PrintAndLog("Search completed.");
185 TLVPrintAIDlistFromSelectTLV(t
);
193 int UsageCmdHFEMVPPSE(void) {
194 PrintAndLog("HELP : Executes PSE/PPSE select command. It returns list of applet on the card:\n");
195 PrintAndLog("Usage: hf emv pse [-s][-k][-1][-2][-a][-t]\n");
196 PrintAndLog(" Options:");
197 PrintAndLog(" -s : select card");
198 PrintAndLog(" -k : keep field for next command");
199 PrintAndLog(" -1 : ppse (1PAY.SYS.DDF01)");
200 PrintAndLog(" -2 : pse (2PAY.SYS.DDF01)");
201 PrintAndLog(" -a : show APDU reqests and responses\n");
202 PrintAndLog(" -t : TLV decode results\n");
203 PrintAndLog("Samples:");
204 PrintAndLog(" hf emv pse -s -1 -> select, get pse");
205 PrintAndLog(" hf emv pse -s -k -2 -> select, get ppse, keep field");
206 PrintAndLog(" hf emv pse -s -t -2 -> select, get ppse, show result in TLV");
210 int CmdHFEMVPPSE(const char *cmd
) {
213 bool activateField
= false;
214 bool leaveSignalON
= false;
215 bool decodeTLV
= false;
217 if (strlen(cmd
) < 1) {
222 SetAPDULogging(false);
225 while(param_getchar(cmd
, cmdp
) != 0x00) {
226 char c
= param_getchar(cmd
, cmdp
);
227 if ((c
== '-') && (param_getlength(cmd
, cmdp
) == 2))
228 switch (param_getchar_indx(cmd
, 1, cmdp
)) {
235 activateField
= true;
239 leaveSignalON
= true;
243 SetAPDULogging(true);
256 PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd
, 1, cmdp
));
263 uint8_t buf
[APDU_RES_LEN
] = {0};
266 int res
= EMVSelectPSE(activateField
, leaveSignalON
, PSENum
, buf
, sizeof(buf
), &len
, &sw
);
269 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw
>> 8, sw
& 0xff));
276 TLVPrintFromBuffer(buf
, len
);
281 int UsageCmdHFEMVExec(void) {
282 PrintAndLog("HELP : Executes EMV contactless transaction:\n");
283 PrintAndLog("Usage: hf emv exec [-s][-a][-t][-j][-f][-v][-c][-x][-g]\n");
284 PrintAndLog(" Options:");
285 PrintAndLog(" -s : select card");
286 PrintAndLog(" -a : show APDU reqests and responses\n");
287 PrintAndLog(" -t : TLV decode results\n");
288 PrintAndLog(" -j : load transaction parameters from `emv/defparams.json` file\n");
289 PrintAndLog(" -f : force search AID. Search AID instead of execute PPSE.\n");
290 PrintAndLog(" -v : transaction type - qVSDC or M/Chip.\n");
291 PrintAndLog(" -c : transaction type - qVSDC or M/Chip plus CDA (SDAD generation).\n");
292 PrintAndLog(" -x : transaction type - VSDC. For test only. Not a standart behavior.\n");
293 PrintAndLog(" -g : VISA. generate AC from GPO\n");
294 PrintAndLog("By default : transaction type - MSD.\n");
295 PrintAndLog("Samples:");
296 PrintAndLog(" hf emv exec -s -a -t -> execute MSD transaction");
297 PrintAndLog(" hf emv exec -s -a -t -c -> execute CDA transaction");
301 #define TLV_ADD(tag, value)( tlvdb_change_or_add_node(tlvRoot, tag, sizeof(value) - 1, (const unsigned char *)value) )
302 #define dreturn(n) {free(pdol_data_tlv);tlvdb_free(tlvSelect);tlvdb_free(tlvRoot);DropField();return n;}
304 bool HexToBuffer(const char *errormsg
, const char *hexvalue
, uint8_t * buffer
, size_t maxbufferlen
, size_t *bufferlen
) {
307 switch(param_gethex_to_eol(hexvalue
, 0, buffer
, maxbufferlen
, &buflen
)) {
309 PrintAndLog("%s Invalid HEX value.", errormsg
);
312 PrintAndLog("%s Hex value too large.", errormsg
);
315 PrintAndLog("%s Hex value must have even number of digits.", errormsg
);
319 if (buflen
> maxbufferlen
) {
320 PrintAndLog("%s HEX length (%d) more than %d", errormsg
, *bufferlen
, maxbufferlen
);
329 bool ParamLoadFromJson(struct tlvdb
*tlv
) {
334 PrintAndLog("ERROR load params: tlv tree is NULL.");
338 // current path + file name
339 const char *relfname
= "emv/defparams.json";
340 char fname
[strlen(get_my_executable_directory()) + strlen(relfname
) + 1];
341 strcpy(fname
, get_my_executable_directory());
342 strcat(fname
, relfname
);
344 root
= json_load_file(fname
, 0, &error
);
346 PrintAndLog("Load params: json error on line %d: %s", error
.line
, error
.text
);
350 if (!json_is_array(root
)) {
351 PrintAndLog("Load params: Invalid json format. root must be array.");
355 PrintAndLog("Load params: json OK");
357 for(int i
= 0; i
< json_array_size(root
); i
++) {
358 json_t
*data
, *jtype
, *jlength
, *jvalue
;
360 data
= json_array_get(root
, i
);
361 if(!json_is_object(data
))
363 PrintAndLog("Load params: data [%d] is not an object", i
+ 1);
368 jtype
= json_object_get(data
, "type");
369 if(!json_is_string(jtype
))
371 PrintAndLog("Load params: data [%d] type is not a string", i
+ 1);
375 const char *tlvType
= json_string_value(jtype
);
377 jvalue
= json_object_get(data
, "value");
378 if(!json_is_string(jvalue
))
380 PrintAndLog("Load params: data [%d] value is not a string", i
+ 1);
384 const char *tlvValue
= json_string_value(jvalue
);
386 jlength
= json_object_get(data
, "length");
387 if(!json_is_number(jlength
))
389 PrintAndLog("Load params: data [%d] length is not a number", i
+ 1);
394 int tlvLength
= json_integer_value(jlength
);
395 if (tlvLength
> 250) {
396 PrintAndLog("Load params: data [%d] length more than 250", i
+ 1);
401 PrintAndLog("TLV param: %s[%d]=%s", tlvType
, tlvLength
, tlvValue
);
402 uint8_t buf
[251] = {0};
405 // 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...
406 if (!HexToBuffer("TLV Error type:", tlvType
, buf
, 2, &buflen
)) {
411 for (int i
= 0; i
< buflen
; i
++) {
412 tag
= (tag
<< 8) + buf
[i
];
415 if (!HexToBuffer("TLV Error value:", tlvValue
, buf
, sizeof(buf
) - 1, &buflen
)) {
420 if (buflen
!= tlvLength
) {
421 PrintAndLog("Load params: data [%d] length of HEX must(%d) be identical to length in TLV param(%d)", i
+ 1, buflen
, tlvLength
);
426 tlvdb_change_or_add_node(tlv
, tag
, tlvLength
, (const unsigned char *)buf
);
434 void ParamLoadDefaults(struct tlvdb
*tlvRoot
) {
435 //9F02:(Amount, authorized (Numeric)) len:6
436 TLV_ADD(0x9F02, "\x00\x00\x00\x00\x01\x00");
437 //9F1A:(Terminal Country Code) len:2
438 TLV_ADD(0x9F1A, "ru");
439 //5F2A:(Transaction Currency Code) len:2
440 // USD 840, EUR 978, RUR 810, RUB 643, RUR 810(old), UAH 980, AZN 031, n/a 999
441 TLV_ADD(0x5F2A, "\x09\x80");
442 //9A:(Transaction Date) len:3
443 TLV_ADD(0x9A, "\x00\x00\x00");
444 //9C:(Transaction Type) len:1 | 00 => Goods and service #01 => Cash
445 TLV_ADD(0x9C, "\x00");
446 // 9F37 Unpredictable Number len:4
447 TLV_ADD(0x9F37, "\x01\x02\x03\x04");
448 // 9F6A Unpredictable Number (MSD for UDOL) len:4
449 TLV_ADD(0x9F6A, "\x01\x02\x03\x04");
450 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
451 TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC
454 int CmdHFEMVExec(const char *cmd
) {
455 bool activateField
= false;
456 bool showAPDU
= false;
457 bool decodeTLV
= false;
458 bool forceSearch
= false;
459 enum TransactionType TrType
= TT_MSD
;
460 bool GenACGPO
= false;
461 bool paramLoadJSON
= false;
463 uint8_t buf
[APDU_RES_LEN
] = {0};
466 uint8_t AID
[APDU_AID_LEN
] = {0};
468 uint8_t ODAiList
[4096];
469 size_t ODAiListLen
= 0;
473 struct tlvdb
*tlvSelect
= NULL
;
474 struct tlvdb
*tlvRoot
= NULL
;
475 struct tlv
*pdol_data_tlv
= NULL
;
477 if (strlen(cmd
) < 1) {
483 while(param_getchar(cmd
, cmdp
) != 0x00) {
484 char c
= param_getchar(cmd
, cmdp
);
485 if ((c
== '-') && (param_getlength(cmd
, cmdp
) == 2))
486 switch (param_getchar_indx(cmd
, 1, cmdp
)) {
493 activateField
= true;
513 TrType
= TT_QVSDCMCHIP
;
525 paramLoadJSON
= true;
528 PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd
, 1, cmdp
));
535 // init applets list tree
536 const char *al
= "Applets list";
537 tlvSelect
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
);
539 // Application Selection
540 // https://www.openscdp.org/scripts/tutorial/emv/applicationselection.html
543 PrintAndLog("\n* PPSE.");
544 SetAPDULogging(showAPDU
);
545 res
= EMVSearchPSE(activateField
, true, decodeTLV
, tlvSelect
);
547 // check PPSE and select application id
549 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
550 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
);
556 PrintAndLog("\n* Search AID in list.");
557 SetAPDULogging(false);
558 if (EMVSearch(activateField
, true, decodeTLV
, tlvSelect
)) {
562 // check search and select application id
563 TLVPrintAIDlistFromSelectTLV(tlvSelect
);
564 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
);
568 const char *alr
= "Root terminal TLV tree";
569 tlvRoot
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
);
571 // check if we found EMV application on card
573 PrintAndLog("Can't select AID. EMV AID not found");
578 PrintAndLog("\n* Selecting AID:%s", sprint_hex_inrow(AID
, AIDlen
));
579 SetAPDULogging(showAPDU
);
580 res
= EMVSelect(false, true, AID
, AIDlen
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
583 PrintAndLog("Can't select AID (%d). Exit...", res
);
588 TLVPrintFromBuffer(buf
, len
);
589 PrintAndLog("* Selected.");
591 PrintAndLog("\n* Init transaction parameters.");
593 ParamLoadDefaults(tlvRoot
);
596 PrintAndLog("* * Transaction parameters loading from JSON...");
597 ParamLoadFromJson(tlvRoot
);
600 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
601 char *qVSDC
= "\x26\x00\x00\x00";
603 qVSDC
= "\x26\x80\x00\x00";
607 TLV_ADD(0x9F66, "\x86\x00\x00\x00"); // MSD
609 // not standard for contactless. just for test.
611 TLV_ADD(0x9F66, "\x46\x00\x00\x00"); // VSDC
614 TLV_ADD(0x9F66, qVSDC
); // qVSDC
617 TLV_ADD(0x9F66, qVSDC
); // qVSDC (VISA CDA not enabled)
623 TLVPrintFromTLV(tlvRoot
); // TODO delete!!!
625 PrintAndLog("\n* Calc PDOL.");
626 pdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x9f38, NULL
), tlvRoot
, 0x83);
628 PrintAndLog("ERROR: can't create PDOL TLV.");
632 size_t pdol_data_tlv_data_len
;
633 unsigned char *pdol_data_tlv_data
= tlv_encode(pdol_data_tlv
, &pdol_data_tlv_data_len
);
634 if (!pdol_data_tlv_data
) {
635 PrintAndLog("ERROR: can't create PDOL data.");
638 PrintAndLog("PDOL data[%d]: %s", pdol_data_tlv_data_len
, sprint_hex(pdol_data_tlv_data
, pdol_data_tlv_data_len
));
640 PrintAndLog("\n* GPO.");
641 res
= EMVGPO(true, pdol_data_tlv_data
, pdol_data_tlv_data_len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
643 free(pdol_data_tlv_data
);
644 //free(pdol_data_tlv); --- free on exit.
647 PrintAndLog("GPO error(%d): %4x. Exit...", res
, sw
);
651 // process response template format 1 [id:80 2b AIP + x4b AFL] and format 2 [id:77 TLV]
652 if (buf
[0] == 0x80) {
654 PrintAndLog("GPO response format1:");
655 TLVPrintFromBuffer(buf
, len
);
658 if (len
< 4 || (len
- 4) % 4) {
659 PrintAndLog("ERROR: GPO response format1 parsing error. length=%d", len
);
662 struct tlvdb
* f1AIP
= tlvdb_fixed(0x82, 2, buf
+ 2);
663 tlvdb_add(tlvRoot
, f1AIP
);
665 PrintAndLog("\n* * Decode response format 1 (0x80) AIP and AFL:");
666 TLVPrintFromTLV(f1AIP
);
670 struct tlvdb
* f1AFL
= tlvdb_fixed(0x94, len
- 4, buf
+ 2 + 2);
671 tlvdb_add(tlvRoot
, f1AFL
);
673 TLVPrintFromTLV(f1AFL
);
677 TLVPrintFromBuffer(buf
, len
);
680 // extract PAN from track2
682 const struct tlv
*track2
= tlvdb_get(tlvRoot
, 0x57, NULL
);
683 if (!tlvdb_get(tlvRoot
, 0x5a, NULL
) && track2
&& track2
->len
>= 8) {
684 struct tlvdb
*pan
= GetPANFromTrack2(track2
);
686 tlvdb_add(tlvRoot
, pan
);
688 const struct tlv
*pantlv
= tlvdb_get(tlvRoot
, 0x5a, NULL
);
689 PrintAndLog("\n* * Extracted PAN from track2: %s", sprint_hex(pantlv
->value
, pantlv
->len
));
691 PrintAndLog("\n* * WARNING: Can't extract PAN from track2.");
696 PrintAndLog("\n* Read records from AFL.");
697 const struct tlv
*AFL
= tlvdb_get(tlvRoot
, 0x94, NULL
);
698 if (!AFL
|| !AFL
->len
) {
699 PrintAndLog("WARNING: AFL not found.");
702 while(AFL
&& AFL
->len
) {
704 PrintAndLog("ERROR: Wrong AFL length: %d", AFL
->len
);
708 for (int i
= 0; i
< AFL
->len
/ 4; i
++) {
709 uint8_t SFI
= AFL
->value
[i
* 4 + 0] >> 3;
710 uint8_t SFIstart
= AFL
->value
[i
* 4 + 1];
711 uint8_t SFIend
= AFL
->value
[i
* 4 + 2];
712 uint8_t SFIoffline
= AFL
->value
[i
* 4 + 3];
714 PrintAndLog("* * SFI[%02x] start:%02x end:%02x offline:%02x", SFI
, SFIstart
, SFIend
, SFIoffline
);
715 if (SFI
== 0 || SFI
== 31 || SFIstart
== 0 || SFIstart
> SFIend
) {
716 PrintAndLog("SFI ERROR! Skipped...");
720 for(int n
= SFIstart
; n
<= SFIend
; n
++) {
721 PrintAndLog("* * * SFI[%02x] %d", SFI
, n
);
723 res
= EMVReadRecord(true, SFI
, n
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
725 PrintAndLog("ERROR SFI[%02x]. APDU error %4x", SFI
, sw
);
730 TLVPrintFromBuffer(buf
, len
);
734 // Build Input list for Offline Data Authentication
735 // EMV 4.3 book3 10.3, page 96
738 const unsigned char *abuf
= buf
;
741 if (tlv_parse_tl(&abuf
, &elmlen
, &e
)) {
742 memcpy(&ODAiList
[ODAiListLen
], &buf
[len
- elmlen
], elmlen
);
743 ODAiListLen
+= elmlen
;
745 PrintAndLog("ERROR SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI
);
748 memcpy(&ODAiList
[ODAiListLen
], buf
, len
);
758 // copy Input list for Offline Data Authentication
760 struct tlvdb
*oda
= tlvdb_fixed(0x21, ODAiListLen
, ODAiList
); // not a standard tag
761 tlvdb_add(tlvRoot
, oda
);
762 PrintAndLog("* Input list for Offline Data Authentication added to TLV. len=%d \n", ODAiListLen
);
766 const struct tlv
*AIPtlv
= tlvdb_get(tlvRoot
, 0x82, NULL
);
767 uint16_t AIP
= AIPtlv
->value
[0] + AIPtlv
->value
[1] * 0x100;
768 PrintAndLog("* * AIP=%04x", AIP
);
772 PrintAndLog("\n* SDA");
778 PrintAndLog("\n* DDA");
779 trDDA(decodeTLV
, tlvRoot
);
785 if (TrType
== TT_QVSDCMCHIP
|| TrType
== TT_CDA
){
786 // 9F26: Application Cryptogram
787 const struct tlv
*AC
= tlvdb_get(tlvRoot
, 0x9F26, NULL
);
789 PrintAndLog("\n--> qVSDC transaction.");
790 PrintAndLog("* AC path");
792 // 9F36: Application Transaction Counter (ATC)
793 const struct tlv
*ATC
= tlvdb_get(tlvRoot
, 0x9F36, NULL
);
796 // 9F10: Issuer Application Data - optional
797 const struct tlv
*IAD
= tlvdb_get(tlvRoot
, 0x9F10, NULL
);
800 PrintAndLog("ATC: %s", sprint_hex(ATC
->value
, ATC
->len
));
801 PrintAndLog("AC: %s", sprint_hex(AC
->value
, AC
->len
));
803 PrintAndLog("IAD: %s", sprint_hex(IAD
->value
, IAD
->len
));
805 if (IAD
->len
>= IAD
->value
[0] + 1) {
806 PrintAndLog("\tKey index: 0x%02x", IAD
->value
[1]);
807 PrintAndLog("\tCrypto ver: 0x%02x(%03d)", IAD
->value
[2], IAD
->value
[2]);
808 PrintAndLog("\tCVR:", sprint_hex(&IAD
->value
[3], IAD
->value
[0] - 2));
809 struct tlvdb
* cvr
= tlvdb_fixed(0x20, IAD
->value
[0] - 2, &IAD
->value
[3]);
810 TLVPrintFromTLVLev(cvr
, 1);
813 PrintAndLog("WARNING: IAD not found.");
817 PrintAndLog("ERROR AC: Application Transaction Counter (ATC) not found.");
823 if (GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
&& (TrType
== TT_QVSDCMCHIP
|| TrType
== TT_CDA
)){
824 const struct tlv
*CDOL1
= tlvdb_get(tlvRoot
, 0x8c, NULL
);
825 if (CDOL1
&& GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
) { // and m/chip transaction flag
826 PrintAndLog("\n--> Mastercard M/Chip transaction.");
828 PrintAndLog("* * Generate challenge");
829 res
= EMVGenerateChallenge(true, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
831 PrintAndLog("ERROR GetChallenge. APDU error %4x", sw
);
835 PrintAndLog("ERROR GetChallenge. Wrong challenge length %d", len
);
839 // ICC Dynamic Number
840 struct tlvdb
* ICCDynN
= tlvdb_fixed(0x9f4c, len
, buf
);
841 tlvdb_add(tlvRoot
, ICCDynN
);
843 PrintAndLog("\n* * ICC Dynamic Number:");
844 TLVPrintFromTLV(ICCDynN
);
847 PrintAndLog("* * Calc CDOL1");
848 struct tlv
*cdol_data_tlv
= dol_process(tlvdb_get(tlvRoot
, 0x8c, NULL
), tlvRoot
, 0x01); // 0x01 - dummy tag
850 PrintAndLog("ERROR: can't create CDOL1 TLV.");
853 PrintAndLog("CDOL1 data[%d]: %s", cdol_data_tlv
->len
, sprint_hex(cdol_data_tlv
->value
, cdol_data_tlv
->len
));
855 PrintAndLog("* * AC1");
856 // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD
857 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
);
860 PrintAndLog("AC1 error(%d): %4x. Exit...", res
, sw
);
865 TLVPrintFromBuffer(buf
, len
);
868 PrintAndLog("\n* CDA:");
869 struct tlvdb
*ac_tlv
= tlvdb_parse_multi(buf
, len
);
870 res
= trCDA(tlvRoot
, ac_tlv
, pdol_data_tlv
, cdol_data_tlv
);
872 PrintAndLog("CDA error (%d)", res
);
877 PrintAndLog("\n* M/Chip transaction result:");
878 // 9F27: Cryptogram Information Data (CID)
879 const struct tlv
*CID
= tlvdb_get(tlvRoot
, 0x9F27, NULL
);
881 emv_tag_dump(CID
, stdout
, 0);
882 PrintAndLog("------------------------------");
884 switch(CID
->value
[0] & EMVAC_AC_MASK
){
886 PrintAndLog("Transaction DECLINED.");
889 PrintAndLog("Transaction approved OFFLINE.");
892 PrintAndLog("Transaction approved ONLINE.");
895 PrintAndLog("ERROR: CID transaction code error %2x", CID
->value
[0] & EMVAC_AC_MASK
);
899 PrintAndLog("ERROR: Wrong CID length %d", CID
->len
);
902 PrintAndLog("ERROR: CID(9F27) not found.");
909 if (AIP
& 0x8000 && TrType
== TT_MSD
) {
910 PrintAndLog("\n--> MSD transaction.");
912 PrintAndLog("* MSD dCVV path. Check dCVV");
914 const struct tlv
*track2
= tlvdb_get(tlvRoot
, 0x57, NULL
);
916 PrintAndLog("Track2: %s", sprint_hex(track2
->value
, track2
->len
));
918 struct tlvdb
*dCVV
= GetdCVVRawFromTrack2(track2
);
919 PrintAndLog("dCVV raw data:");
920 TLVPrintFromTLV(dCVV
);
922 if (GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
) {
923 PrintAndLog("\n* Mastercard calculate UDOL");
926 const struct tlv
*UDOL
= tlvdb_get(tlvRoot
, 0x9F69, NULL
);
927 // UDOL(9F69) default: 9F6A (Unpredictable number) 4 bytes
928 const struct tlv defUDOL
= {
931 .value
= (uint8_t *)"\x9f\x6a\x04",
934 PrintAndLog("Use default UDOL.");
936 struct tlv
*udol_data_tlv
= dol_process(UDOL
? UDOL
: &defUDOL
, tlvRoot
, 0x01); // 0x01 - dummy tag
938 PrintAndLog("ERROR: can't create UDOL TLV.");
942 PrintAndLog("UDOL data[%d]: %s", udol_data_tlv
->len
, sprint_hex(udol_data_tlv
->value
, udol_data_tlv
->len
));
944 PrintAndLog("\n* Mastercard compute cryptographic checksum(UDOL)");
946 res
= MSCComputeCryptoChecksum(true, (uint8_t *)udol_data_tlv
->value
, udol_data_tlv
->len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
);
948 PrintAndLog("ERROR Compute Crypto Checksum. APDU error %4x", sw
);
954 TLVPrintFromBuffer(buf
, len
);
961 PrintAndLog("ERROR MSD: Track2 data not found.");
970 tlvdb_free(tlvSelect
);
973 PrintAndLog("\n* Transaction completed.");
978 int UsageCmdHFEMVScan(void) {
979 PrintAndLog("HELP : Scan EMV card and save it contents to a file. \n");
980 PrintAndLog(" It executes EMV contactless transaction and saves result to a file which can be used for emulation.\n");
981 PrintAndLog("Usage: hf emv scan [-a][-t][-v][-c][-x][-g] <file_name>\n");
982 PrintAndLog(" Options:");
983 PrintAndLog(" -a : show APDU reqests and responses\n");
984 PrintAndLog(" -t : TLV decode results\n");
985 PrintAndLog(" -v : transaction type - qVSDC or M/Chip.\n");
986 PrintAndLog(" -c : transaction type - qVSDC or M/Chip plus CDA (SDAD generation).\n");
987 PrintAndLog(" -x : transaction type - VSDC. For test only. Not a standart behavior.\n");
988 PrintAndLog(" -g : VISA. generate AC from GPO\n");
989 PrintAndLog("By default : transaction type - MSD.\n");
990 PrintAndLog("Samples:");
991 PrintAndLog(" hf emv scan -a -t -> scan MSD transaction mode");
992 PrintAndLog(" hf emv scan -a -t -c -> scan CDA transaction mode");
996 int CmdHFEMVScan(const char *cmd
) {
1002 int CmdHFEMVTest(const char *cmd
) {
1003 return ExecuteCryptoTests(true);
1006 int CmdHelp(const char *Cmd
);
1007 static command_t CommandTable
[] = {
1008 {"help", CmdHelp
, 1, "This help"},
1009 {"exec", CmdHFEMVExec
, 0, "Executes EMV contactless transaction."},
1010 {"pse", CmdHFEMVPPSE
, 0, "Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory."},
1011 {"search", CmdHFEMVSearch
, 0, "Try to select all applets from applets list and print installed applets."},
1012 {"select", CmdHFEMVSelect
, 0, "Select applet."},
1013 // {"scan", CmdHFEMVScan, 0, "Scan EMV card and save it contents to json file for emulator."},
1014 {"test", CmdHFEMVTest
, 0, "Crypto logic test."},
1015 {NULL
, NULL
, 0, NULL
}
1018 int CmdHFEMV(const char *Cmd
) {
1019 CmdsParse(CommandTable
, Cmd
);
1023 int CmdHelp(const char *Cmd
) {
1024 CmdsHelp(CommandTable
);