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