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 "util_posix.h"
14 #include "protocols.h"
16 #include "cmdsmartcard.h"
19 // Got from here. Thanks)
20 // https://eftlab.co.uk/index.php/site-map/knowledge-base/211-emv-aid-rid-pix
21 static const char *PSElist
[] = {
22 "325041592E5359532E4444463031", // 2PAY.SYS.DDF01 - Visa Proximity Payment System Environment - PPSE
23 "315041592E5359532E4444463031" // 1PAY.SYS.DDF01 - Visa Payment System Environment - PSE
25 //static const size_t PSElistLen = sizeof(PSElist)/sizeof(char*);
27 char *TransactionTypeStr
[] = {
35 enum CardPSVendor vendor
;
39 static const TAIDList AIDlist
[] = {
41 { CV_VISA
, "A00000000305076010"}, // VISA ELO Credit
42 { CV_VISA
, "A0000000031010" }, // VISA Debit/Credit (Classic)
43 { CV_VISA
, "A000000003101001" }, // VISA Credit
44 { CV_VISA
, "A000000003101002" }, // VISA Debit
45 { CV_VISA
, "A0000000032010" }, // VISA Electron
46 { CV_VISA
, "A0000000032020" }, // VISA
47 { CV_VISA
, "A0000000033010" }, // VISA Interlink
48 { CV_VISA
, "A0000000034010" }, // VISA Specific
49 { CV_VISA
, "A0000000035010" }, // VISA Specific
50 { CV_VISA
, "A0000000036010" }, // Domestic Visa Cash Stored Value
51 { CV_VISA
, "A0000000036020" }, // International Visa Cash Stored Value
52 { CV_VISA
, "A0000000038002" }, // VISA Auth, VisaRemAuthen EMV-CAP (DPA)
53 { CV_VISA
, "A0000000038010" }, // VISA Plus
54 { CV_VISA
, "A0000000039010" }, // VISA Loyalty
55 { CV_VISA
, "A000000003999910" }, // VISA Proprietary ATM
57 { CV_VISA
, "A000000098" }, // Debit Card
58 { CV_VISA
, "A0000000980848" }, // Debit Card
59 // Mastercard International
60 { CV_MASTERCARD
, "A00000000401" }, // MasterCard PayPass
61 { CV_MASTERCARD
, "A0000000041010" }, // MasterCard Credit
62 { CV_MASTERCARD
, "A00000000410101213" }, // MasterCard Credit
63 { CV_MASTERCARD
, "A00000000410101215" }, // MasterCard Credit
64 { CV_MASTERCARD
, "A0000000042010" }, // MasterCard Specific
65 { CV_MASTERCARD
, "A0000000043010" }, // MasterCard Specific
66 { CV_MASTERCARD
, "A0000000043060" }, // Maestro (Debit)
67 { CV_MASTERCARD
, "A000000004306001" }, // Maestro (Debit)
68 { CV_MASTERCARD
, "A0000000044010" }, // MasterCard Specific
69 { CV_MASTERCARD
, "A0000000045010" }, // MasterCard Specific
70 { CV_MASTERCARD
, "A0000000046000" }, // Cirrus
71 { CV_MASTERCARD
, "A0000000048002" }, // SecureCode Auth EMV-CAP
72 { CV_MASTERCARD
, "A0000000049999" }, // MasterCard PayPass
73 { CV_MASTERCARD
, "B012345678" }, // Maestro TEST Used for development
75 { CV_AMERICANEXPRESS
, "A000000025" },
76 { CV_AMERICANEXPRESS
, "A0000000250000" },
77 { CV_AMERICANEXPRESS
, "A00000002501" },
78 { CV_AMERICANEXPRESS
, "A000000025010402" },
79 { CV_AMERICANEXPRESS
, "A000000025010701" },
80 { CV_AMERICANEXPRESS
, "A000000025010801" },
81 // Groupement des Cartes Bancaires "CB"
82 { CV_CB
, "A0000000421010" }, // Cartes Bancaire EMV Card
83 { CV_CB
, "A0000000422010" },
84 { CV_CB
, "A0000000423010" },
85 { CV_CB
, "A0000000424010" },
86 { CV_CB
, "A0000000425010" },
88 { CV_JCB
, "A00000006510" }, // JCB
89 { CV_JCB
, "A0000000651010" }, // JCB J Smart Credit
90 // Switch Card Services Ltd.
91 { CV_SWITCH
, "A0000000050001" }, // Maestro UK
92 { CV_SWITCH
, "A0000000050002" }, // Solo
93 // Diners Club International Ltd.
94 { CV_DINERS
, "A0000001523010" }, // Discover, Pulse D Pas Discover Card
95 { CV_DINERS
, "A0000001524010" }, // Discover, Discover Debit Common Card
97 { CV_OTHER
, "A00000002401" }, // Midland Bank Plc - Self Service
98 { CV_OTHER
, "A0000000291010" }, // LINK Interchange Network Ltd - Link / American Express
99 { CV_OTHER
, "A00000006900" }, // Société Européenne de Monnaie Electronique SEME - Moneo
100 { CV_OTHER
, "A000000077010000021000000000003B" }, // Oberthur Technologies France - Visa AEPN
101 { CV_OTHER
, "A0000001211010" }, // PBS Danmark A/S - Denmark - Dankort (VISA GEM Vision) - Danish domestic debit card
102 { CV_OTHER
, "A0000001410001" }, // Associazione Bancaria Italiana - Italy - PagoBANCOMAT - CoGeBan Consorzio BANCOMAT (Italian domestic debit card)
103 { CV_OTHER
, "A0000001544442" }, // Banricompras Debito - Banrisul - Banco do Estado do Rio Grande do SUL - S.A.
104 { CV_OTHER
, "A000000172950001" }, // Financial Information Service Co. Ltd. - Taiwan - BAROC Financial Application Taiwan- The Bankers Association of the Republic of China
105 { CV_OTHER
, "A0000001850002" }, // Post Office Limited - United Kingdom - UK Post Office Account card
106 { CV_OTHER
, "A0000002281010" }, // Saudi Arabian Monetary Agency (SAMA) - Kingdom of Saudi Arabia - SPAN (M/Chip) - SPAN2 (Saudi Payments Network) - Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)
107 { CV_OTHER
, "A0000002282010" }, // Saudi Arabian Monetary Agency (SAMA) - Kingdom of Saudi Arabia - SPAN (VIS) - SPAN2 (Saudi Payments Network) - Saudi Arabia domestic credit/debit card (Saudi Arabia Monetary Agency)
108 { CV_OTHER
, "A0000002771010" }, // Interac Association - Canada - INTERAC - Canadian domestic credit/debit card
109 { CV_OTHER
, "A00000031510100528" }, // Currence Holding/PIN BV - The Netherlands- Currence PuC
110 { CV_OTHER
, "A0000003156020" }, // Currence Holding/PIN BV - The Netherlands - Chipknip
111 { CV_OTHER
, "A0000003591010028001" }, // Euro Alliance of Payment Schemes s.c.r.l. (EAPS) - Belgium - Girocard EAPS - ZKA (Germany)
112 { CV_OTHER
, "A0000003710001" }, // Verve - Nigeria - InterSwitch Verve Card - Nigerian local switch company
113 { CV_OTHER
, "A0000004540010" }, // eTranzact - Nigeria - Etranzact Genesis Card - Nigerian local switch company
114 { CV_OTHER
, "A0000004540011" }, // eTranzact - Nigeria - Etranzact Genesis Card 2 - Nigerian local switch company
115 { CV_OTHER
, "A0000004766C" }, // Google - United States - GOOGLE_PAYMENT_AID
116 { CV_OTHER
, "A0000005241010" }, // RuPay - India - RuPay - RuPay (India)
117 { CV_OTHER
, "A0000006723010" }, // TROY - Turkey - TROY chip credit card - Turkey's Payment Method
118 { CV_OTHER
, "A0000006723020" }, // TROY - Turkey - TROY chip debit card - Turkey's Payment Method
119 { CV_OTHER
, "A0000007705850" }, // Indian Oil Corporation Limited - India - XTRAPOWER Fleet Card Program - Indian Oil’s Pre Paid Program
120 { CV_OTHER
, "D27600002545500100" }, // ZKA - Germany - Girocard - ZKA Girocard (Geldkarte) (Germany)
121 { CV_OTHER
, "D5280050218002" }, // The Netherlands - ? - (Netherlands)
122 { CV_OTHER
, "D5780000021010" }, // Bankaxept Norway Bankaxept Norwegian domestic debit card
123 { CV_OTHER
, "F0000000030001" }, // BRADESCO - Brazilian Bank Banco Bradesco
125 static const size_t AIDlistLen
= sizeof(AIDlist
)/sizeof(TAIDList
);
127 static bool APDULogging
= false;
128 void SetAPDULogging(bool logging
) {
129 APDULogging
= logging
;
132 enum CardPSVendor
GetCardPSVendor(uint8_t * AID
, size_t AIDlen
) {
137 hex_to_buffer((uint8_t *)buf
, AID
, AIDlen
, sizeof(buf
) - 1, 0, 0, true);
139 for(int i
= 0; i
< AIDlistLen
; i
++) {
140 if (strncmp(AIDlist
[i
].aid
, buf
, strlen(AIDlist
[i
].aid
)) == 0){
141 return AIDlist
[i
].vendor
;
148 static bool print_cb(void *data
, const struct tlv
*tlv
, int level
, bool is_leaf
) {
149 emv_tag_dump(tlv
, stdout
, level
);
151 dump_buffer(tlv
->value
, tlv
->len
, stdout
, level
);
157 bool TLVPrintFromBuffer(uint8_t *data
, int datalen
) {
158 struct tlvdb
*t
= NULL
;
159 t
= tlvdb_parse_multi(data
, datalen
);
161 PrintAndLogEx(NORMAL
, "-------------------- TLV decoded --------------------");
163 tlvdb_visit(t
, print_cb
, NULL
, 0);
167 PrintAndLogEx(WARNING
, "TLV ERROR: Can't parse response as TLV tree.");
172 void TLVPrintFromTLVLev(struct tlvdb
*tlv
, int level
) {
176 tlvdb_visit(tlv
, print_cb
, NULL
, level
);
179 void TLVPrintFromTLV(struct tlvdb
*tlv
) {
180 TLVPrintFromTLVLev(tlv
, 0);
183 void TLVPrintAIDlistFromSelectTLV(struct tlvdb
*tlv
) {
184 PrintAndLogEx(NORMAL
, "|------------------|--------|-------------------------|");
185 PrintAndLogEx(NORMAL
, "| AID |Priority| Name |");
186 PrintAndLogEx(NORMAL
, "|------------------|--------|-------------------------|");
188 struct tlvdb
*ttmp
= tlvdb_find(tlv
, 0x6f);
190 PrintAndLogEx(NORMAL
, "| none |");
193 const struct tlv
*tgAID
= tlvdb_get_inchild(ttmp
, 0x84, NULL
);
194 const struct tlv
*tgName
= tlvdb_get_inchild(ttmp
, 0x50, NULL
);
195 const struct tlv
*tgPrio
= tlvdb_get_inchild(ttmp
, 0x87, NULL
);
198 PrintAndLogEx(NORMAL
, "|%s| %s |%s|",
199 sprint_hex_inrow_ex(tgAID
->value
, tgAID
->len
, 18),
200 (tgPrio
) ? sprint_hex(tgPrio
->value
, 1) : " ",
201 (tgName
) ? sprint_ascii_ex(tgName
->value
, tgName
->len
, 25) : " ");
203 ttmp
= tlvdb_find_next(ttmp
, 0x6f);
206 PrintAndLogEx(NORMAL
, "|------------------|--------|-------------------------|");
209 struct tlvdb
*GetPANFromTrack2(const struct tlv
*track2
) {
210 char track2Hex
[200] = {0};
211 uint8_t PAN
[100] = {0};
213 char *tmp
= track2Hex
;
218 for (int i
= 0; i
< track2
->len
; ++i
, tmp
+= 2)
219 sprintf(tmp
, "%02x", (unsigned int)track2
->value
[i
]);
221 int posD
= strchr(track2Hex
, 'd') - track2Hex
;
226 if (strlen(track2Hex
) % 2) {
227 track2Hex
[posD
] = 'F';
228 track2Hex
[posD
+ 1] = '\0';
231 param_gethex_to_eol(track2Hex
, 0, PAN
, sizeof(PAN
), &PANlen
);
233 return tlvdb_fixed(0x5a, PANlen
, PAN
);
236 struct tlvdb
*GetdCVVRawFromTrack2(const struct tlv
*track2
) {
237 char track2Hex
[200] = {0};
238 char dCVVHex
[100] = {0};
239 uint8_t dCVV
[100] = {0};
241 const int PINlen
= 5; // must calculated from 9F67 MSD Offset but i have not seen this tag)
242 char *tmp
= track2Hex
;
247 for (int i
= 0; i
< track2
->len
; ++i
, tmp
+= 2)
248 sprintf(tmp
, "%02x", (unsigned int)track2
->value
[i
]);
250 int posD
= strchr(track2Hex
, 'd') - track2Hex
;
254 memset(dCVVHex
, '0', 32);
256 memcpy(dCVVHex
+ 0, track2Hex
+ posD
+ PINlen
+ 11, 4);
258 memcpy(dCVVHex
+ 4, track2Hex
, 5);
260 memcpy(dCVVHex
+ 9, track2Hex
+ posD
+ 1, 4);
262 memcpy(dCVVHex
+ 13, track2Hex
+ posD
+ 5, 3);
264 param_gethex_to_eol(dCVVHex
, 0, dCVV
, sizeof(dCVV
), &dCVVlen
);
266 return tlvdb_fixed(0x02, dCVVlen
, dCVV
);
270 static int EMVExchangeEx(EMVCommandChannel channel
, bool ActivateField
, bool LeaveFieldON
, uint8_t *apdu
, int apdu_len
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
)
277 if (ActivateField
&& channel
== ECC_CONTACTLESS
) {
283 PrintAndLogEx(SUCCESS
, ">>>> %s", sprint_hex(apdu
, apdu_len
));
286 case ECC_CONTACTLESS
:
287 // 6 byes + data = INS + CLA + P1 + P2 + Lc + <data = Nc> + Le(?IncludeLe)
288 res
= ExchangeAPDU14a(apdu
, apdu_len
, ActivateField
, LeaveFieldON
, Result
, (int)MaxResultLen
, (int *)ResultLen
);
294 //int ExchangeAPDUSC(uint8_t *datain, int datainlen, bool activateCard, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen);
295 #ifdef WITH_SMARTCARD
296 res
= ExchangeAPDUSC(apdu
, apdu_len
, ActivateField
, LeaveFieldON
, Result
, (int)MaxResultLen
, (int *)ResultLen
);
305 PrintAndLogEx(SUCCESS
, "<<<< %s", sprint_hex(Result
, *ResultLen
));
307 if (*ResultLen
< 2) {
311 /* if (Result[*ResultLen-2] == 0x61) {
312 uint8_t La = Result[*ResultLen-1];
313 uint8_t get_response[5] = {apdu[0], ISO7816_GET_RESPONSE, 0x00, 0x00, La};
314 return EMVExchangeEx(channel, false, LeaveFieldON, get_response, sizeof(get_response), Result, MaxResultLen, ResultLen, sw, tlv);
318 isw
= Result
[*ResultLen
] * 0x0100 + Result
[*ResultLen
+ 1];
324 PrintAndLogEx(ERR
, "APDU(%02x%02x) ERROR: [%4X] %s", apdu
[0], apdu
[1], isw
, GetAPDUCodeDescription(*sw
>> 8, *sw
& 0xff));
331 struct tlvdb
*t
= tlvdb_parse_multi(Result
, *ResultLen
);
338 int EMVExchange(EMVCommandChannel channel
, bool LeaveFieldON
, uint8_t *apdu
, int apdu_len
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
)
340 uint8_t APDU
[APDU_COMMAND_LEN
];
341 memcpy(APDU
, apdu
, apdu_len
);
342 APDU
[apdu_len
] = 0x00;
343 if (channel
== ECC_CONTACTLESS
) {
344 if (apdu_len
== 5 && apdu
[4] == 0) {
345 // there is no Lc but an Le == 0 already
346 } else if (apdu_len
> 5 && apdu_len
== 5 + apdu
[4] + 1) {
347 // there is Lc, data and Le
350 apdu_len
++; // no Le, add Le = 0x00 because some vendors require it for contactless
353 return EMVExchangeEx(channel
, false, LeaveFieldON
, APDU
, apdu_len
, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
356 int EMVSelect(EMVCommandChannel channel
, bool ActivateField
, bool LeaveFieldON
, uint8_t *AID
, size_t AIDLen
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
)
358 uint8_t Select_APDU
[APDU_COMMAND_LEN
] = {0x00, ISO7816_SELECT_FILE
, 0x04, 0x00, AIDLen
, 0x00};
359 memcpy(Select_APDU
+ 5, AID
, AIDLen
);
360 int apdulen
= 5 + AIDLen
;
361 if (channel
== ECC_CONTACTLESS
) {
362 apdulen
++; // some vendors require Le = 0x00 for contactless operations
364 return EMVExchangeEx(channel
, ActivateField
, LeaveFieldON
, Select_APDU
, apdulen
, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
367 int EMVSelectPSE(EMVCommandChannel channel
, bool ActivateField
, bool LeaveFieldON
, uint8_t PSENum
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
) {
368 uint8_t buf
[APDU_DATA_LEN
] = {0};
374 param_gethex_to_eol(PSElist
[1], 0, buf
, sizeof(buf
), &len
);
378 param_gethex_to_eol(PSElist
[0], 0, buf
, sizeof(buf
), &len
);
385 res
= EMVSelect(channel
, ActivateField
, LeaveFieldON
, buf
, len
, Result
, MaxResultLen
, ResultLen
, sw
, NULL
);
391 int EMVSelectWithRetry(EMVCommandChannel channel
, bool ActivateField
, bool LeaveFieldON
, uint8_t *AID
, size_t AIDLen
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
) {
395 res
= EMVSelect(channel
, false, true, AID
, AIDLen
, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
397 // retry if error and not returned sw error
398 if (res
&& res
!= 5) {
402 // card select error, proxmark error
404 PrintAndLogEx(WARNING
, "Exit...");
409 PrintAndLogEx(NORMAL
, "Retry failed [%s]. Skiped...", sprint_hex_inrow(AID
, AIDLen
));
413 } while (res
&& res
!= 5);
419 int EMVCheckAID(EMVCommandChannel channel
, bool decodeTLV
, struct tlvdb
*tlvdbelm
, struct tlvdb
*tlv
){
420 uint8_t data
[APDU_RESPONSE_LEN
] = {0};
426 const struct tlv
*tgAID
= tlvdb_get_inchild(tlvdbelm
, 0x4f, NULL
);
428 res
= EMVSelectWithRetry(channel
, false, true, (uint8_t *)tgAID
->value
, tgAID
->len
, data
, sizeof(data
), &datalen
, &sw
, tlv
);
430 // if returned sw error
433 tlvdbelm
= tlvdb_find_next(tlvdbelm
, 0x61);
442 PrintAndLogEx(NORMAL
, "%s:", sprint_hex_inrow(tgAID
->value
, tgAID
->len
));
443 TLVPrintFromBuffer(data
, datalen
);
446 tlvdbelm
= tlvdb_find_next(tlvdbelm
, 0x61);
452 int EMVSearchPSE(EMVCommandChannel channel
, bool ActivateField
, bool LeaveFieldON
, uint8_t PSENum
, bool decodeTLV
, struct tlvdb
*tlv
) {
453 uint8_t data
[APDU_RESPONSE_LEN
] = {0};
455 uint8_t sfidata
[0x11][APDU_RESPONSE_LEN
] = {0};
456 size_t sfidatalen
[0x11] = {0};
459 bool fileFound
= false;
461 char *PSE_or_PPSE
= PSENum
== 1 ? "PSE" : "PPSE";
464 res
= EMVSelectPSE(channel
, ActivateField
, true, PSENum
, data
, sizeof(data
), &datalen
, &sw
);
468 PrintAndLogEx(FAILED
, "Select PSE error. APDU error: %04x.", sw
);
472 struct tlvdb
*t
= NULL
;
473 t
= tlvdb_parse_multi(data
, datalen
);
476 struct tlvdb
*tsfi
= tlvdb_find_path(t
, (tlv_tag_t
[]){0x6f, 0xa5, 0x88, 0x00});
479 tlv_get_uint8(tlvdb_get_tlv(tsfi
), &sfin
);
480 PrintAndLogEx(INFO
, "* PPSE get SFI: 0x%02x.", sfin
);
482 for (uint8_t ui
= 0x01; ui
<= 0x10; ui
++) {
483 PrintAndLogEx(INFO
, "* * Get SFI: 0x%02x. num: 0x%02x", sfin
, ui
);
484 res
= EMVReadRecord(channel
, true, sfin
, ui
, sfidata
[ui
], APDU_RESPONSE_LEN
, &sfidatalen
[ui
], &sw
, NULL
);
489 PrintAndLogEx(INFO
, "* * PPSE get SFI. End of records.");
496 PrintAndLogEx(FAILED
, "PPSE get Error. APDU error: %04x.", sw
);
501 TLVPrintFromBuffer(sfidata
[ui
], sfidatalen
[ui
]);
505 for (uint8_t ui
= 0x01; ui
<= 0x10; ui
++) {
506 if (sfidatalen
[ui
]) {
507 struct tlvdb
*tsfi
= NULL
;
508 tsfi
= tlvdb_parse_multi(sfidata
[ui
], sfidatalen
[ui
]);
510 struct tlvdb
*tsfitmp
= tlvdb_find_path(tsfi
, (tlv_tag_t
[]){0x70, 0x61, 0x00});
512 PrintAndLogEx(FAILED
, "SFI 0x%02d doesn't have any records.", sfidatalen
[ui
]);
515 res
= EMVCheckAID(channel
, decodeTLV
, tsfitmp
, tlv
);
524 // PSE/PPSE plain (wo SFI)
525 struct tlvdb
*ttmp
= tlvdb_find_path(t
, (tlv_tag_t
[]){0x6f, 0xa5, 0xbf0c, 0x61, 0x00});
527 res
= EMVCheckAID(channel
, decodeTLV
, ttmp
, tlv
);
532 PrintAndLogEx(FAILED
, "PPSE doesn't have any records.");
536 PrintAndLogEx(WARNING
, "%s ERROR: Can't get TLV from response.", PSE_or_PPSE
);
539 PrintAndLogEx(WARNING
, "%s ERROR: Can't select PPSE AID. Error: %d", PSE_or_PPSE
, res
);
542 if(!LeaveFieldON
&& channel
== ECC_CONTACTLESS
)
548 int EMVSearch(EMVCommandChannel channel
, bool ActivateField
, bool LeaveFieldON
, bool decodeTLV
, struct tlvdb
*tlv
) {
549 uint8_t aidbuf
[APDU_DATA_LEN
] = {0};
551 uint8_t data
[APDU_RESPONSE_LEN
] = {0};
557 for(int i
= 0; i
< AIDlistLen
; i
++) {
558 param_gethex_to_eol(AIDlist
[i
].aid
, 0, aidbuf
, sizeof(aidbuf
), &aidlen
);
559 res
= EMVSelect(channel
, (i
== 0) ? ActivateField
: false, (i
== AIDlistLen
- 1) ? LeaveFieldON
: true, aidbuf
, aidlen
, data
, sizeof(data
), &datalen
, &sw
, tlv
);
560 // retry if error and not returned sw error
561 if (res
&& res
!= 5) {
565 // (1) - card select error, proxmark error OR (200) - result length = 0
566 if (res
== 1 || res
== 200) {
567 PrintAndLogEx(WARNING
, "Exit...");
572 PrintAndLogEx(FAILED
, "Retry failed [%s]. Skipped...", AIDlist
[i
].aid
);
585 PrintAndLogEx(SUCCESS
, "%s", AIDlist
[i
].aid
);
586 TLVPrintFromBuffer(data
, datalen
);
593 int EMVSelectApplication(struct tlvdb
*tlv
, uint8_t *AID
, size_t *AIDlen
) {
594 // check priority. 0x00 - highest
599 struct tlvdb
*ttmp
= tlvdb_find(tlv
, 0x6f);
604 const struct tlv
*tgAID
= tlvdb_get_inchild(ttmp
, 0x84, NULL
);
605 const struct tlv
*tgPrio
= tlvdb_get_inchild(ttmp
, 0x87, NULL
);
611 int pt
= bytes_to_num((uint8_t*)tgPrio
->value
, (tgPrio
->len
< 2) ? tgPrio
->len
: 2);
615 memcpy(AID
, tgAID
->value
, tgAID
->len
);
616 *AIDlen
= tgAID
->len
;
619 // takes the first application from list wo priority
621 memcpy(AID
, tgAID
->value
, tgAID
->len
);
622 *AIDlen
= tgAID
->len
;
626 ttmp
= tlvdb_find_next(ttmp
, 0x6f);
632 int EMVGPO(EMVCommandChannel channel
, bool LeaveFieldON
, uint8_t *PDOL
, size_t PDOLLen
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
)
634 uint8_t GPO_APDU
[APDU_COMMAND_LEN
] = {0x80, 0xa8, 0x00, 0x00, PDOLLen
, 0x00};
635 memcpy(GPO_APDU
+ 5, PDOL
, PDOLLen
);
636 int apdulen
= 5 + PDOLLen
;
638 return EMVExchange(channel
, LeaveFieldON
, GPO_APDU
, apdulen
, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
641 int EMVReadRecord(EMVCommandChannel channel
, bool LeaveFieldON
, uint8_t SFI
, uint8_t SFIrec
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
)
643 uint8_t read_APDU
[5] = {0x00, ISO7816_READ_RECORDS
, SFIrec
, (SFI
<< 3) | 0x04, 0x00};
644 int res
= EMVExchange(channel
, LeaveFieldON
, read_APDU
, sizeof(read_APDU
), Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
646 PrintAndLogEx(INFO
, ">>> trying to reissue command withouth Le...");
647 res
= EMVExchangeEx(channel
, false, LeaveFieldON
, read_APDU
, sizeof(read_APDU
), Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
652 int EMVAC(EMVCommandChannel channel
, bool LeaveFieldON
, uint8_t RefControl
, uint8_t *CDOL
, size_t CDOLLen
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
)
654 uint8_t CDOL_APDU
[APDU_COMMAND_LEN
] = {0x80, 0xae, RefControl
, 0x00, CDOLLen
, 0x00};
655 memcpy(CDOL_APDU
+ 5, CDOL
, CDOLLen
);
656 int apdulen
= 5 + CDOLLen
;
658 return EMVExchange(channel
, LeaveFieldON
, CDOL_APDU
, apdulen
, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
661 int EMVGenerateChallenge(EMVCommandChannel channel
, bool LeaveFieldON
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
)
663 uint8_t get_challenge_APDU
[APDU_COMMAND_LEN
] = {0x00, ISO7816_GET_CHALLENGE
, 0x00, 0x00};
665 int res
= EMVExchange(channel
, LeaveFieldON
, get_challenge_APDU
, 4, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
667 PrintAndLogEx(INFO
, ">>> trying to reissue command withouth Le...");
668 res
= EMVExchangeEx(channel
, false, LeaveFieldON
, get_challenge_APDU
, 4, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
673 int EMVInternalAuthenticate(EMVCommandChannel channel
, bool LeaveFieldON
, uint8_t *DDOL
, size_t DDOLLen
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
)
675 uint8_t authenticate_APDU
[APDU_COMMAND_LEN
] = {0x00, ISO7816_INTERNAL_AUTHENTICATION
, 0x00, 0x00, DDOLLen
, 0x00};
676 memcpy(authenticate_APDU
+ 5, DDOL
, DDOLLen
);
677 int apdulen
= 5 + DDOLLen
;
679 return EMVExchange(channel
, LeaveFieldON
, authenticate_APDU
, apdulen
, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
682 int MSCComputeCryptoChecksum(EMVCommandChannel channel
, bool LeaveFieldON
, uint8_t *UDOL
, uint8_t UDOLlen
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
)
684 uint8_t checksum_APDU
[APDU_COMMAND_LEN
] = {0x80, 0x2a, 0x8e, 0x80, UDOLlen
, 0x00};
685 memcpy(checksum_APDU
+ 5, UDOL
, UDOLlen
);
686 int apdulen
= 5 + UDOLlen
;
688 return EMVExchange(channel
, LeaveFieldON
, checksum_APDU
, apdulen
, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
692 struct emv_pk
*get_ca_pk(struct tlvdb
*db
) {
693 const struct tlv
*df_tlv
= tlvdb_get(db
, 0x84, NULL
);
694 const struct tlv
*caidx_tlv
= tlvdb_get(db
, 0x8f, NULL
);
696 if (!df_tlv
|| !caidx_tlv
|| df_tlv
->len
< 6 || caidx_tlv
->len
!= 1)
699 PrintAndLogEx(NORMAL
, "CA public key index 0x%0x", caidx_tlv
->value
[0]);
700 return emv_pk_get_ca_pk(df_tlv
->value
, caidx_tlv
->value
[0]);
703 int trSDA(struct tlvdb
*tlv
) {
705 struct emv_pk
*pk
= get_ca_pk(tlv
);
707 PrintAndLogEx(WARNING
, "Error: Key not found. Exit.");
711 struct emv_pk
*issuer_pk
= emv_pki_recover_issuer_cert(pk
, tlv
);
714 PrintAndLogEx(WARNING
, "Error: Issuer certificate not found. Exit.");
718 PrintAndLogEx(SUCCESS
, "Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx",
725 issuer_pk
->serial
[0],
726 issuer_pk
->serial
[1],
730 const struct tlv
*sda_tlv
= tlvdb_get(tlv
, 0x21, NULL
);
731 if (!sda_tlv
|| sda_tlv
->len
< 1) {
732 emv_pk_free(issuer_pk
);
734 PrintAndLogEx(WARNING
, "Can't find input list for Offline Data Authentication. Exit.");
738 struct tlvdb
*dac_db
= emv_pki_recover_dac(issuer_pk
, tlv
, sda_tlv
);
740 const struct tlv
*dac_tlv
= tlvdb_get(dac_db
, 0x9f45, NULL
);
741 PrintAndLogEx(NORMAL
, "SDA verified OK. (Data Authentication Code: %02hhx:%02hhx)\n", dac_tlv
->value
[0], dac_tlv
->value
[1]);
742 tlvdb_add(tlv
, dac_db
);
744 emv_pk_free(issuer_pk
);
746 PrintAndLogEx(WARNING
, "SSAD verify error");
750 emv_pk_free(issuer_pk
);
755 static const unsigned char default_ddol_value
[] = {0x9f, 0x37, 0x04};
756 static struct tlv default_ddol_tlv
= {.tag
= 0x9f49, .len
= 3, .value
= default_ddol_value
};
758 int trDDA(EMVCommandChannel channel
, bool decodeTLV
, struct tlvdb
*tlv
) {
759 uint8_t buf
[APDU_RESPONSE_LEN
] = {0};
763 struct emv_pk
*pk
= get_ca_pk(tlv
);
765 PrintAndLogEx(WARNING
, "Error: Key not found. Exit.");
769 const struct tlv
*sda_tlv
= tlvdb_get(tlv
, 0x21, NULL
);
770 /* if (!sda_tlv || sda_tlv->len < 1) { it may be 0!!!!
772 PrintAndLogEx(WARNING, "Error: Can't find input list for Offline Data Authentication. Exit.");
776 struct emv_pk
*issuer_pk
= emv_pki_recover_issuer_cert(pk
, tlv
);
779 PrintAndLogEx(WARNING
, "Error: Issuer certificate not found. Exit.");
782 PrintAndLogEx(SUCCESS
, "Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
789 issuer_pk
->serial
[0],
790 issuer_pk
->serial
[1],
794 struct emv_pk
*icc_pk
= emv_pki_recover_icc_cert(issuer_pk
, tlv
, sda_tlv
);
797 emv_pk_free(issuer_pk
);
798 PrintAndLogEx(WARNING
, "Error: ICC certificate not found. Exit.");
801 PrintAndLogEx(SUCCESS
, "ICC PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
813 if (tlvdb_get(tlv
, 0x9f2d, NULL
)) {
814 struct emv_pk
*icc_pe_pk
= emv_pki_recover_icc_pe_cert(issuer_pk
, tlv
);
816 PrintAndLogEx(WARNING
, "WARNING: ICC PE PK recover error. ");
818 PrintAndLogEx(SUCCESS
, "ICC PE PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
825 icc_pe_pk
->serial
[0],
826 icc_pe_pk
->serial
[1],
831 PrintAndLogEx(INFO
, "ICC PE PK (PIN Encipherment Public Key Certificate) not found.\n");
834 // 9F4B: Signed Dynamic Application Data
835 const struct tlv
*sdad_tlv
= tlvdb_get(tlv
, 0x9f4b, NULL
);
836 // DDA with internal authenticate OR fDDA with filled 0x9F4B tag (GPO result)
837 // EMV kernel3 v2.4, contactless book C-3, C.1., page 147
839 PrintAndLogEx(NORMAL
, "\n* * Got Signed Dynamic Application Data (9F4B) form GPO. Maybe fDDA...");
841 const struct tlvdb
*atc_db
= emv_pki_recover_atc_ex(icc_pk
, tlv
, true);
843 PrintAndLogEx(WARNING
, "Error: Can't recover IDN (ICC Dynamic Number)");
845 emv_pk_free(issuer_pk
);
850 // 9f36 Application Transaction Counter (ATC)
851 const struct tlv
*atc_tlv
= tlvdb_get(atc_db
, 0x9f36, NULL
);
853 PrintAndLogEx(NORMAL
, "\nATC (Application Transaction Counter) [%zu] %s", atc_tlv
->len
, sprint_hex_inrow(atc_tlv
->value
, atc_tlv
->len
));
855 const struct tlv
*core_atc_tlv
= tlvdb_get(tlv
, 0x9f36, NULL
);
856 if(tlv_equal(core_atc_tlv
, atc_tlv
)) {
857 PrintAndLogEx(SUCCESS
, "ATC check OK.");
858 PrintAndLogEx(SUCCESS
, "fDDA (fast DDA) verified OK.");
860 PrintAndLogEx(WARNING
, "Error: fDDA verified, but ATC in the certificate and ATC in the record not the same.");
863 PrintAndLogEx(NORMAL
, "\nERROR: fDDA (fast DDA) verify error");
865 emv_pk_free(issuer_pk
);
870 struct tlvdb
*dac_db
= emv_pki_recover_dac(issuer_pk
, tlv
, sda_tlv
);
872 const struct tlv
*dac_tlv
= tlvdb_get(dac_db
, 0x9f45, NULL
);
873 PrintAndLogEx(NORMAL
, "SDAD verified OK. (Data Authentication Code: %02hhx:%02hhx)\n", dac_tlv
->value
[0], dac_tlv
->value
[1]);
874 tlvdb_add(tlv
, dac_db
);
876 PrintAndLogEx(WARNING
, "Error: SSAD verify error");
878 emv_pk_free(issuer_pk
);
883 PrintAndLogEx(NORMAL
, "\n* Calc DDOL");
884 const struct tlv
*ddol_tlv
= tlvdb_get(tlv
, 0x9f49, NULL
);
886 ddol_tlv
= &default_ddol_tlv
;
887 PrintAndLogEx(NORMAL
, "DDOL [9f49] not found. Using default DDOL");
890 struct tlv
*ddol_data_tlv
= dol_process(ddol_tlv
, tlv
, 0);
891 if (!ddol_data_tlv
) {
892 PrintAndLogEx(WARNING
, "Error: Can't create DDOL TLV");
894 emv_pk_free(issuer_pk
);
899 PrintAndLogEx(NORMAL
, "DDOL data[%d]: %s", ddol_data_tlv
->len
, sprint_hex(ddol_data_tlv
->value
, ddol_data_tlv
->len
));
901 PrintAndLogEx(NORMAL
, "\n* Internal Authenticate");
902 int res
= EMVInternalAuthenticate(channel
, true, (uint8_t *)ddol_data_tlv
->value
, ddol_data_tlv
->len
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
904 PrintAndLogEx(WARNING
, "Internal Authenticate error(%d): %4x. Exit...", res
, sw
);
907 emv_pk_free(issuer_pk
);
912 struct tlvdb
*dda_db
= NULL
;
913 if (buf
[0] == 0x80) {
915 PrintAndLogEx(WARNING
, "Error: Internal Authenticate format1 parsing error. length=%d", len
);
917 // parse response 0x80
918 struct tlvdb
*t80
= tlvdb_parse_multi(buf
, len
);
919 const struct tlv
* t80tlv
= tlvdb_get_tlv(t80
);
921 // 9f4b Signed Dynamic Application Data
922 dda_db
= tlvdb_fixed(0x9f4b, t80tlv
->len
, t80tlv
->value
);
923 tlvdb_add(tlv
, dda_db
);
928 PrintAndLogEx(NORMAL
, "* * Decode response format 1:");
929 TLVPrintFromTLV(dda_db
);
933 dda_db
= tlvdb_parse_multi(buf
, len
);
935 PrintAndLogEx(WARNING
, "Error: Can't parse Internal Authenticate result as TLV");
938 emv_pk_free(issuer_pk
);
942 tlvdb_add(tlv
, dda_db
);
945 TLVPrintFromTLV(dda_db
);
948 struct tlvdb
*idn_db
= emv_pki_recover_idn_ex(icc_pk
, dda_db
, ddol_data_tlv
, true);
951 PrintAndLogEx(WARNING
, "Error: Can't recover IDN (ICC Dynamic Number)");
954 emv_pk_free(issuer_pk
);
960 // 9f4c ICC Dynamic Number
961 const struct tlv
*idn_tlv
= tlvdb_get(idn_db
, 0x9f4c, NULL
);
963 PrintAndLogEx(NORMAL
, "\nIDN (ICC Dynamic Number) [%zu] %s", idn_tlv
->len
, sprint_hex_inrow(idn_tlv
->value
, idn_tlv
->len
));
964 PrintAndLogEx(NORMAL
, "DDA verified OK.");
965 tlvdb_add(tlv
, idn_db
);
968 PrintAndLogEx(NORMAL
, "\nERROR: DDA verify error");
972 emv_pk_free(issuer_pk
);
979 emv_pk_free(issuer_pk
);
984 int trCDA(struct tlvdb
*tlv
, struct tlvdb
*ac_tlv
, struct tlv
*pdol_data_tlv
, struct tlv
*ac_data_tlv
) {
986 struct emv_pk
*pk
= get_ca_pk(tlv
);
988 PrintAndLogEx(WARNING
, "Error: Key not found. Exit.");
992 const struct tlv
*sda_tlv
= tlvdb_get(tlv
, 0x21, NULL
);
993 if (!sda_tlv
|| sda_tlv
->len
< 1) {
994 PrintAndLogEx(WARNING
, "Error: Can't find input list for Offline Data Authentication. Exit.");
999 struct emv_pk
*issuer_pk
= emv_pki_recover_issuer_cert(pk
, tlv
);
1001 PrintAndLogEx(WARNING
, "Error: Issuer certificate not found. Exit.");
1005 PrintAndLogEx(SUCCESS
, "Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
1012 issuer_pk
->serial
[0],
1013 issuer_pk
->serial
[1],
1014 issuer_pk
->serial
[2]
1017 struct emv_pk
*icc_pk
= emv_pki_recover_icc_cert(issuer_pk
, tlv
, sda_tlv
);
1019 PrintAndLogEx(WARNING
, "Error: ICC setrificate not found. Exit.");
1021 emv_pk_free(issuer_pk
);
1024 PrintAndLogEx(SUCCESS
, "ICC PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
1036 struct tlvdb
*dac_db
= emv_pki_recover_dac(issuer_pk
, tlv
, sda_tlv
);
1038 const struct tlv
*dac_tlv
= tlvdb_get(dac_db
, 0x9f45, NULL
);
1039 PrintAndLogEx(NORMAL
, "SSAD verified OK. (%02hhx:%02hhx)", dac_tlv
->value
[0], dac_tlv
->value
[1]);
1040 tlvdb_add(tlv
, dac_db
);
1042 PrintAndLogEx(WARNING
, "Error: SSAD verify error");
1044 emv_pk_free(issuer_pk
);
1045 emv_pk_free(icc_pk
);
1049 PrintAndLogEx(NORMAL
, "\n* * Check Signed Dynamic Application Data (SDAD)");
1050 struct tlvdb
*idn_db
= emv_pki_perform_cda_ex(icc_pk
, tlv
, ac_tlv
,
1051 pdol_data_tlv
, // pdol
1052 ac_data_tlv
, // cdol1
1056 const struct tlv
*idn_tlv
= tlvdb_get(idn_db
, 0x9f4c, NULL
);
1057 PrintAndLogEx(NORMAL
, "\nIDN (ICC Dynamic Number) [%zu] %s", idn_tlv
->len
, sprint_hex_inrow(idn_tlv
->value
, idn_tlv
->len
));
1058 PrintAndLogEx(NORMAL
, "CDA verified OK.");
1059 tlvdb_add(tlv
, idn_db
);
1061 PrintAndLogEx(NORMAL
, "\nERROR: CDA verify error");
1065 emv_pk_free(issuer_pk
);
1066 emv_pk_free(icc_pk
);
1070 int RecoveryCertificates(struct tlvdb
*tlvRoot
, json_t
*root
) {
1072 struct emv_pk
*pk
= get_ca_pk(tlvRoot
);
1074 PrintAndLog("ERROR: Key not found. Exit.");
1078 struct emv_pk
*issuer_pk
= emv_pki_recover_issuer_cert(pk
, tlvRoot
);
1081 PrintAndLog("WARNING: Issuer certificate not found. Exit.");
1084 PrintAndLogEx(SUCCESS
, "Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx",
1091 issuer_pk
->serial
[0],
1092 issuer_pk
->serial
[1],
1093 issuer_pk
->serial
[2]
1096 JsonSaveBufAsHex(root
, "$.ApplicationData.RID", issuer_pk
->rid
, 5);
1098 char *issuer_pk_c
= emv_pk_dump_pk(issuer_pk
);
1099 JsonSaveStr(root
, "$.ApplicationData.IssuerPublicKeyDec", issuer_pk_c
);
1100 JsonSaveBufAsHex(root
, "$.ApplicationData.IssuerPublicKeyModulus", issuer_pk
->modulus
, issuer_pk
->mlen
);
1103 struct emv_pk
*icc_pk
= emv_pki_recover_icc_cert(issuer_pk
, tlvRoot
, NULL
);
1106 emv_pk_free(issuer_pk
);
1107 PrintAndLogEx(WARNING
, "WARNING: ICC certificate not found. Exit.");
1110 PrintAndLogEx(SUCCESS
, "ICC PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
1122 char *icc_pk_c
= emv_pk_dump_pk(icc_pk
);
1123 JsonSaveStr(root
, "$.ApplicationData.ICCPublicKeyDec", icc_pk_c
);
1124 JsonSaveBufAsHex(root
, "$.ApplicationData.ICCPublicKeyModulus", icc_pk
->modulus
, icc_pk
->mlen
);