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