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