]> git.zerfleddert.de Git - proxmark3-svn/blob - client/emv/cmdemv.c
c40a9a69b3544d1861001bdaedea09c0664213cb
[proxmark3-svn] / client / emv / cmdemv.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2017 Merlok
3 //
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
6 // the license.
7 //-----------------------------------------------------------------------------
8 // EMV commands
9 //-----------------------------------------------------------------------------
10
11 #include <ctype.h>
12 #include "cmdemv.h"
13 #include "test/cryptotest.h"
14 #include "cliparser/cliparser.h"
15
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");
27 return 0;
28 }
29
30 int CmdHFEMVSelect(const char *cmd) {
31 uint8_t data[APDU_AID_LEN] = {0};
32 int datalen = 0;
33
34
35 CLIParserInit("hf 14a select",
36 "Executes select applet command",
37 "Usage:\n\thf emv select -s a00000000101 -> select card, select applet\n\thf emv select -s -t a00000000101 -> select card, select applet, show result in TLV\n");
38
39 void* argtable[] = {
40 arg_param_begin,
41 arg_lit0("sS", "select", "activate field and select card"),
42 arg_lit0("kK", "keep", "keep field for next command"),
43 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
44 arg_lit0("tT", "tlv", "TLV decode results"),
45 arg_str0(NULL, NULL, "<HEX applet AID>", NULL),
46 arg_param_end
47 };
48 CLIExecWithReturn(cmd, argtable, true);
49
50 bool activateField = arg_get_lit(1);
51 bool leaveSignalON = arg_get_lit(2);
52 bool APDULogging = arg_get_lit(3);
53 bool decodeTLV = arg_get_lit(4);
54 if (arg_get_str_len(5))
55 CLIGetStrBLessWithReturn(5, data, &datalen, 0);
56 CLIParserFree();
57
58 SetAPDULogging(APDULogging);
59
60 // exec
61 uint8_t buf[APDU_RES_LEN] = {0};
62 size_t len = 0;
63 uint16_t sw = 0;
64 int res = EMVSelect(activateField, leaveSignalON, data, datalen, buf, sizeof(buf), &len, &sw, NULL);
65
66 if (sw)
67 PrintAndLog("APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
68
69 if (res)
70 return res;
71
72 if (decodeTLV)
73 TLVPrintFromBuffer(buf, len);
74
75 return 0;
76 }
77
78 int CmdHFEMVSearch(const char *cmd) {
79
80 CLIParserInit("hf 14a select",
81 "Tries to select all applets from applet list:\n",
82 "Usage:\n\thf emv search -s -> select card and search\n\thf emv search -s -t -> select card, search and show result in TLV\n");
83
84 void* argtable[] = {
85 arg_param_begin,
86 arg_lit0("sS", "select", "activate field and select card"),
87 arg_lit0("kK", "keep", "keep field ON for next command"),
88 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
89 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
90 arg_param_end
91 };
92 CLIExecWithReturn(cmd, argtable, true);
93
94 bool activateField = arg_get_lit(1);
95 bool leaveSignalON = arg_get_lit(2);
96 bool APDULogging = arg_get_lit(3);
97 bool decodeTLV = arg_get_lit(4);
98 CLIParserFree();
99
100 SetAPDULogging(APDULogging);
101
102 struct tlvdb *t = NULL;
103 const char *al = "Applets list";
104 t = tlvdb_fixed(1, strlen(al), (const unsigned char *)al);
105
106 if (EMVSearch(activateField, leaveSignalON, decodeTLV, t)) {
107 tlvdb_free(t);
108 return 2;
109 }
110
111 PrintAndLog("Search completed.");
112
113 // print list here
114 if (!decodeTLV) {
115 TLVPrintAIDlistFromSelectTLV(t);
116 }
117
118 tlvdb_free(t);
119
120 return 0;
121 }
122
123 int UsageCmdHFEMVPPSE(void) {
124 PrintAndLog("HELP : Executes PSE/PPSE select command. It returns list of applet on the card:\n");
125 PrintAndLog("Usage: hf emv pse [-s][-k][-1][-2][-a][-t]\n");
126 PrintAndLog(" Options:");
127 PrintAndLog(" -s : select card");
128 PrintAndLog(" -k : keep field for next command");
129 PrintAndLog(" -1 : ppse (1PAY.SYS.DDF01)");
130 PrintAndLog(" -2 : pse (2PAY.SYS.DDF01)");
131 PrintAndLog(" -a : show APDU reqests and responses\n");
132 PrintAndLog(" -t : TLV decode results\n");
133 PrintAndLog("Samples:");
134 PrintAndLog(" hf emv pse -s -1 -> select, get pse");
135 PrintAndLog(" hf emv pse -s -k -2 -> select, get ppse, keep field");
136 PrintAndLog(" hf emv pse -s -t -2 -> select, get ppse, show result in TLV");
137 return 0;
138 }
139
140 int CmdHFEMVPPSE(const char *cmd) {
141
142 uint8_t PSENum = 2;
143 bool activateField = false;
144 bool leaveSignalON = false;
145 bool decodeTLV = false;
146
147 if (strlen(cmd) < 1) {
148 UsageCmdHFEMVPPSE();
149 return 0;
150 }
151
152 SetAPDULogging(false);
153
154 int cmdp = 0;
155 while(param_getchar(cmd, cmdp) != 0x00) {
156 char c = param_getchar(cmd, cmdp);
157 if ((c == '-') && (param_getlength(cmd, cmdp) == 2))
158 switch (param_getchar_indx(cmd, 1, cmdp)) {
159 case 'h':
160 case 'H':
161 UsageCmdHFEMVPPSE();
162 return 0;
163 case 's':
164 case 'S':
165 activateField = true;
166 break;
167 case 'k':
168 case 'K':
169 leaveSignalON = true;
170 break;
171 case 'a':
172 case 'A':
173 SetAPDULogging(true);
174 break;
175 case 't':
176 case 'T':
177 decodeTLV = true;
178 break;
179 case '1':
180 PSENum = 1;
181 break;
182 case '2':
183 PSENum = 2;
184 break;
185 default:
186 PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
187 return 1;
188 }
189 cmdp++;
190 }
191
192 // exec
193 uint8_t buf[APDU_RES_LEN] = {0};
194 size_t len = 0;
195 uint16_t sw = 0;
196 int res = EMVSelectPSE(activateField, leaveSignalON, PSENum, buf, sizeof(buf), &len, &sw);
197
198 if (sw)
199 PrintAndLog("APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
200
201 if (res)
202 return res;
203
204
205 if (decodeTLV)
206 TLVPrintFromBuffer(buf, len);
207
208 return 0;
209 }
210
211 int UsageCmdHFEMVExec(void) {
212 PrintAndLog("HELP : Executes EMV contactless transaction:\n");
213 PrintAndLog("Usage: hf emv exec [-s][-a][-t][-f][-v][-c][-x][-g]\n");
214 PrintAndLog(" Options:");
215 PrintAndLog(" -s : select card");
216 PrintAndLog(" -a : show APDU reqests and responses\n");
217 PrintAndLog(" -t : TLV decode results\n");
218 PrintAndLog(" -f : force search AID. Search AID instead of execute PPSE.\n");
219 PrintAndLog(" -v : transaction type - qVSDC or M/Chip.\n");
220 PrintAndLog(" -c : transaction type - qVSDC or M/Chip plus CDA (SDAD generation).\n");
221 PrintAndLog(" -x : transaction type - VSDC. For test only. Not a standart behavior.\n");
222 PrintAndLog(" -g : VISA. generate AC from GPO\n");
223 PrintAndLog("By default : transaction type - MSD.\n");
224 PrintAndLog("Samples:");
225 PrintAndLog(" hf emv exec -s -a -t -> execute MSD transaction");
226 PrintAndLog(" hf emv exec -s -a -t -c -> execute CDA transaction");
227 return 0;
228 }
229
230 #define TLV_ADD(tag, value)( tlvdb_add(tlvRoot, tlvdb_fixed(tag, sizeof(value) - 1, (const unsigned char *)value)) )
231 #define dreturn(n) {free(pdol_data_tlv);tlvdb_free(tlvSelect);tlvdb_free(tlvRoot);DropField();return n;}
232
233 int CmdHFEMVExec(const char *cmd) {
234 bool activateField = false;
235 bool showAPDU = false;
236 bool decodeTLV = false;
237 bool forceSearch = false;
238 enum TransactionType TrType = TT_MSD;
239 bool GenACGPO = false;
240
241 uint8_t buf[APDU_RES_LEN] = {0};
242 size_t len = 0;
243 uint16_t sw = 0;
244 uint8_t AID[APDU_AID_LEN] = {0};
245 size_t AIDlen = 0;
246 uint8_t ODAiList[4096];
247 size_t ODAiListLen = 0;
248
249 int res;
250
251 struct tlvdb *tlvSelect = NULL;
252 struct tlvdb *tlvRoot = NULL;
253 struct tlv *pdol_data_tlv = NULL;
254
255 if (strlen(cmd) < 1) {
256 UsageCmdHFEMVExec();
257 return 0;
258 }
259
260 int cmdp = 0;
261 while(param_getchar(cmd, cmdp) != 0x00) {
262 char c = param_getchar(cmd, cmdp);
263 if ((c == '-') && (param_getlength(cmd, cmdp) == 2))
264 switch (param_getchar_indx(cmd, 1, cmdp)) {
265 case 'h':
266 case 'H':
267 UsageCmdHFEMVExec();
268 return 0;
269 case 's':
270 case 'S':
271 activateField = true;
272 break;
273 case 'a':
274 case 'A':
275 showAPDU = true;
276 break;
277 case 't':
278 case 'T':
279 decodeTLV = true;
280 break;
281 case 'f':
282 case 'F':
283 forceSearch = true;
284 break;
285 case 'x':
286 case 'X':
287 TrType = TT_VSDC;
288 break;
289 case 'v':
290 case 'V':
291 TrType = TT_QVSDCMCHIP;
292 break;
293 case 'c':
294 case 'C':
295 TrType = TT_CDA;
296 break;
297 case 'g':
298 case 'G':
299 GenACGPO = true;
300 break;
301 default:
302 PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
303 return 1;
304 }
305 cmdp++;
306 }
307
308
309 // init applets list tree
310 const char *al = "Applets list";
311 tlvSelect = tlvdb_fixed(1, strlen(al), (const unsigned char *)al);
312
313 // Application Selection
314 // https://www.openscdp.org/scripts/tutorial/emv/applicationselection.html
315 if (!forceSearch) {
316 // PPSE
317 PrintAndLog("\n* PPSE.");
318 SetAPDULogging(showAPDU);
319 res = EMVSearchPSE(activateField, true, decodeTLV, tlvSelect);
320
321 // check PPSE and select application id
322 if (!res) {
323 TLVPrintAIDlistFromSelectTLV(tlvSelect);
324 EMVSelectApplication(tlvSelect, AID, &AIDlen);
325 }
326 }
327
328 // Search
329 if (!AIDlen) {
330 PrintAndLog("\n* Search AID in list.");
331 SetAPDULogging(false);
332 if (EMVSearch(activateField, true, decodeTLV, tlvSelect)) {
333 dreturn(2);
334 }
335
336 // check search and select application id
337 TLVPrintAIDlistFromSelectTLV(tlvSelect);
338 EMVSelectApplication(tlvSelect, AID, &AIDlen);
339 }
340
341 // Init TLV tree
342 const char *alr = "Root terminal TLV tree";
343 tlvRoot = tlvdb_fixed(1, strlen(alr), (const unsigned char *)alr);
344
345 // check if we found EMV application on card
346 if (!AIDlen) {
347 PrintAndLog("Can't select AID. EMV AID not found");
348 dreturn(2);
349 }
350
351 // Select
352 PrintAndLog("\n* Selecting AID:%s", sprint_hex_inrow(AID, AIDlen));
353 SetAPDULogging(showAPDU);
354 res = EMVSelect(false, true, AID, AIDlen, buf, sizeof(buf), &len, &sw, tlvRoot);
355
356 if (res) {
357 PrintAndLog("Can't select AID (%d). Exit...", res);
358 dreturn(3);
359 }
360
361 if (decodeTLV)
362 TLVPrintFromBuffer(buf, len);
363 PrintAndLog("* Selected.");
364
365 PrintAndLog("\n* Init transaction parameters.");
366
367 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
368 char *qVSDC = "\x26\x00\x00\x00";
369 if (GenACGPO) {
370 qVSDC = "\x26\x80\x00\x00";
371 }
372 switch(TrType) {
373 case TT_MSD:
374 TLV_ADD(0x9F66, "\x86\x00\x00\x00"); // MSD
375 break;
376 // not standard for contactless. just for test.
377 case TT_VSDC:
378 TLV_ADD(0x9F66, "\x46\x00\x00\x00"); // VSDC
379 break;
380 case TT_QVSDCMCHIP:
381 TLV_ADD(0x9F66, qVSDC); // qVSDC
382 break;
383 case TT_CDA:
384 TLV_ADD(0x9F66, qVSDC); // qVSDC (VISA CDA not enabled)
385 break;
386 default:
387 TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC
388 break;
389 }
390
391 //9F02:(Amount, authorized (Numeric)) len:6
392 TLV_ADD(0x9F02, "\x00\x00\x00\x00\x01\x00");
393 //9F1A:(Terminal Country Code) len:2
394 TLV_ADD(0x9F1A, "ru");
395 //5F2A:(Transaction Currency Code) len:2
396 // USD 840, EUR 978, RUR 810, RUB 643, RUR 810(old), UAH 980, AZN 031, n/a 999
397 TLV_ADD(0x5F2A, "\x09\x80");
398 //9A:(Transaction Date) len:3
399 TLV_ADD(0x9A, "\x00\x00\x00");
400 //9C:(Transaction Type) len:1 | 00 => Goods and service #01 => Cash
401 TLV_ADD(0x9C, "\x00");
402 // 9F37 Unpredictable Number len:4
403 TLV_ADD(0x9F37, "\x01\x02\x03\x04");
404 // 9F6A Unpredictable Number (MSD for UDOL) len:4
405 TLV_ADD(0x9F6A, "\x01\x02\x03\x04");
406
407 TLVPrintFromTLV(tlvRoot); // TODO delete!!!
408
409 PrintAndLog("\n* Calc PDOL.");
410 pdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x9f38, NULL), tlvRoot, 0x83);
411 if (!pdol_data_tlv){
412 PrintAndLog("ERROR: can't create PDOL TLV.");
413 dreturn(4);
414 }
415
416 size_t pdol_data_tlv_data_len;
417 unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len);
418 if (!pdol_data_tlv_data) {
419 PrintAndLog("ERROR: can't create PDOL data.");
420 dreturn(4);
421 }
422 PrintAndLog("PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len));
423
424 PrintAndLog("\n* GPO.");
425 res = EMVGPO(true, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot);
426
427 free(pdol_data_tlv_data);
428 //free(pdol_data_tlv); --- free on exit.
429
430 if (res) {
431 PrintAndLog("GPO error(%d): %4x. Exit...", res, sw);
432 dreturn(5);
433 }
434
435 // process response template format 1 [id:80 2b AIP + x4b AFL] and format 2 [id:77 TLV]
436 if (buf[0] == 0x80) {
437 if (decodeTLV){
438 PrintAndLog("GPO response format1:");
439 TLVPrintFromBuffer(buf, len);
440 }
441
442 if (len < 4 || (len - 4) % 4) {
443 PrintAndLog("ERROR: GPO response format1 parsing error. length=%d", len);
444 } else {
445 // AIP
446 struct tlvdb * f1AIP = tlvdb_fixed(0x82, 2, buf + 2);
447 tlvdb_add(tlvRoot, f1AIP);
448 if (decodeTLV){
449 PrintAndLog("\n* * Decode response format 1 (0x80) AIP and AFL:");
450 TLVPrintFromTLV(f1AIP);
451 }
452
453 // AFL
454 struct tlvdb * f1AFL = tlvdb_fixed(0x94, len - 4, buf + 2 + 2);
455 tlvdb_add(tlvRoot, f1AFL);
456 if (decodeTLV)
457 TLVPrintFromTLV(f1AFL);
458 }
459 } else {
460 if (decodeTLV)
461 TLVPrintFromBuffer(buf, len);
462 }
463
464 // extract PAN from track2
465 {
466 const struct tlv *track2 = tlvdb_get(tlvRoot, 0x57, NULL);
467 if (!tlvdb_get(tlvRoot, 0x5a, NULL) && track2 && track2->len >= 8) {
468 struct tlvdb *pan = GetPANFromTrack2(track2);
469 if (pan) {
470 tlvdb_add(tlvRoot, pan);
471
472 const struct tlv *pantlv = tlvdb_get(tlvRoot, 0x5a, NULL);
473 PrintAndLog("\n* * Extracted PAN from track2: %s", sprint_hex(pantlv->value, pantlv->len));
474 } else {
475 PrintAndLog("\n* * WARNING: Can't extract PAN from track2.");
476 }
477 }
478 }
479
480 PrintAndLog("\n* Read records from AFL.");
481 const struct tlv *AFL = tlvdb_get(tlvRoot, 0x94, NULL);
482 if (!AFL || !AFL->len) {
483 PrintAndLog("WARNING: AFL not found.");
484 }
485
486 while(AFL && AFL->len) {
487 if (AFL->len % 4) {
488 PrintAndLog("ERROR: Wrong AFL length: %d", AFL->len);
489 break;
490 }
491
492 for (int i = 0; i < AFL->len / 4; i++) {
493 uint8_t SFI = AFL->value[i * 4 + 0] >> 3;
494 uint8_t SFIstart = AFL->value[i * 4 + 1];
495 uint8_t SFIend = AFL->value[i * 4 + 2];
496 uint8_t SFIoffline = AFL->value[i * 4 + 3];
497
498 PrintAndLog("* * SFI[%02x] start:%02x end:%02x offline:%02x", SFI, SFIstart, SFIend, SFIoffline);
499 if (SFI == 0 || SFI == 31 || SFIstart == 0 || SFIstart > SFIend) {
500 PrintAndLog("SFI ERROR! Skipped...");
501 continue;
502 }
503
504 for(int n = SFIstart; n <= SFIend; n++) {
505 PrintAndLog("* * * SFI[%02x] %d", SFI, n);
506
507 res = EMVReadRecord(true, SFI, n, buf, sizeof(buf), &len, &sw, tlvRoot);
508 if (res) {
509 PrintAndLog("ERROR SFI[%02x]. APDU error %4x", SFI, sw);
510 continue;
511 }
512
513 if (decodeTLV) {
514 TLVPrintFromBuffer(buf, len);
515 PrintAndLog("");
516 }
517
518 // Build Input list for Offline Data Authentication
519 // EMV 4.3 book3 10.3, page 96
520 if (SFIoffline) {
521 if (SFI < 11) {
522 const unsigned char *abuf = buf;
523 size_t elmlen = len;
524 struct tlv e;
525 if (tlv_parse_tl(&abuf, &elmlen, &e)) {
526 memcpy(&ODAiList[ODAiListLen], &buf[len - elmlen], elmlen);
527 ODAiListLen += elmlen;
528 } else {
529 PrintAndLog("ERROR SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI);
530 }
531 } else {
532 memcpy(&ODAiList[ODAiListLen], buf, len);
533 ODAiListLen += len;
534 }
535 }
536 }
537 }
538
539 break;
540 }
541
542 // copy Input list for Offline Data Authentication
543 if (ODAiListLen) {
544 struct tlvdb *oda = tlvdb_fixed(0x21, ODAiListLen, ODAiList); // not a standard tag
545 tlvdb_add(tlvRoot, oda);
546 PrintAndLog("* Input list for Offline Data Authentication added to TLV. len=%d \n", ODAiListLen);
547 }
548
549 // get AIP
550 const struct tlv *AIPtlv = tlvdb_get(tlvRoot, 0x82, NULL);
551 uint16_t AIP = AIPtlv->value[0] + AIPtlv->value[1] * 0x100;
552 PrintAndLog("* * AIP=%04x", AIP);
553
554 // SDA
555 if (AIP & 0x0040) {
556 PrintAndLog("\n* SDA");
557 trSDA(tlvRoot);
558 }
559
560 // DDA
561 if (AIP & 0x0020) {
562 PrintAndLog("\n* DDA");
563 trDDA(decodeTLV, tlvRoot);
564 }
565
566 // transaction check
567
568 // qVSDC
569 if (TrType == TT_QVSDCMCHIP|| TrType == TT_CDA){
570 // 9F26: Application Cryptogram
571 const struct tlv *AC = tlvdb_get(tlvRoot, 0x9F26, NULL);
572 if (AC) {
573 PrintAndLog("\n--> qVSDC transaction.");
574 PrintAndLog("* AC path");
575
576 // 9F36: Application Transaction Counter (ATC)
577 const struct tlv *ATC = tlvdb_get(tlvRoot, 0x9F36, NULL);
578 if (ATC) {
579
580 // 9F10: Issuer Application Data - optional
581 const struct tlv *IAD = tlvdb_get(tlvRoot, 0x9F10, NULL);
582
583 // print AC data
584 PrintAndLog("ATC: %s", sprint_hex(ATC->value, ATC->len));
585 PrintAndLog("AC: %s", sprint_hex(AC->value, AC->len));
586 if (IAD){
587 PrintAndLog("IAD: %s", sprint_hex(IAD->value, IAD->len));
588
589 if (IAD->len >= IAD->value[0] + 1) {
590 PrintAndLog("\tKey index: 0x%02x", IAD->value[1]);
591 PrintAndLog("\tCrypto ver: 0x%02x(%03d)", IAD->value[2], IAD->value[2]);
592 PrintAndLog("\tCVR:", sprint_hex(&IAD->value[3], IAD->value[0] - 2));
593 struct tlvdb * cvr = tlvdb_fixed(0x20, IAD->value[0] - 2, &IAD->value[3]);
594 TLVPrintFromTLVLev(cvr, 1);
595 }
596 } else {
597 PrintAndLog("WARNING: IAD not found.");
598 }
599
600 } else {
601 PrintAndLog("ERROR AC: Application Transaction Counter (ATC) not found.");
602 }
603 }
604 }
605
606 // Mastercard M/CHIP
607 if (GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD && (TrType == TT_QVSDCMCHIP || TrType == TT_CDA)){
608 const struct tlv *CDOL1 = tlvdb_get(tlvRoot, 0x8c, NULL);
609 if (CDOL1 && GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD) { // and m/chip transaction flag
610 PrintAndLog("\n--> Mastercard M/Chip transaction.");
611
612 PrintAndLog("* * Generate challenge");
613 res = EMVGenerateChallenge(true, buf, sizeof(buf), &len, &sw, tlvRoot);
614 if (res) {
615 PrintAndLog("ERROR GetChallenge. APDU error %4x", sw);
616 dreturn(6);
617 }
618 if (len < 4) {
619 PrintAndLog("ERROR GetChallenge. Wrong challenge length %d", len);
620 dreturn(6);
621 }
622
623 // ICC Dynamic Number
624 struct tlvdb * ICCDynN = tlvdb_fixed(0x9f4c, len, buf);
625 tlvdb_add(tlvRoot, ICCDynN);
626 if (decodeTLV){
627 PrintAndLog("\n* * ICC Dynamic Number:");
628 TLVPrintFromTLV(ICCDynN);
629 }
630
631 PrintAndLog("* * Calc CDOL1");
632 struct tlv *cdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8c, NULL), tlvRoot, 0x01); // 0x01 - dummy tag
633 if (!cdol_data_tlv){
634 PrintAndLog("ERROR: can't create CDOL1 TLV.");
635 dreturn(6);
636 }
637 PrintAndLog("CDOL1 data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len));
638
639 PrintAndLog("* * AC1");
640 // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD
641 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);
642
643 if (res) {
644 PrintAndLog("AC1 error(%d): %4x. Exit...", res, sw);
645 dreturn(7);
646 }
647
648 if (decodeTLV)
649 TLVPrintFromBuffer(buf, len);
650
651 // CDA
652 PrintAndLog("\n* CDA:");
653 struct tlvdb *ac_tlv = tlvdb_parse_multi(buf, len);
654 res = trCDA(tlvRoot, ac_tlv, pdol_data_tlv, cdol_data_tlv);
655 if (res) {
656 PrintAndLog("CDA error (%d)", res);
657 }
658 free(ac_tlv);
659 free(cdol_data_tlv);
660
661 PrintAndLog("\n* M/Chip transaction result:");
662 // 9F27: Cryptogram Information Data (CID)
663 const struct tlv *CID = tlvdb_get(tlvRoot, 0x9F27, NULL);
664 if (CID) {
665 emv_tag_dump(CID, stdout, 0);
666 PrintAndLog("------------------------------");
667 if (CID->len > 0) {
668 switch(CID->value[0] & EMVAC_AC_MASK){
669 case EMVAC_AAC:
670 PrintAndLog("Transaction DECLINED.");
671 break;
672 case EMVAC_TC:
673 PrintAndLog("Transaction approved OFFLINE.");
674 break;
675 case EMVAC_ARQC:
676 PrintAndLog("Transaction approved ONLINE.");
677 break;
678 default:
679 PrintAndLog("ERROR: CID transaction code error %2x", CID->value[0] & EMVAC_AC_MASK);
680 break;
681 }
682 } else {
683 PrintAndLog("ERROR: Wrong CID length %d", CID->len);
684 }
685 } else {
686 PrintAndLog("ERROR: CID(9F27) not found.");
687 }
688
689 }
690 }
691
692 // MSD
693 if (AIP & 0x8000 && TrType == TT_MSD) {
694 PrintAndLog("\n--> MSD transaction.");
695
696 PrintAndLog("* MSD dCVV path. Check dCVV");
697
698 const struct tlv *track2 = tlvdb_get(tlvRoot, 0x57, NULL);
699 if (track2) {
700 PrintAndLog("Track2: %s", sprint_hex(track2->value, track2->len));
701
702 struct tlvdb *dCVV = GetdCVVRawFromTrack2(track2);
703 PrintAndLog("dCVV raw data:");
704 TLVPrintFromTLV(dCVV);
705
706 if (GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD) {
707 PrintAndLog("\n* Mastercard calculate UDOL");
708
709 // UDOL (9F69)
710 const struct tlv *UDOL = tlvdb_get(tlvRoot, 0x9F69, NULL);
711 // UDOL(9F69) default: 9F6A (Unpredictable number) 4 bytes
712 const struct tlv defUDOL = {
713 .tag = 0x01,
714 .len = 3,
715 .value = (uint8_t *)"\x9f\x6a\x04",
716 };
717 if (!UDOL)
718 PrintAndLog("Use default UDOL.");
719
720 struct tlv *udol_data_tlv = dol_process(UDOL ? UDOL : &defUDOL, tlvRoot, 0x01); // 0x01 - dummy tag
721 if (!udol_data_tlv){
722 PrintAndLog("ERROR: can't create UDOL TLV.");
723 dreturn(8);
724 }
725
726 PrintAndLog("UDOL data[%d]: %s", udol_data_tlv->len, sprint_hex(udol_data_tlv->value, udol_data_tlv->len));
727
728 PrintAndLog("\n* Mastercard compute cryptographic checksum(UDOL)");
729
730 res = MSCComputeCryptoChecksum(true, (uint8_t *)udol_data_tlv->value, udol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot);
731 if (res) {
732 PrintAndLog("ERROR Compute Crypto Checksum. APDU error %4x", sw);
733 free(udol_data_tlv);
734 dreturn(9);
735 }
736
737 if (decodeTLV) {
738 TLVPrintFromBuffer(buf, len);
739 PrintAndLog("");
740 }
741 free(udol_data_tlv);
742
743 }
744 } else {
745 PrintAndLog("ERROR MSD: Track2 data not found.");
746 }
747 }
748
749 // DropField
750 DropField();
751
752 // Destroy TLV's
753 free(pdol_data_tlv);
754 tlvdb_free(tlvSelect);
755 tlvdb_free(tlvRoot);
756
757 PrintAndLog("\n* Transaction completed.");
758
759 return 0;
760 }
761
762 int CmdHFEMVTest(const char *cmd) {
763 return ExecuteCryptoTests(true);
764 }
765
766 int CmdHelp(const char *Cmd);
767 static command_t CommandTable[] = {
768 {"help", CmdHelp, 1, "This help"},
769 {"exec", CmdHFEMVExec, 0, "Executes EMV contactless transaction."},
770 {"pse", CmdHFEMVPPSE, 0, "Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory."},
771 {"search", CmdHFEMVSearch, 0, "Try to select all applets from applets list and print installed applets."},
772 {"select", CmdHFEMVSelect, 0, "Select applet."},
773 {"test", CmdHFEMVTest, 0, "Crypto logic test."},
774 {NULL, NULL, 0, NULL}
775 };
776
777 int CmdHFEMV(const char *Cmd) {
778 CmdsParse(CommandTable, Cmd);
779 return 0;
780 }
781
782 int CmdHelp(const char *Cmd) {
783 CmdsHelp(CommandTable);
784 return 0;
785 }
Impressum, Datenschutz