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