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