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