]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/emv/cmdemv.c
268d9e630d61d7e3669fa4e15706081fe8b6c7ac
   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 int UsageCmdHFEMVSelect(void) { 
  14         PrintAndLog("HELP :  Executes select applet command:\n"); 
  15         PrintAndLog("Usage:  hf emv select [-s][-k][-a][-t] <HEX applet AID>\n"); 
  16         PrintAndLog("  Options:"); 
  17         PrintAndLog("  -s       : select card"); 
  18         PrintAndLog("  -k       : keep field for next command"); 
  19         PrintAndLog("  -a       : show APDU reqests and responses\n"); 
  20         PrintAndLog("  -t       : TLV decode results\n"); 
  21         PrintAndLog("Samples:"); 
  22         PrintAndLog(" hf emv select -s a00000000101 -> select card, select applet"); 
  23         PrintAndLog(" hf emv select -s -t a00000000101 -> select card, select applet, show result in TLV"); 
  27 int CmdHFEMVSelect(const char *cmd
) { 
  28         uint8_t data
[APDU_AID_LEN
] = {0}; 
  30         bool activateField 
= false; 
  31         bool leaveSignalON 
= false; 
  32         bool decodeTLV 
= false; 
  34         if (strlen(cmd
) < 1) { 
  35                 UsageCmdHFEMVSelect(); 
  39         SetAPDULogging(false); 
  42         while(param_getchar(cmd
, cmdp
) != 0x00) { 
  43                 char c 
= param_getchar(cmd
, cmdp
); 
  44                 if ((c 
== '-') && (param_getlength(cmd
, cmdp
) == 2)) 
  45                         switch (param_getchar_indx(cmd
, 1, cmdp
)) { 
  48                                         UsageCmdHFEMVSelect(); 
  67                                         PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd
, 1, cmdp
)); 
  72                         switch(param_gethex_to_eol(cmd
, cmdp
, data
, sizeof(data
), &datalen
)) { 
  74                                 PrintAndLog("Invalid HEX value."); 
  77                                 PrintAndLog("AID too large."); 
  80                                 PrintAndLog("Hex must have even number of digits."); 
  84                         // we get all the hex to end of line with spaces 
  93         uint8_t buf
[APDU_RES_LEN
] = {0}; 
  96         int res 
= EMVSelect(activateField
, leaveSignalON
, data
, datalen
, buf
, sizeof(buf
), &len
, &sw
, NULL
); 
  99                 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw 
>> 8, sw 
& 0xff));  
 105                 TLVPrintFromBuffer(buf
, len
); 
 110 int UsageCmdHFEMVSearch(void) { 
 111         PrintAndLog("HELP :  Tries to select all applets from applet list:\n"); 
 112         PrintAndLog("Usage:  hf emv search [-s][-k][-a][-t]\n"); 
 113         PrintAndLog("  Options:"); 
 114         PrintAndLog("  -s       : select card"); 
 115         PrintAndLog("  -k       : keep field for next command"); 
 116         PrintAndLog("  -a       : show APDU reqests and responses\n"); 
 117         PrintAndLog("  -t       : TLV decode results of selected applets\n"); 
 118         PrintAndLog("Samples:"); 
 119         PrintAndLog(" hf emv search -s -> select card and search"); 
 120         PrintAndLog(" hf emv search -s -t -> select card, search and show result in TLV"); 
 124 int CmdHFEMVSearch(const char *cmd
) { 
 126         bool activateField 
= false; 
 127         bool leaveSignalON 
= false; 
 128         bool decodeTLV 
= false; 
 130         if (strlen(cmd
) < 1) { 
 131                 UsageCmdHFEMVSearch(); 
 135         SetAPDULogging(false); 
 138         while(param_getchar(cmd
, cmdp
) != 0x00) { 
 139                 char c 
= param_getchar(cmd
, cmdp
); 
 140                 if ((c 
== '-') && (param_getlength(cmd
, cmdp
) == 2)) 
 141                         switch (param_getchar_indx(cmd
, 1, cmdp
)) { 
 144                                         UsageCmdHFEMVSearch(); 
 148                                         activateField 
= true; 
 152                                         leaveSignalON 
= true; 
 156                                         SetAPDULogging(true); 
 163                                         PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd
, 1, cmdp
)); 
 169         struct tlvdb 
*t 
= NULL
; 
 170         const char *al 
= "Applets list"; 
 171         t 
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
); 
 173         if (EMVSearch(activateField
, leaveSignalON
, decodeTLV
, t
)) { 
 178         PrintAndLog("Search completed."); 
 182                 TLVPrintAIDlistFromSelectTLV(t
); 
 190 int UsageCmdHFEMVPPSE(void) { 
 191         PrintAndLog("HELP :  Executes PSE/PPSE select command. It returns list of applet on the card:\n"); 
 192         PrintAndLog("Usage:  hf emv pse [-s][-k][-1][-2][-a][-t]\n"); 
 193         PrintAndLog("  Options:"); 
 194         PrintAndLog("  -s       : select card"); 
 195         PrintAndLog("  -k       : keep field for next command"); 
 196         PrintAndLog("  -1       : ppse (1PAY.SYS.DDF01)"); 
 197         PrintAndLog("  -2       : pse (2PAY.SYS.DDF01)"); 
 198         PrintAndLog("  -a       : show APDU reqests and responses\n"); 
 199         PrintAndLog("  -t       : TLV decode results\n"); 
 200         PrintAndLog("Samples:"); 
 201         PrintAndLog(" hf emv pse -s -1 -> select, get pse"); 
 202         PrintAndLog(" hf emv pse -s -k -2 -> select, get ppse, keep field"); 
 203         PrintAndLog(" hf emv pse -s -t -2 -> select, get ppse, show result in TLV"); 
 207 int CmdHFEMVPPSE(const char *cmd
) { 
 210         bool activateField 
= false; 
 211         bool leaveSignalON 
= false; 
 212         bool decodeTLV 
= false; 
 214         if (strlen(cmd
) < 1) { 
 219         SetAPDULogging(false); 
 222         while(param_getchar(cmd
, cmdp
) != 0x00) { 
 223                 char c 
= param_getchar(cmd
, cmdp
); 
 224                 if ((c 
== '-') && (param_getlength(cmd
, cmdp
) == 2)) 
 225                         switch (param_getchar_indx(cmd
, 1, cmdp
)) { 
 232                                         activateField 
= true; 
 236                                         leaveSignalON 
= true; 
 240                                         SetAPDULogging(true); 
 253                                         PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd
, 1, cmdp
)); 
 260         uint8_t buf
[APDU_RES_LEN
] = {0}; 
 263         int res 
= EMVSelectPSE(activateField
, leaveSignalON
, PSENum
, buf
, sizeof(buf
), &len
, &sw
); 
 266                 PrintAndLog("APDU response status: %04x - %s", sw
, GetAPDUCodeDescription(sw 
>> 8, sw 
& 0xff));  
 273                 TLVPrintFromBuffer(buf
, len
); 
 278 int UsageCmdHFEMVExec(void) { 
 279         PrintAndLog("HELP :  Executes EMV contactless transaction:\n"); 
 280         PrintAndLog("Usage:  hf emv exec [-s][-a][-t]\n"); 
 281         PrintAndLog("  Options:"); 
 282         PrintAndLog("  -s       : select card"); 
 283         PrintAndLog("  -a       : show APDU reqests and responses\n"); 
 284         PrintAndLog("  -t       : TLV decode results\n"); 
 285         PrintAndLog("  -f       : force search AID. Search AID instead of execute PPSE.\n"); 
 286         PrintAndLog("  -v       : transaction type - qVSDC or M/Chip.\n"); 
 287         PrintAndLog("  -c       : transaction type - qVSDC or M/Chip plus CDA (SDAD generation).\n"); 
 288         PrintAndLog("  -x       : transaction type - VSDC. For test only. Not a standart behavior.\n"); 
 289         PrintAndLog("By default : transaction type - MSD.\n"); 
 290         PrintAndLog("Samples:"); 
 291         PrintAndLog(" hf emv pse -s -> select card"); 
 292         PrintAndLog(" hf emv pse -s -t -a -> select card, show responses in TLV, show APDU"); 
 296 #define TLV_ADD(tag, value)( tlvdb_add(tlvRoot, tlvdb_fixed(tag, sizeof(value) - 1, (const unsigned char *)value)) ) 
 298 int CmdHFEMVExec(const char *cmd
) { 
 299         bool activateField 
= false; 
 300         bool showAPDU 
= false; 
 301         bool decodeTLV 
= false; 
 302         bool forceSearch 
= false; 
 303         enum TransactionType TrType 
= TT_MSD
; 
 305         uint8_t buf
[APDU_RES_LEN
] = {0}; 
 308         uint8_t AID
[APDU_AID_LEN
] = {0}; 
 313         if (strlen(cmd
) < 1) { 
 319         while(param_getchar(cmd
, cmdp
) != 0x00) { 
 320                 char c 
= param_getchar(cmd
, cmdp
); 
 321                 if ((c 
== '-') && (param_getlength(cmd
, cmdp
) == 2)) 
 322                         switch (param_getchar_indx(cmd
, 1, cmdp
)) { 
 329                                         activateField 
= true; 
 349                                         TrType 
= TT_QVSDCMCHIP
; 
 356                                         PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd
, 1, cmdp
)); 
 363         // init applets list tree 
 364         struct tlvdb 
*tlvSelect 
= NULL
; 
 365         const char *al 
= "Applets list"; 
 366         tlvSelect 
= tlvdb_fixed(1, strlen(al
), (const unsigned char *)al
); 
 368         // Application Selection 
 369         // https://www.openscdp.org/scripts/tutorial/emv/applicationselection.html 
 372                 PrintAndLog("\n* PPSE."); 
 373                 SetAPDULogging(showAPDU
); 
 374                 res 
= EMVSearchPSE(activateField
, true, decodeTLV
, tlvSelect
); 
 376                 // check PPSE and select application id 
 378                         TLVPrintAIDlistFromSelectTLV(tlvSelect
); 
 379                         EMVSelectApplication(tlvSelect
, AID
, &AIDlen
); 
 385                 PrintAndLog("\n* Search AID in list."); 
 386                 SetAPDULogging(false); 
 387                 if (EMVSearch(activateField
, true, decodeTLV
, tlvSelect
)) { 
 388                         tlvdb_free(tlvSelect
); 
 392                 // check search and select application id 
 393                 TLVPrintAIDlistFromSelectTLV(tlvSelect
); 
 394                 EMVSelectApplication(tlvSelect
, AID
, &AIDlen
); 
 398         struct tlvdb 
*tlvRoot 
= NULL
; 
 399         const char *alr 
= "Root terminal TLV tree"; 
 400         tlvRoot 
= tlvdb_fixed(1, strlen(alr
), (const unsigned char *)alr
); 
 402         // check if we found EMV application on card 
 404                 PrintAndLog("Can't select AID. EMV AID not found"); 
 409         PrintAndLog("\n* Selecting AID:%s", sprint_hex_inrow(AID
, AIDlen
)); 
 410         SetAPDULogging(showAPDU
); 
 411         res 
= EMVSelect(false, true, AID
, AIDlen
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
); 
 414                 PrintAndLog("Can't select AID (%d). Exit...", res
); 
 419                 TLVPrintFromBuffer(buf
, len
); 
 420         PrintAndLog("* Selected."); 
 422         PrintAndLog("\n* Init transaction parameters."); 
 424     //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4 
 427                         TLV_ADD(0x9F66, "\x86\x00\x00\x00"); // MSD 
 429                 // not standart for contactless. just for test. 
 431                         TLV_ADD(0x9F66, "\x46\x00\x00\x00"); // VSDC 
 434                         TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC 
 437                         TLV_ADD(0x9F66, "\x86\x80\x00\x00"); // CDA 
 440                         TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC 
 443     //9F02:(Amount, Authorised (Numeric)) len:6 
 444         TLV_ADD(0x9F02, "\x00\x00\x00\x00\x01\x00"); 
 445     //9F1A:(Terminal Country Code) len:2 
 446         TLV_ADD(0x9F1A, "ru"); 
 447     //5F2A:(Transaction Currency Code) len:2 
 448     // USD 840, EUR 978, RUR 810, RUB 643, RUR 810(old), UAH 980, AZN 031, n/a 999 
 449         TLV_ADD(0x5F2A, "\x09\x80"); 
 450     //9A:(Transaction Date) len:3 
 451         TLV_ADD(0x9A,   "\x00\x00\x00"); 
 452     //9C:(Transaction Type) len:1   |  00 => Goods and service #01 => Cash 
 453         TLV_ADD(0x9C,   "\x00"); 
 454         // 9F37 Unpredictable Number len:4 
 455         TLV_ADD(0x9F37, "\x01\x02\x03\x04"); 
 456         // 9F6A Unpredictable Number (MSD for UDOL) len:4 
 457         TLV_ADD(0x9F6A, "\x01\x02\x03\x04"); 
 459         TLVPrintFromTLV(tlvRoot
); // TODO delete!!! 
 461         PrintAndLog("\n* Calc PDOL."); 
 462         struct tlv 
*pdol_data_tlv 
= dol_process(tlvdb_get(tlvRoot
, 0x9f38, NULL
), tlvRoot
, 0x83); 
 464                 PrintAndLog("ERROR: can't create PDOL TLV."); 
 468         size_t pdol_data_tlv_data_len
; 
 469         unsigned char *pdol_data_tlv_data 
= tlv_encode(pdol_data_tlv
, &pdol_data_tlv_data_len
); 
 470         if (!pdol_data_tlv_data
) { 
 471                 PrintAndLog("ERROR: can't create PDOL data."); 
 474         PrintAndLog("PDOL data[%d]: %s", pdol_data_tlv_data_len
, sprint_hex(pdol_data_tlv_data
, pdol_data_tlv_data_len
)); 
 476         PrintAndLog("\n* GPO."); 
 477         res 
= EMVGPO(true, pdol_data_tlv_data
, pdol_data_tlv_data_len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
); 
 479         free(pdol_data_tlv_data
); 
 483                 PrintAndLog("GPO error(%d): %4x. Exit...", res
, sw
); 
 487         // process response template format 1 [id:80  2b AIP + x4b AFL] and format 2 [id:77 TLV] 
 488         if (buf
[0] == 0x80) { 
 490                         PrintAndLog("GPO response format1:"); 
 491                         TLVPrintFromBuffer(buf
, len
); 
 494                 if (len 
< 4 || (len 
- 4) % 4) { 
 495                         PrintAndLog("ERROR: GPO response format1 parsing error. length=%d", len
); 
 498                         struct tlvdb 
* f1AIP 
= tlvdb_fixed(0x82, 2, buf 
+ 2); 
 499                         tlvdb_add(tlvRoot
, f1AIP
); 
 501                                 PrintAndLog("\n* * Decode response format 1 (0x80) AIP and AFL:"); 
 502                                 TLVPrintFromTLV(f1AIP
); 
 506                         struct tlvdb 
* f1AFL 
= tlvdb_fixed(0x94, len 
- 4, buf 
+ 2 + 2); 
 507                         tlvdb_add(tlvRoot
, f1AFL
); 
 509                                 TLVPrintFromTLV(f1AFL
); 
 513                         TLVPrintFromBuffer(buf
, len
); 
 516         // extract PAN from track2 
 518                 const struct tlv 
*track2 
= tlvdb_get(tlvRoot
, 0x57, NULL
); 
 519                 if (!tlvdb_get(tlvRoot
, 0x5a, NULL
) && track2 
&& track2
->len 
>= 8) { 
 520                         struct tlvdb 
*pan 
= GetPANFromTrack2(track2
); 
 522                                 tlvdb_add(tlvRoot
, pan
);  
 524                                 const struct tlv 
*pantlv 
= tlvdb_get(tlvRoot
, 0x5a, NULL
);       
 525                                 PrintAndLog("\n* * Extracted PAN from track2: %s", sprint_hex(pantlv
->value
, pantlv
->len
)); 
 527                                 PrintAndLog("\n* * WARNING: Can't extract PAN from track2."); 
 532         PrintAndLog("\n* Read records from AFL."); 
 533         const struct tlv 
*AFL 
= tlvdb_get(tlvRoot
, 0x94, NULL
); 
 534         if (!AFL 
|| !AFL
->len
) { 
 535                 PrintAndLog("WARNING: AFL not found."); 
 538         while(AFL 
&& AFL
->len
) { 
 540                         PrintAndLog("ERROR: Wrong AFL length: %d", AFL
->len
); 
 544                 for (int i 
= 0; i 
< AFL
->len 
/ 4; i
++) { 
 545                         uint8_t SFI 
= AFL
->value
[i 
* 4 + 0] >> 3; 
 546                         uint8_t SFIstart 
= AFL
->value
[i 
* 4 + 1]; 
 547                         uint8_t SFIend 
= AFL
->value
[i 
* 4 + 2]; 
 548                         uint8_t SFIoffline 
= AFL
->value
[i 
* 4 + 3]; 
 550                         PrintAndLog("* * SFI[%02x] start:%02x end:%02x offline:%02x", SFI
, SFIstart
, SFIend
, SFIoffline
); 
 551                         if (SFI 
== 0 || SFI 
== 31 || SFIstart 
== 0 || SFIstart 
> SFIend
) { 
 552                                 PrintAndLog("SFI ERROR! Skipped..."); 
 556                         for(int n 
= SFIstart
; n 
<= SFIend
; n
++) { 
 557                                 PrintAndLog("* * * SFI[%02x] %d", SFI
, n
); 
 559                                 res 
= EMVReadRecord(true, SFI
, n
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
); 
 561                                         PrintAndLog("ERROR SFI[%02x]. APDU error %4x", SFI
, sw
); 
 566                                         TLVPrintFromBuffer(buf
, len
); 
 571                                         // here will be offline records storing... 
 572                                         // dont foget: if (sfi < 11) 
 581         const struct tlv 
*AIPtlv 
= tlvdb_get(tlvRoot
, 0x82, NULL
);       
 582         uint16_t AIP 
= AIPtlv
->value
[0] + AIPtlv
->value
[1] * 0x100; 
 583         PrintAndLog("* * AIP=%04x", AIP
); 
 587                 PrintAndLog("\n* SDA"); 
 588                 trSDA(AID
, AIDlen
, tlvRoot
); 
 593                 PrintAndLog("\n* DDA"); 
 600         if (TrType 
== TT_QVSDCMCHIP
|| TrType 
== TT_CDA
){ 
 601                 // 9F26: Application Cryptogram 
 602                 const struct tlv 
*AC 
= tlvdb_get(tlvRoot
, 0x9F26, NULL
); 
 604                         PrintAndLog("\n--> qVSDC transaction."); 
 605                         PrintAndLog("* AC path"); 
 607                         // 9F36: Application Transaction Counter (ATC) 
 608                         const struct tlv 
*ATC 
= tlvdb_get(tlvRoot
, 0x9F36, NULL
); 
 611                                 // 9F10: Issuer Application Data - optional 
 612                                 const struct tlv 
*IAD 
= tlvdb_get(tlvRoot
, 0x9F10, NULL
); 
 615                                 PrintAndLog("ATC: %s", sprint_hex(ATC
->value
, ATC
->len
)); 
 616                                 PrintAndLog("AC: %s", sprint_hex(AC
->value
, AC
->len
)); 
 618                                         PrintAndLog("IAD: %s", sprint_hex(IAD
->value
, IAD
->len
)); 
 620                                         if (IAD
->len 
>= IAD
->value
[0] + 1) { 
 621                                                 PrintAndLog("\tKey index:  0x%02x", IAD
->value
[1]); 
 622                                                 PrintAndLog("\tCrypto ver: 0x%02x(%03d)", IAD
->value
[2], IAD
->value
[2]); 
 623                                                 PrintAndLog("\tCVR:", sprint_hex(&IAD
->value
[3], IAD
->value
[0] - 2)); 
 624                                                 struct tlvdb 
* cvr 
= tlvdb_fixed(0x20, IAD
->value
[0] - 2, &IAD
->value
[3]); 
 625                                                 TLVPrintFromTLVLev(cvr
, 1); 
 628                                         PrintAndLog("WARNING: IAD not found."); 
 632                                 PrintAndLog("ERROR AC: Application Transaction Counter (ATC) not found."); 
 638         if (GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD 
&& (TrType 
== TT_QVSDCMCHIP 
|| TrType 
== TT_CDA
)){ 
 639                 const struct tlv 
*CDOL1 
= tlvdb_get(tlvRoot
, 0x8c, NULL
); 
 640                 if (CDOL1 
&& GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
) { // and m/chip transaction flag 
 641                         PrintAndLog("\n--> Mastercard M/Chip transaction."); 
 643                         PrintAndLog("* * Generate challenge"); 
 644                         res 
= EMVGenerateChallenge(true, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
); 
 646                                 PrintAndLog("ERROR GetChallenge. APDU error %4x", sw
); 
 650                                 PrintAndLog("ERROR GetChallenge. Wrong challenge length %d", len
); 
 654                         // ICC Dynamic Number 
 655                         struct tlvdb 
* ICCDynN 
= tlvdb_fixed(0x9f4c, len
, buf
); 
 656                         tlvdb_add(tlvRoot
, ICCDynN
); 
 658                                 PrintAndLog("\n* * ICC Dynamic Number:"); 
 659                                 TLVPrintFromTLV(ICCDynN
); 
 662                         PrintAndLog("* * Calc CDOL1"); 
 663                         struct tlv 
*cdol_data_tlv 
= dol_process(tlvdb_get(tlvRoot
, 0x8c, NULL
), tlvRoot
, 0x01); // 0x01 - dummy tag 
 665                                 PrintAndLog("ERROR: can't create CDOL1 TLV."); 
 668                         PrintAndLog("CDOL1 data[%d]: %s", cdol_data_tlv
->len
, sprint_hex(cdol_data_tlv
->value
, cdol_data_tlv
->len
)); 
 670                         PrintAndLog("* * AC1"); 
 671                         // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD 
 672                         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
); 
 677                                 PrintAndLog("AC1 error(%d): %4x. Exit...", res
, sw
); 
 682                                 TLVPrintFromBuffer(buf
, len
); 
 684                         PrintAndLog("* M/Chip transaction result:"); 
 685                         // 9F27: Cryptogram Information Data (CID) 
 686                         const struct tlv 
*CID 
= tlvdb_get(tlvRoot
, 0x9F27, NULL
); 
 688                                 emv_tag_dump(CID
, stdout
, 0); 
 689                                 PrintAndLog("------------------------------"); 
 691                                         switch(CID
->value
[0] & EMVAC_AC_MASK
){ 
 693                                                         PrintAndLog("Transaction DECLINED."); 
 696                                                         PrintAndLog("Transaction approved OFFLINE."); 
 699                                                         PrintAndLog("Transaction approved ONLINE."); 
 702                                                         PrintAndLog("ERROR: CID transaction code error %2x", CID
->value
[0] & EMVAC_AC_MASK
); 
 706                                         PrintAndLog("ERROR: Wrong CID length %d", CID
->len
); 
 709                                 PrintAndLog("ERROR: CID(9F27) not found."); 
 716         if (AIP 
& 0x8000 && TrType 
== TT_MSD
) {  
 717                 PrintAndLog("\n--> MSD transaction."); 
 719                 PrintAndLog("* MSD dCVV path. Check dCVV"); 
 721                 const struct tlv 
*track2 
= tlvdb_get(tlvRoot
, 0x57, NULL
); 
 723                         PrintAndLog("Track2: %s", sprint_hex(track2
->value
, track2
->len
)); 
 725                         struct tlvdb 
*dCVV 
= GetdCVVRawFromTrack2(track2
); 
 726                         PrintAndLog("dCVV raw data:"); 
 727                         TLVPrintFromTLV(dCVV
); 
 729                         if (GetCardPSVendor(AID
, AIDlen
) == CV_MASTERCARD
) { 
 730                                 PrintAndLog("\n* Mastercard calculate UDOL"); 
 733                                 const struct tlv 
*UDOL 
= tlvdb_get(tlvRoot
, 0x9F69, NULL
); 
 734                                 // UDOL(9F69) default: 9F6A (Unpredictable number) 4 bytes 
 735                                 const struct tlv defUDOL 
= { 
 738                                         .value 
= (uint8_t *)"\x9f\x6a\x04", 
 741                                         PrintAndLog("Use default UDOL."); 
 743                                 struct tlv 
*udol_data_tlv 
= dol_process(UDOL 
? UDOL 
: &defUDOL
, tlvRoot
, 0x01); // 0x01 - dummy tag 
 745                                         PrintAndLog("ERROR: can't create UDOL TLV."); 
 749                                 PrintAndLog("UDOL data[%d]: %s", udol_data_tlv
->len
, sprint_hex(udol_data_tlv
->value
, udol_data_tlv
->len
)); 
 751                                 PrintAndLog("\n* Mastercard compute cryptographic checksum(UDOL)"); 
 753                                 res 
= MSCComputeCryptoChecksum(true, (uint8_t *)udol_data_tlv
->value
, udol_data_tlv
->len
, buf
, sizeof(buf
), &len
, &sw
, tlvRoot
); 
 755                                         PrintAndLog("ERROR Compute Crypto Checksum. APDU error %4x", sw
); 
 760                                         TLVPrintFromBuffer(buf
, len
); 
 766                         PrintAndLog("ERROR MSD: Track2 data not found."); 
 774         tlvdb_free(tlvSelect
); 
 777         PrintAndLog("\n* Transaction completed."); 
 782 int CmdHelp(const char *Cmd
); 
 783 static command_t CommandTable
[] =  { 
 784         {"help",        CmdHelp
,                1,      "This help"}, 
 785         {"exec",        CmdHFEMVExec
,   0,      "Executes EMV contactless transaction."}, 
 786         {"pse",         CmdHFEMVPPSE
,   0,      "Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory."}, 
 787         {"search",      CmdHFEMVSearch
, 0,      "Try to select all applets from applets list and print installed applets."}, 
 788         {"select",      CmdHFEMVSelect
, 0,      "Select applet."}, 
 789         {NULL
, NULL
, 0, NULL
} 
 792 int CmdHFEMV(const char *Cmd
) { 
 793         CmdsParse(CommandTable
, Cmd
); 
 797 int CmdHelp(const char *Cmd
) { 
 798         CmdsHelp(CommandTable
);