]> git.zerfleddert.de Git - proxmark3-svn/blob - client/emv/cmdemv.c
627b4ab29e87e5d71f2b967853484d9ab9765306
[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 "cmdemv.h"
12
13 #include <ctype.h>
14 #include "proxmark3.h"
15 #include "cmdparser.h"
16 #include "mifare.h"
17 #include "emvjson.h"
18 #include "emv_pki.h"
19 #include "emvcore.h"
20 #include "test/cryptotest.h"
21 #include "cliparser/cliparser.h"
22 #include "jansson.h"
23 #include "emv_roca.h"
24
25
26 #define TLV_ADD(tag, value)( tlvdb_change_or_add_node(tlvRoot, tag, sizeof(value) - 1, (const unsigned char *)value) )
27 void ParamLoadDefaults(struct tlvdb *tlvRoot) {
28 //9F02:(Amount, authorized (Numeric)) len:6
29 TLV_ADD(0x9F02, "\x00\x00\x00\x00\x01\x00");
30 //9F1A:(Terminal Country Code) len:2
31 TLV_ADD(0x9F1A, "ru");
32 //5F2A:(Transaction Currency Code) len:2
33 // USD 840, EUR 978, RUR 810, RUB 643, RUR 810(old), UAH 980, AZN 031, n/a 999
34 TLV_ADD(0x5F2A, "\x09\x80");
35 //9A:(Transaction Date) len:3
36 TLV_ADD(0x9A, "\x00\x00\x00");
37 //9C:(Transaction Type) len:1 | 00 => Goods and service #01 => Cash
38 TLV_ADD(0x9C, "\x00");
39 // 9F37 Unpredictable Number len:4
40 TLV_ADD(0x9F37, "\x01\x02\x03\x04");
41 // 9F6A Unpredictable Number (MSD for UDOL) len:4
42 TLV_ADD(0x9F6A, "\x01\x02\x03\x04");
43 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
44 TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC
45 //95:(Terminal Verification Results) len:5
46 // all OK TVR
47 TLV_ADD(0x95, "\x00\x00\x00\x00\x00");
48 }
49
50 void PrintChannel(EMVCommandChannel channel) {
51 switch(channel) {
52 case ECC_CONTACTLESS:
53 PrintAndLogEx(INFO, "Channel: CONTACTLESS");
54 break;
55 case ECC_CONTACT:
56 PrintAndLogEx(INFO, "Channel: CONTACT");
57 break;
58 }
59 }
60
61 int CmdEMVSelect(const char *cmd) {
62 uint8_t data[APDU_DATA_LEN] = {0};
63 int datalen = 0;
64
65 CLIParserInit("emv select",
66 "Executes select applet command",
67 "Usage:\n\temv select -s a00000000101 -> select card, select applet\n\temv select -st a00000000101 -> select card, select applet, 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 for next command"),
73 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
74 arg_lit0("tT", "tlv", "TLV decode results"),
75 #ifdef WITH_SMARTCARD
76 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
77 #endif
78 arg_strx0(NULL, NULL, "<HEX applet AID>", NULL),
79 arg_param_end
80 };
81 CLIExecWithReturn(cmd, argtable, true);
82
83 bool activateField = arg_get_lit(1);
84 bool leaveSignalON = arg_get_lit(2);
85 bool APDULogging = arg_get_lit(3);
86 bool decodeTLV = arg_get_lit(4);
87 EMVCommandChannel channel = ECC_CONTACTLESS;
88 #ifdef WITH_SMARTCARD
89 if (arg_get_lit(5))
90 channel = ECC_CONTACT;
91 PrintChannel(channel);
92 CLIGetHexWithReturn(6, data, &datalen);
93 #else
94 CLIGetHexWithReturn(5, data, &datalen);
95 #endif
96 CLIParserFree();
97
98 SetAPDULogging(APDULogging);
99
100 // exec
101 uint8_t buf[APDU_RESPONSE_LEN] = {0};
102 size_t len = 0;
103 uint16_t sw = 0;
104 int res = EMVSelect(channel, activateField, leaveSignalON, data, datalen, buf, sizeof(buf), &len, &sw, NULL);
105
106 if (sw)
107 PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
108
109 if (res)
110 return res;
111
112 if (decodeTLV)
113 TLVPrintFromBuffer(buf, len);
114
115 return 0;
116 }
117
118 int CmdEMVSearch(const char *cmd) {
119
120 CLIParserInit("emv search",
121 "Tries to select all applets from applet list:\n",
122 "Usage:\n\temv search -s -> select card and search\n\temv search -st -> select card, search and show result in TLV\n");
123
124 void* argtable[] = {
125 arg_param_begin,
126 arg_lit0("sS", "select", "activate field and select card"),
127 arg_lit0("kK", "keep", "keep field ON for next command"),
128 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
129 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
130 #ifdef WITH_SMARTCARD
131 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
132 #endif
133 arg_param_end
134 };
135 CLIExecWithReturn(cmd, argtable, true);
136
137 bool activateField = arg_get_lit(1);
138 bool leaveSignalON = arg_get_lit(2);
139 bool APDULogging = arg_get_lit(3);
140 bool decodeTLV = arg_get_lit(4);
141 EMVCommandChannel channel = ECC_CONTACTLESS;
142 #ifdef WITH_SMARTCARD
143 if (arg_get_lit(5))
144 channel = ECC_CONTACT;
145 #endif
146 PrintChannel(channel);
147 CLIParserFree();
148
149 SetAPDULogging(APDULogging);
150
151 struct tlvdb *t = NULL;
152 const char *al = "Applets list";
153 t = tlvdb_fixed(1, strlen(al), (const unsigned char *)al);
154
155 if (EMVSearch(channel, activateField, leaveSignalON, decodeTLV, t)) {
156 tlvdb_free(t);
157 return 2;
158 }
159
160 PrintAndLogEx(SUCCESS, "Search completed.");
161
162 // print list here
163 if (!decodeTLV) {
164 TLVPrintAIDlistFromSelectTLV(t);
165 }
166
167 tlvdb_free(t);
168
169 return 0;
170 }
171
172 int CmdEMVPPSE(const char *cmd) {
173
174 CLIParserInit("emv pse",
175 "Executes PSE/PPSE select command. It returns list of applet on the card:\n",
176 "Usage:\n\temv pse -s1 -> select, get pse\n\temv pse -st2 -> select, get ppse, show result in TLV\n");
177
178 void* argtable[] = {
179 arg_param_begin,
180 arg_lit0("sS", "select", "activate field and select card"),
181 arg_lit0("kK", "keep", "keep field ON for next command"),
182 arg_lit0("1", "pse", "pse (1PAY.SYS.DDF01) mode"),
183 arg_lit0("2", "ppse", "ppse (2PAY.SYS.DDF01) mode (default mode)"),
184 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
185 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
186 #ifdef WITH_SMARTCARD
187 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
188 #endif
189 arg_param_end
190 };
191 CLIExecWithReturn(cmd, argtable, true);
192
193 bool activateField = arg_get_lit(1);
194 bool leaveSignalON = arg_get_lit(2);
195 uint8_t PSENum = 2;
196 if (arg_get_lit(3))
197 PSENum = 1;
198 if (arg_get_lit(4))
199 PSENum = 2;
200 bool APDULogging = arg_get_lit(5);
201 bool decodeTLV = arg_get_lit(6);
202 EMVCommandChannel channel = ECC_CONTACTLESS;
203 #ifdef WITH_SMARTCARD
204 if (arg_get_lit(7))
205 channel = ECC_CONTACT;
206 #endif
207 PrintChannel(channel);
208 CLIParserFree();
209
210 SetAPDULogging(APDULogging);
211
212 // exec
213 uint8_t buf[APDU_RESPONSE_LEN] = {0};
214 size_t len = 0;
215 uint16_t sw = 0;
216 int res = EMVSelectPSE(channel, activateField, leaveSignalON, PSENum, buf, sizeof(buf), &len, &sw);
217
218 if (sw)
219 PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
220
221 if (res)
222 return res;
223
224
225 if (decodeTLV)
226 TLVPrintFromBuffer(buf, len);
227
228 return 0;
229 }
230
231 int CmdEMVGPO(const char *cmd) {
232 uint8_t data[APDU_RESPONSE_LEN] = {0};
233 int datalen = 0;
234
235 CLIParserInit("emv gpo",
236 "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.",
237 "Usage:\n\temv gpo -k -> execute GPO\n"
238 "\temv gpo -t 01020304 -> execute GPO with 4-byte PDOL data, show result in TLV\n"
239 "\temv gpo -pmt 9F 37 04 -> load params from file, make PDOL data from PDOL, execute GPO with PDOL, show result in TLV\n");
240
241 void* argtable[] = {
242 arg_param_begin,
243 arg_lit0("kK", "keep", "keep field ON for next command"),
244 arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for PDOLdata making from PDOL and parameters"),
245 arg_lit0("mM", "make", "make PDOLdata from PDOL (tag 9F38) and parameters (by default uses default parameters)"),
246 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
247 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
248 #ifdef WITH_SMARTCARD
249 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
250 #endif
251 arg_strx0(NULL, NULL, "<HEX PDOLdata/PDOL>", NULL),
252 arg_param_end
253 };
254 CLIExecWithReturn(cmd, argtable, true);
255
256 bool leaveSignalON = arg_get_lit(1);
257 bool paramsLoadFromFile = arg_get_lit(2);
258 bool dataMakeFromPDOL = arg_get_lit(3);
259 bool APDULogging = arg_get_lit(4);
260 bool decodeTLV = arg_get_lit(5);
261 EMVCommandChannel channel = ECC_CONTACTLESS;
262 #ifdef WITH_SMARTCARD
263 if (arg_get_lit(6))
264 channel = ECC_CONTACT;
265 CLIGetHexWithReturn(7, data, &datalen);
266 #else
267 CLIGetHexWithReturn(6, data, &datalen);
268 #endif
269 PrintChannel(channel);
270 CLIParserFree();
271
272 SetAPDULogging(APDULogging);
273
274 // Init TLV tree
275 const char *alr = "Root terminal TLV tree";
276 struct tlvdb *tlvRoot = tlvdb_fixed(1, strlen(alr), (const unsigned char *)alr);
277
278 // calc PDOL
279 struct tlv *pdol_data_tlv = NULL;
280 struct tlv data_tlv = {
281 .tag = 0x83,
282 .len = datalen,
283 .value = (uint8_t *)data,
284 };
285 if (dataMakeFromPDOL) {
286 ParamLoadDefaults(tlvRoot);
287
288 if (paramsLoadFromFile) {
289 PrintAndLogEx(INFO, "Params loading from file...");
290 ParamLoadFromJson(tlvRoot);
291 };
292
293 pdol_data_tlv = dol_process((const struct tlv *)tlvdb_external(0x9f38, datalen, data), tlvRoot, 0x83);
294 if (!pdol_data_tlv){
295 PrintAndLogEx(ERR, "Can't create PDOL TLV.");
296 tlvdb_free(tlvRoot);
297 return 4;
298 }
299 } else {
300 if (paramsLoadFromFile) {
301 PrintAndLogEx(WARNING, "Don't need to load parameters. Sending plain PDOL data...");
302 }
303 pdol_data_tlv = &data_tlv;
304 }
305
306 size_t pdol_data_tlv_data_len = 0;
307 unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len);
308 if (!pdol_data_tlv_data) {
309 PrintAndLogEx(ERR, "Can't create PDOL data.");
310 tlvdb_free(tlvRoot);
311 return 4;
312 }
313 PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len));
314
315 // exec
316 uint8_t buf[APDU_RESPONSE_LEN] = {0};
317 size_t len = 0;
318 uint16_t sw = 0;
319 int res = EMVGPO(channel, leaveSignalON, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot);
320
321 if (pdol_data_tlv != &data_tlv)
322 free(pdol_data_tlv);
323 tlvdb_free(tlvRoot);
324
325 if (sw)
326 PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
327
328 if (res)
329 return res;
330
331 if (decodeTLV)
332 TLVPrintFromBuffer(buf, len);
333
334 return 0;
335 }
336
337 int CmdEMVReadRecord(const char *cmd) {
338 uint8_t data[APDU_RESPONSE_LEN] = {0};
339 int datalen = 0;
340
341 CLIParserInit("emv readrec",
342 "Executes Read Record command. It returns data in TLV format.\nNeeds a bank applet to be selected and sometimes needs GPO to be executed.",
343 "Usage:\n\temv readrec -k 0101 -> read file SFI=01, SFIrec=01\n\temv readrec -kt 0201-> read file 0201 and show result in TLV\n");
344
345 void* argtable[] = {
346 arg_param_begin,
347 arg_lit0("kK", "keep", "keep field ON for next command"),
348 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
349 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
350 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
351 arg_strx1(NULL, NULL, "<SFI 1byte HEX><SFIrecord 1byte HEX>", NULL),
352 arg_param_end
353 };
354 CLIExecWithReturn(cmd, argtable, true);
355
356 bool leaveSignalON = arg_get_lit(1);
357 bool APDULogging = arg_get_lit(2);
358 bool decodeTLV = arg_get_lit(3);
359 EMVCommandChannel channel = ECC_CONTACTLESS;
360 #ifdef WITH_SMARTCARD
361 if (arg_get_lit(4))
362 channel = ECC_CONTACT;
363 CLIGetHexWithReturn(5, data, &datalen);
364 #else
365 CLIGetHexWithReturn(4, data, &datalen);
366 #endif
367 PrintChannel(channel);
368 CLIParserFree();
369
370 if (datalen != 2) {
371 PrintAndLogEx(ERR, "Command needs to have 2 bytes of data");
372 return 1;
373 }
374
375 SetAPDULogging(APDULogging);
376
377 // exec
378 uint8_t buf[APDU_RESPONSE_LEN] = {0};
379 size_t len = 0;
380 uint16_t sw = 0;
381 int res = EMVReadRecord(channel, leaveSignalON, data[0], data[1], buf, sizeof(buf), &len, &sw, NULL);
382
383 if (sw)
384 PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
385
386 if (res)
387 return res;
388
389
390 if (decodeTLV)
391 TLVPrintFromBuffer(buf, len);
392
393 return 0;
394 }
395
396 int CmdEMVAC(const char *cmd) {
397 uint8_t data[APDU_RESPONSE_LEN] = {0};
398 int datalen = 0;
399
400 CLIParserInit("emv genac",
401 "Generate Application Cryptogram command. It returns data in TLV format .\nNeeds a EMV applet to be selected and GPO to be executed.",
402 "Usage:\n\temv genac -k 0102 -> generate AC with 2-byte CDOLdata and keep field ON after command\n"
403 "\temv genac -t 01020304 -> generate AC with 4-byte CDOL data, show result in TLV\n"
404 "\temv genac -Daac 01020304 -> generate AC with 4-byte CDOL data and terminal decision 'declined'\n"
405 "\temv genac -pmt 9F 37 04 -> load params from file, make CDOL data from CDOL, generate AC with CDOL, show result in TLV");
406
407 void* argtable[] = {
408 arg_param_begin,
409 arg_lit0("kK", "keep", "keep field ON for next command"),
410 arg_lit0("cC", "cda", "executes CDA transaction. Needs to get SDAD in results."),
411 arg_str0("dD", "decision", "<aac|tc|arqc>", "Terminal decision. aac - declined, tc - approved, arqc - online authorisation requested"),
412 arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for CDOLdata making from CDOL and parameters"),
413 arg_lit0("mM", "make", "make CDOLdata from CDOL (tag 8C and 8D) and parameters (by default uses default parameters)"),
414 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
415 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
416 #ifdef WITH_SMARTCARD
417 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
418 #endif
419 arg_strx1(NULL, NULL, "<HEX CDOLdata/CDOL>", NULL),
420 arg_param_end
421 };
422 CLIExecWithReturn(cmd, argtable, false);
423
424 bool leaveSignalON = arg_get_lit(1);
425 bool trTypeCDA = arg_get_lit(2);
426 uint8_t termDecision = 0xff;
427 if (arg_get_str_len(3)) {
428 if (!strncmp(arg_get_str(3)->sval[0], "aac", 4))
429 termDecision = EMVAC_AAC;
430 if (!strncmp(arg_get_str(3)->sval[0], "tc", 4))
431 termDecision = EMVAC_TC;
432 if (!strncmp(arg_get_str(3)->sval[0], "arqc", 4))
433 termDecision = EMVAC_ARQC;
434
435 if (termDecision == 0xff) {
436 PrintAndLog("ERROR: can't find terminal decision '%s'", arg_get_str(3)->sval[0]);
437 return 1;
438 }
439 } else {
440 termDecision = EMVAC_TC;
441 }
442 if (trTypeCDA)
443 termDecision = termDecision | EMVAC_CDAREQ;
444 bool paramsLoadFromFile = arg_get_lit(4);
445 bool dataMakeFromCDOL = arg_get_lit(5);
446 bool APDULogging = arg_get_lit(6);
447 bool decodeTLV = arg_get_lit(7);
448 EMVCommandChannel channel = ECC_CONTACTLESS;
449 #ifdef WITH_SMARTCARD
450 if (arg_get_lit(8))
451 channel = ECC_CONTACT;
452 CLIGetHexWithReturn(9, data, &datalen);
453 #else
454 CLIGetHexWithReturn(8, data, &datalen);
455 #endif
456 PrintChannel(channel);
457 CLIParserFree();
458
459 SetAPDULogging(APDULogging);
460
461 // Init TLV tree
462 const char *alr = "Root terminal TLV tree";
463 struct tlvdb *tlvRoot = tlvdb_fixed(1, strlen(alr), (const unsigned char *)alr);
464
465 // calc CDOL
466 struct tlv *cdol_data_tlv = NULL;
467 struct tlv data_tlv = {
468 .tag = 0x01,
469 .len = datalen,
470 .value = (uint8_t *)data,
471 };
472
473 if (dataMakeFromCDOL) {
474 ParamLoadDefaults(tlvRoot);
475
476 if (paramsLoadFromFile) {
477 PrintAndLogEx(INFO, "Params loading from file...");
478 ParamLoadFromJson(tlvRoot);
479 };
480
481 cdol_data_tlv = dol_process((const struct tlv *)tlvdb_external(0x8c, datalen, data), tlvRoot, 0x01); // 0x01 - dummy tag
482 if (!cdol_data_tlv){
483 PrintAndLogEx(ERR, "Can't create CDOL TLV.");
484 tlvdb_free(tlvRoot);
485 return 4;
486 }
487 } else {
488 if (paramsLoadFromFile) {
489 PrintAndLogEx(WARNING, "Don't need to load parameters. Sending plain CDOL data...");
490 }
491 cdol_data_tlv = &data_tlv;
492 }
493
494 PrintAndLogEx(INFO, "CDOL data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len));
495
496 // exec
497 uint8_t buf[APDU_RESPONSE_LEN] = {0};
498 size_t len = 0;
499 uint16_t sw = 0;
500 int res = EMVAC(channel, leaveSignalON, termDecision, (uint8_t *)cdol_data_tlv->value, cdol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot);
501
502 if (cdol_data_tlv != &data_tlv)
503 free(cdol_data_tlv);
504 tlvdb_free(tlvRoot);
505
506 if (sw)
507 PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
508
509 if (res)
510 return res;
511
512 if (decodeTLV)
513 TLVPrintFromBuffer(buf, len);
514
515 return 0;
516 }
517
518 int CmdEMVGenerateChallenge(const char *cmd) {
519
520 CLIParserInit("emv challenge",
521 "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.",
522 "Usage:\n\temv challenge -> get challenge\n\temv challenge -k -> get challenge, keep fileld ON\n");
523
524 void* argtable[] = {
525 arg_param_begin,
526 arg_lit0("kK", "keep", "keep field ON for next command"),
527 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
528 #ifdef WITH_SMARTCARD
529 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
530 #endif
531 arg_param_end
532 };
533 CLIExecWithReturn(cmd, argtable, true);
534
535 bool leaveSignalON = arg_get_lit(1);
536 bool APDULogging = arg_get_lit(2);
537 EMVCommandChannel channel = ECC_CONTACTLESS;
538 #ifdef WITH_SMARTCARD
539 if (arg_get_lit(3))
540 channel = ECC_CONTACT;
541 #endif
542 PrintChannel(channel);
543 CLIParserFree();
544
545 SetAPDULogging(APDULogging);
546
547 // exec
548 uint8_t buf[APDU_RESPONSE_LEN] = {0};
549 size_t len = 0;
550 uint16_t sw = 0;
551 int res = EMVGenerateChallenge(channel, leaveSignalON, buf, sizeof(buf), &len, &sw, NULL);
552
553 if (sw)
554 PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
555
556 if (res)
557 return res;
558
559 PrintAndLogEx(SUCCESS, "Challenge: %s", sprint_hex(buf, len));
560
561 if (len != 4 && len != 8)
562 PrintAndLogEx(WARNING, "Length of challenge must be 4 or 8, but it %d", len);
563
564 return 0;
565 }
566
567 int CmdEMVInternalAuthenticate(const char *cmd) {
568 uint8_t data[APDU_RESPONSE_LEN] = {0};
569 int datalen = 0;
570
571 CLIParserInit("emv intauth",
572 "Generate Internal Authenticate command. Usually needs 4-byte random number. It returns data in TLV format .\n"
573 "Needs a EMV applet to be selected and GPO to be executed.",
574
575 "Usage:\n"
576 "\temv intauth -k 01020304 -> execute Internal Authenticate with 4-byte DDOLdata and keep field ON after command\n"
577 "\temv intauth -t 01020304 -> execute Internal Authenticate with 4-byte DDOL data, show result in TLV\n"
578 "\temv intauth -pmt 9F 37 04 -> load params from file, make DDOL data from DDOL, Internal Authenticate with DDOL, show result in TLV");
579
580 void* argtable[] = {
581 arg_param_begin,
582 arg_lit0("kK", "keep", "keep field ON for next command"),
583 arg_lit0("pP", "params", "load parameters from `emv/defparams.json` file for DDOLdata making from DDOL and parameters"),
584 arg_lit0("mM", "make", "make DDOLdata from DDOL (tag 9F49) and parameters (by default uses default parameters)"),
585 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
586 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
587 #ifdef WITH_SMARTCARD
588 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
589 #endif
590 arg_strx1(NULL, NULL, "<HEX DDOLdata/DDOL>", NULL),
591 arg_param_end
592 };
593 CLIExecWithReturn(cmd, argtable, false);
594
595 bool leaveSignalON = arg_get_lit(1);
596 bool paramsLoadFromFile = arg_get_lit(2);
597 bool dataMakeFromDDOL = arg_get_lit(3);
598 bool APDULogging = arg_get_lit(4);
599 bool decodeTLV = arg_get_lit(5);
600 EMVCommandChannel channel = ECC_CONTACTLESS;
601 #ifdef WITH_SMARTCARD
602 if (arg_get_lit(6))
603 channel = ECC_CONTACT;
604 CLIGetHexWithReturn(7, data, &datalen);
605 #else
606 CLIGetHexWithReturn(6, data, &datalen);
607 #endif
608 PrintChannel(channel);
609 CLIParserFree();
610
611 SetAPDULogging(APDULogging);
612
613 // Init TLV tree
614 const char *alr = "Root terminal TLV tree";
615 struct tlvdb *tlvRoot = tlvdb_fixed(1, strlen(alr), (const unsigned char *)alr);
616
617 // calc DDOL
618 struct tlv *ddol_data_tlv = NULL;
619 struct tlv data_tlv = {
620 .tag = 0x01,
621 .len = datalen,
622 .value = (uint8_t *)data,
623 };
624
625 if (dataMakeFromDDOL) {
626 ParamLoadDefaults(tlvRoot);
627
628 if (paramsLoadFromFile) {
629 PrintAndLogEx(INFO, "Params loading from file...");
630 ParamLoadFromJson(tlvRoot);
631 };
632
633 ddol_data_tlv = dol_process((const struct tlv *)tlvdb_external(0x9f49, datalen, data), tlvRoot, 0x01); // 0x01 - dummy tag
634 if (!ddol_data_tlv){
635 PrintAndLogEx(ERR, "Can't create DDOL TLV.");
636 tlvdb_free(tlvRoot);
637 return 4;
638 }
639 } else {
640 if (paramsLoadFromFile) {
641 PrintAndLogEx(WARNING, "Don't need to load parameters. Sending plain DDOL data...");
642 }
643 ddol_data_tlv = &data_tlv;
644 }
645
646 PrintAndLogEx(INFO, "DDOL data[%d]: %s", ddol_data_tlv->len, sprint_hex(ddol_data_tlv->value, ddol_data_tlv->len));
647
648 // exec
649 uint8_t buf[APDU_RESPONSE_LEN] = {0};
650 size_t len = 0;
651 uint16_t sw = 0;
652 int res = EMVInternalAuthenticate(channel, leaveSignalON, data, datalen, buf, sizeof(buf), &len, &sw, NULL);
653
654 if (ddol_data_tlv != &data_tlv)
655 free(ddol_data_tlv);
656 tlvdb_free(tlvRoot);
657
658 if (sw)
659 PrintAndLogEx(INFO, "APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
660
661 if (res)
662 return res;
663
664 if (decodeTLV)
665 TLVPrintFromBuffer(buf, len);
666
667 return 0;
668 }
669
670 #define dreturn(n) {free(pdol_data_tlv);tlvdb_free(tlvSelect);tlvdb_free(tlvRoot);DropField();return n;}
671
672 void InitTransactionParameters(struct tlvdb *tlvRoot, bool paramLoadJSON, enum TransactionType TrType, bool GenACGPO) {
673
674 ParamLoadDefaults(tlvRoot);
675
676 if (paramLoadJSON) {
677 PrintAndLog("* * Transaction parameters loading from JSON...");
678 ParamLoadFromJson(tlvRoot);
679 }
680
681 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
682 char *qVSDC = "\x26\x00\x00\x00";
683 if (GenACGPO) {
684 qVSDC = "\x26\x80\x00\x00";
685 }
686 switch(TrType) {
687 case TT_MSD:
688 TLV_ADD(0x9F66, "\x86\x00\x00\x00"); // MSD
689 break;
690 // not standard for contactless. just for test.
691 case TT_VSDC:
692 TLV_ADD(0x9F66, "\x46\x00\x00\x00"); // VSDC
693 break;
694 case TT_QVSDCMCHIP:
695 TLV_ADD(0x9F66, qVSDC); // qVSDC
696 break;
697 case TT_CDA:
698 TLV_ADD(0x9F66, qVSDC); // qVSDC (VISA CDA not enabled)
699 break;
700 default:
701 break;
702 }
703 }
704
705 void ProcessGPOResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t len, bool decodeTLV) {
706 if (buf[0] == 0x80) {
707 if (decodeTLV){
708 PrintAndLog("GPO response format1:");
709 TLVPrintFromBuffer(buf, len);
710 }
711
712 if (len < 4 || (len - 4) % 4) {
713 PrintAndLogEx(ERR, "GPO response format1 parsing error. length=%d", len);
714 } else {
715 // AIP
716 struct tlvdb * f1AIP = tlvdb_fixed(0x82, 2, buf + 2);
717 tlvdb_add(tlvRoot, f1AIP);
718 if (decodeTLV){
719 PrintAndLogEx(INFO, "\n* * Decode response format 1 (0x80) AIP and AFL:");
720 TLVPrintFromTLV(f1AIP);
721 }
722
723 // AFL
724 struct tlvdb * f1AFL = tlvdb_fixed(0x94, len - 4, buf + 2 + 2);
725 tlvdb_add(tlvRoot, f1AFL);
726 if (decodeTLV)
727 TLVPrintFromTLV(f1AFL);
728 }
729 } else {
730 if (decodeTLV)
731 TLVPrintFromBuffer(buf, len);
732 }
733 }
734
735 void ProcessACResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t len, bool decodeTLV) {
736 if (buf[0] == 0x80) {
737 if (decodeTLV){
738 PrintAndLog("GPO response format1:");
739 TLVPrintFromBuffer(buf, len);
740 }
741
742 uint8_t elmlen = len - 2; // wo 0x80XX
743
744 if (len < 4 + 2 || (elmlen - 2) % 4 || elmlen != buf[1]) {
745 PrintAndLogEx(ERR, "GPO response format1 parsing error. length=%d", len);
746 } else {
747 struct tlvdb *tlvElm = NULL;
748 if (decodeTLV)
749 PrintAndLog("\n------------ Format1 decoded ------------");
750
751 // CID (Cryptogram Information Data)
752 tlvdb_change_or_add_node_ex(tlvRoot, 0x9f27, 1, &buf[2], &tlvElm);
753 if (decodeTLV)
754 TLVPrintFromTLV(tlvElm);
755
756 // ATC (Application Transaction Counter)
757 tlvdb_change_or_add_node_ex(tlvRoot, 0x9f36, 2, &buf[3], &tlvElm);
758 if (decodeTLV)
759 TLVPrintFromTLV(tlvElm);
760
761 // AC (Application Cryptogram)
762 tlvdb_change_or_add_node_ex(tlvRoot, 0x9f26, MIN(8, elmlen - 3), &buf[5], &tlvElm);
763 if (decodeTLV)
764 TLVPrintFromTLV(tlvElm);
765
766 // IAD (Issuer Application Data) - optional
767 if (len > 11 + 2) {
768 tlvdb_change_or_add_node_ex(tlvRoot, 0x9f10, elmlen - 11, &buf[13], &tlvElm);
769 if (decodeTLV)
770 TLVPrintFromTLV(tlvElm);
771 }
772 }
773 } else {
774 if (decodeTLV)
775 TLVPrintFromBuffer(buf, len);
776 }
777 }
778
779 int CmdEMVExec(const char *cmd) {
780 uint8_t buf[APDU_RESPONSE_LEN] = {0};
781 size_t len = 0;
782 uint16_t sw = 0;
783 uint8_t AID[APDU_DATA_LEN] = {0};
784 size_t AIDlen = 0;
785 uint8_t ODAiList[4096];
786 size_t ODAiListLen = 0;
787
788 int res;
789
790 struct tlvdb *tlvSelect = NULL;
791 struct tlvdb *tlvRoot = NULL;
792 struct tlv *pdol_data_tlv = NULL;
793
794 CLIParserInit("emv exec",
795 "Executes EMV contactless transaction",
796 "Usage:\n"
797 "\temv exec -sat -> select card, execute MSD transaction, show APDU and TLV\n"
798 "\temv exec -satc -> select card, execute CDA transaction, show APDU and TLV\n");
799
800 void* argtable[] = {
801 arg_param_begin,
802 arg_lit0("sS", "select", "activate field and select card."),
803 arg_lit0("aA", "apdu", "show APDU reqests and responses."),
804 arg_lit0("tT", "tlv", "TLV decode results."),
805 arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."),
806 arg_lit0("fF", "forceaid", "Force search AID. Search AID instead of execute PPSE."),
807 arg_rem("By default:", "Transaction type - MSD"),
808 arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
809 arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
810 arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standart behavior."),
811 arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."),
812 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
813 arg_param_end
814 };
815 CLIExecWithReturn(cmd, argtable, true);
816
817 bool activateField = arg_get_lit(1);
818 bool showAPDU = arg_get_lit(2);
819 bool decodeTLV = arg_get_lit(3);
820 bool paramLoadJSON = arg_get_lit(4);
821 bool forceSearch = arg_get_lit(5);
822
823 enum TransactionType TrType = TT_MSD;
824 if (arg_get_lit(7))
825 TrType = TT_QVSDCMCHIP;
826 if (arg_get_lit(8))
827 TrType = TT_CDA;
828 if (arg_get_lit(9))
829 TrType = TT_VSDC;
830
831 bool GenACGPO = arg_get_lit(10);
832 EMVCommandChannel channel = ECC_CONTACTLESS;
833 #ifdef WITH_SMARTCARD
834 if (arg_get_lit(11))
835 channel = ECC_CONTACT;
836 #endif
837 PrintChannel(channel);
838 uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2;
839 char *PSE_or_PPSE = psenum == 1 ? "PSE" : "PPSE";
840
841 CLIParserFree();
842
843 SetAPDULogging(showAPDU);
844
845 // init applets list tree
846 const char *al = "Applets list";
847 tlvSelect = tlvdb_fixed(1, strlen(al), (const unsigned char *)al);
848
849 // Application Selection
850 // https://www.openscdp.org/scripts/tutorial/emv/applicationselection.html
851 if (!forceSearch) {
852 // PPSE / PSE
853 PrintAndLogEx(NORMAL, "\n* %s.", PSE_or_PPSE);
854 SetAPDULogging(showAPDU);
855 res = EMVSearchPSE(channel, activateField, true, psenum, decodeTLV, tlvSelect);
856
857 // check PPSE / PSE and select application id
858 if (!res) {
859 TLVPrintAIDlistFromSelectTLV(tlvSelect);
860 EMVSelectApplication(tlvSelect, AID, &AIDlen);
861 }
862 }
863
864 // Search
865 if (!AIDlen) {
866 PrintAndLogEx(NORMAL, "\n* Search AID in list.");
867 SetAPDULogging(false);
868 if (EMVSearch(channel, activateField, true, decodeTLV, tlvSelect)) {
869 dreturn(2);
870 }
871
872 // check search and select application id
873 TLVPrintAIDlistFromSelectTLV(tlvSelect);
874 EMVSelectApplication(tlvSelect, AID, &AIDlen);
875 }
876
877 // Init TLV tree
878 const char *alr = "Root terminal TLV tree";
879 tlvRoot = tlvdb_fixed(1, strlen(alr), (const unsigned char *)alr);
880
881 // check if we found EMV application on card
882 if (!AIDlen) {
883 PrintAndLogEx(WARNING, "Can't select AID. EMV AID not found");
884 dreturn(2);
885 }
886
887 // Select
888 PrintAndLogEx(NORMAL, "\n* Selecting AID:%s", sprint_hex_inrow(AID, AIDlen));
889 SetAPDULogging(showAPDU);
890 res = EMVSelect(channel, false, true, AID, AIDlen, buf, sizeof(buf), &len, &sw, tlvRoot);
891
892 if (res) {
893 PrintAndLogEx(WARNING, "Can't select AID (%d). Exit...", res);
894 dreturn(3);
895 }
896
897 if (decodeTLV)
898 TLVPrintFromBuffer(buf, len);
899 PrintAndLogEx(INFO, "* Selected.");
900
901 PrintAndLogEx(INFO, "\n* Init transaction parameters.");
902 InitTransactionParameters(tlvRoot, paramLoadJSON, TrType, GenACGPO);
903 TLVPrintFromTLV(tlvRoot); // TODO delete!!!
904
905 PrintAndLogEx(NORMAL, "\n* Calc PDOL.");
906 pdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x9f38, NULL), tlvRoot, 0x83);
907 if (!pdol_data_tlv){
908 PrintAndLogEx(WARNING, "Error: can't create PDOL TLV.");
909 dreturn(4);
910 }
911
912 size_t pdol_data_tlv_data_len;
913 unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len);
914 if (!pdol_data_tlv_data) {
915 PrintAndLogEx(WARNING, "Error: can't create PDOL data.");
916 dreturn(4);
917 }
918 PrintAndLogEx(NORMAL, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len));
919
920 PrintAndLogEx(NORMAL, "\n* GPO.");
921 res = EMVGPO(channel, true, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot);
922
923 free(pdol_data_tlv_data);
924 //free(pdol_data_tlv); --- free on exit.
925
926 if (res) {
927 PrintAndLogEx(NORMAL, "GPO error(%d): %4x. Exit...", res, sw);
928 dreturn(5);
929 }
930
931 // process response template format 1 [id:80 2b AIP + x4b AFL] and format 2 [id:77 TLV]
932 ProcessGPOResponseFormat1(tlvRoot, buf, len, decodeTLV);
933
934 // extract PAN from track2
935 {
936 const struct tlv *track2 = tlvdb_get(tlvRoot, 0x57, NULL);
937 if (!tlvdb_get(tlvRoot, 0x5a, NULL) && track2 && track2->len >= 8) {
938 struct tlvdb *pan = GetPANFromTrack2(track2);
939 if (pan) {
940 tlvdb_add(tlvRoot, pan);
941
942 const struct tlv *pantlv = tlvdb_get(tlvRoot, 0x5a, NULL);
943 PrintAndLogEx(NORMAL, "\n* * Extracted PAN from track2: %s", sprint_hex(pantlv->value, pantlv->len));
944 } else {
945 PrintAndLogEx(NORMAL, "\n* * WARNING: Can't extract PAN from track2.");
946 }
947 }
948 }
949
950 PrintAndLogEx(NORMAL, "\n* Read records from AFL.");
951 const struct tlv *AFL = tlvdb_get(tlvRoot, 0x94, NULL);
952 if (!AFL || !AFL->len) {
953 PrintAndLogEx(WARNING, "AFL not found.");
954 }
955
956 while(AFL && AFL->len) {
957 if (AFL->len % 4) {
958 PrintAndLogEx(WARNING, "Error: Wrong AFL length: %d", AFL->len);
959 break;
960 }
961
962 for (int i = 0; i < AFL->len / 4; i++) {
963 uint8_t SFI = AFL->value[i * 4 + 0] >> 3;
964 uint8_t SFIstart = AFL->value[i * 4 + 1];
965 uint8_t SFIend = AFL->value[i * 4 + 2];
966 uint8_t SFIoffline = AFL->value[i * 4 + 3];
967
968 PrintAndLogEx(NORMAL, "* * SFI[%02x] start:%02x end:%02x offline count:%02x", SFI, SFIstart, SFIend, SFIoffline);
969 if (SFI == 0 || SFI == 31 || SFIstart == 0 || SFIstart > SFIend) {
970 PrintAndLogEx(NORMAL, "SFI ERROR! Skipped...");
971 continue;
972 }
973
974 for(int n = SFIstart; n <= SFIend; n++) {
975 PrintAndLogEx(NORMAL, "* * * SFI[%02x] %d", SFI, n);
976
977 res = EMVReadRecord(channel, true, SFI, n, buf, sizeof(buf), &len, &sw, tlvRoot);
978 if (res) {
979 PrintAndLogEx(WARNING, "Error SFI[%02x]. APDU error %4x", SFI, sw);
980 continue;
981 }
982
983 if (decodeTLV) {
984 TLVPrintFromBuffer(buf, len);
985 PrintAndLogEx(NORMAL, "");
986 }
987
988 // Build Input list for Offline Data Authentication
989 // EMV 4.3 book3 10.3, page 96
990 if (SFIoffline > 0) {
991 if (SFI < 11) {
992 const unsigned char *abuf = buf;
993 size_t elmlen = len;
994 struct tlv e;
995 if (tlv_parse_tl(&abuf, &elmlen, &e)) {
996 memcpy(&ODAiList[ODAiListLen], &buf[len - elmlen], elmlen);
997 ODAiListLen += elmlen;
998 } else {
999 PrintAndLogEx(WARNING, "Error SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI);
1000 }
1001 } else {
1002 memcpy(&ODAiList[ODAiListLen], buf, len);
1003 ODAiListLen += len;
1004 }
1005
1006 SFIoffline--;
1007 }
1008 }
1009 }
1010
1011 break;
1012 }
1013
1014 // copy Input list for Offline Data Authentication
1015 if (ODAiListLen) {
1016 struct tlvdb *oda = tlvdb_fixed(0x21, ODAiListLen, ODAiList); // not a standard tag
1017 tlvdb_add(tlvRoot, oda);
1018 PrintAndLogEx(NORMAL, "* Input list for Offline Data Authentication added to TLV. len=%d \n", ODAiListLen);
1019 }
1020
1021 // get AIP
1022 uint16_t AIP = 0;
1023 const struct tlv *AIPtlv = tlvdb_get(tlvRoot, 0x82, NULL);
1024 if (AIPtlv) {
1025 AIP = AIPtlv->value[0] + AIPtlv->value[1] * 0x100;
1026 PrintAndLogEx(NORMAL, "* * AIP=%04x", AIP);
1027 } else {
1028 PrintAndLogEx(ERR, "Can't found AIP.");
1029 }
1030
1031 // SDA
1032 if (AIP & 0x0040) {
1033 PrintAndLogEx(NORMAL, "\n* SDA");
1034 trSDA(tlvRoot);
1035 }
1036
1037 // DDA
1038 if (AIP & 0x0020) {
1039 PrintAndLogEx(NORMAL, "\n* DDA");
1040 trDDA(channel, decodeTLV, tlvRoot);
1041 }
1042
1043 // transaction check
1044
1045 // qVSDC
1046 if (TrType == TT_QVSDCMCHIP|| TrType == TT_CDA){
1047 // 9F26: Application Cryptogram
1048 const struct tlv *AC = tlvdb_get(tlvRoot, 0x9F26, NULL);
1049 if (AC) {
1050 PrintAndLogEx(NORMAL, "\n--> qVSDC transaction.");
1051 PrintAndLogEx(NORMAL, "* AC path");
1052
1053 // 9F36: Application Transaction Counter (ATC)
1054 const struct tlv *ATC = tlvdb_get(tlvRoot, 0x9F36, NULL);
1055 if (ATC) {
1056
1057 // 9F10: Issuer Application Data - optional
1058 const struct tlv *IAD = tlvdb_get(tlvRoot, 0x9F10, NULL);
1059
1060 // print AC data
1061 PrintAndLogEx(NORMAL, "ATC: %s", sprint_hex(ATC->value, ATC->len));
1062 PrintAndLogEx(NORMAL, "AC: %s", sprint_hex(AC->value, AC->len));
1063 if (IAD){
1064 PrintAndLogEx(NORMAL, "IAD: %s", sprint_hex(IAD->value, IAD->len));
1065
1066 if (IAD->len >= IAD->value[0] + 1) {
1067 PrintAndLogEx(NORMAL, "\tKey index: 0x%02x", IAD->value[1]);
1068 PrintAndLogEx(NORMAL, "\tCrypto ver: 0x%02x(%03d)", IAD->value[2], IAD->value[2]);
1069 PrintAndLogEx(NORMAL, "\tCVR:", sprint_hex(&IAD->value[3], IAD->value[0] - 2));
1070 struct tlvdb * cvr = tlvdb_fixed(0x20, IAD->value[0] - 2, &IAD->value[3]);
1071 TLVPrintFromTLVLev(cvr, 1);
1072 }
1073 } else {
1074 PrintAndLogEx(WARNING, "IAD not found.");
1075 }
1076
1077 } else {
1078 PrintAndLogEx(ERR, "AC: Application Transaction Counter (ATC) not found.");
1079 }
1080 }
1081 }
1082
1083 // Mastercard M/CHIP
1084 if (GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD && (TrType == TT_QVSDCMCHIP || TrType == TT_CDA)){
1085 const struct tlv *CDOL1 = tlvdb_get(tlvRoot, 0x8c, NULL);
1086 if (CDOL1 && GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD) { // and m/chip transaction flag
1087 PrintAndLogEx(NORMAL, "\n--> Mastercard M/Chip transaction.");
1088
1089 PrintAndLogEx(NORMAL, "* * Generate challenge");
1090 res = EMVGenerateChallenge(channel, true, buf, sizeof(buf), &len, &sw, tlvRoot);
1091 if (res) {
1092 PrintAndLogEx(WARNING, "GetChallenge. APDU error %4x", sw);
1093 dreturn(6);
1094 }
1095 if (len < 4) {
1096 PrintAndLogEx(WARNING, "GetChallenge. Wrong challenge length %d", len);
1097 dreturn(6);
1098 }
1099
1100 // ICC Dynamic Number
1101 struct tlvdb * ICCDynN = tlvdb_fixed(0x9f4c, len, buf);
1102 tlvdb_add(tlvRoot, ICCDynN);
1103 if (decodeTLV){
1104 PrintAndLogEx(NORMAL, "\n* * ICC Dynamic Number:");
1105 TLVPrintFromTLV(ICCDynN);
1106 }
1107
1108 PrintAndLogEx(NORMAL, "* * Calc CDOL1");
1109 struct tlv *cdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8c, NULL), tlvRoot, 0x01); // 0x01 - dummy tag
1110 if (!cdol_data_tlv){
1111 PrintAndLogEx(WARNING, "Error: can't create CDOL1 TLV.");
1112 dreturn(6);
1113 }
1114 PrintAndLogEx(NORMAL, "CDOL1 data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len));
1115
1116 PrintAndLogEx(NORMAL, "* * AC1");
1117 // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD
1118 res = EMVAC(channel, 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);
1119
1120 if (res) {
1121 PrintAndLogEx(NORMAL, "AC1 error(%d): %4x. Exit...", res, sw);
1122 dreturn(7);
1123 }
1124
1125 if (decodeTLV)
1126 TLVPrintFromBuffer(buf, len);
1127
1128 // CDA
1129 PrintAndLogEx(NORMAL, "\n* CDA:");
1130 struct tlvdb *ac_tlv = tlvdb_parse_multi(buf, len);
1131 res = trCDA(tlvRoot, ac_tlv, pdol_data_tlv, cdol_data_tlv);
1132 if (res) {
1133 PrintAndLogEx(NORMAL, "CDA error (%d)", res);
1134 }
1135 free(ac_tlv);
1136 free(cdol_data_tlv);
1137
1138 PrintAndLogEx(NORMAL, "\n* M/Chip transaction result:");
1139 // 9F27: Cryptogram Information Data (CID)
1140 const struct tlv *CID = tlvdb_get(tlvRoot, 0x9F27, NULL);
1141 if (CID) {
1142 emv_tag_dump(CID, stdout, 0);
1143 PrintAndLogEx(NORMAL, "------------------------------");
1144 if (CID->len > 0) {
1145 switch(CID->value[0] & EMVAC_AC_MASK){
1146 case EMVAC_AAC:
1147 PrintAndLogEx(NORMAL, "Transaction DECLINED.");
1148 break;
1149 case EMVAC_TC:
1150 PrintAndLogEx(NORMAL, "Transaction approved OFFLINE.");
1151 break;
1152 case EMVAC_ARQC:
1153 PrintAndLogEx(NORMAL, "Transaction approved ONLINE.");
1154 break;
1155 default:
1156 PrintAndLogEx(WARNING, "Error: CID transaction code error %2x", CID->value[0] & EMVAC_AC_MASK);
1157 break;
1158 }
1159 } else {
1160 PrintAndLogEx(WARNING, "Wrong CID length %d", CID->len);
1161 }
1162 } else {
1163 PrintAndLogEx(WARNING, "CID(9F27) not found.");
1164 }
1165
1166 }
1167 }
1168
1169 // MSD
1170 if (AIP & 0x8000 && TrType == TT_MSD) {
1171 PrintAndLogEx(NORMAL, "\n--> MSD transaction.");
1172
1173 PrintAndLogEx(NORMAL, "* MSD dCVV path. Check dCVV");
1174
1175 const struct tlv *track2 = tlvdb_get(tlvRoot, 0x57, NULL);
1176 if (track2) {
1177 PrintAndLogEx(NORMAL, "Track2: %s", sprint_hex(track2->value, track2->len));
1178
1179 struct tlvdb *dCVV = GetdCVVRawFromTrack2(track2);
1180 PrintAndLogEx(NORMAL, "dCVV raw data:");
1181 TLVPrintFromTLV(dCVV);
1182
1183 if (GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD) {
1184 PrintAndLogEx(NORMAL, "\n* Mastercard calculate UDOL");
1185
1186 // UDOL (9F69)
1187 const struct tlv *UDOL = tlvdb_get(tlvRoot, 0x9F69, NULL);
1188 // UDOL(9F69) default: 9F6A (Unpredictable number) 4 bytes
1189 const struct tlv defUDOL = {
1190 .tag = 0x01,
1191 .len = 3,
1192 .value = (uint8_t *)"\x9f\x6a\x04",
1193 };
1194 if (!UDOL)
1195 PrintAndLogEx(NORMAL, "Use default UDOL.");
1196
1197 struct tlv *udol_data_tlv = dol_process(UDOL ? UDOL : &defUDOL, tlvRoot, 0x01); // 0x01 - dummy tag
1198 if (!udol_data_tlv){
1199 PrintAndLogEx(WARNING, "can't create UDOL TLV.");
1200 dreturn(8);
1201 }
1202
1203 PrintAndLogEx(NORMAL, "UDOL data[%d]: %s", udol_data_tlv->len, sprint_hex(udol_data_tlv->value, udol_data_tlv->len));
1204
1205 PrintAndLogEx(NORMAL, "\n* Mastercard compute cryptographic checksum(UDOL)");
1206
1207 res = MSCComputeCryptoChecksum(channel, true, (uint8_t *)udol_data_tlv->value, udol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot);
1208 if (res) {
1209 PrintAndLogEx(WARNING, "Compute Crypto Checksum. APDU error %4x", sw);
1210 free(udol_data_tlv);
1211 dreturn(9);
1212 }
1213
1214 // Mastercard compute cryptographic checksum result
1215 TLVPrintFromBuffer(buf, len);
1216 PrintAndLogEx(NORMAL, "");
1217
1218 free(udol_data_tlv);
1219
1220 }
1221 } else {
1222 PrintAndLogEx(WARNING, "MSD: Track2 data not found.");
1223 }
1224 }
1225
1226 // VSDC
1227 if (GetCardPSVendor(AID, AIDlen) == CV_VISA && (TrType == TT_VSDC || TrType == TT_CDA)){
1228 PrintAndLogEx(NORMAL, "\n--> VSDC transaction.");
1229
1230 PrintAndLogEx(NORMAL, "* * Calc CDOL1");
1231 struct tlv *cdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8c, NULL), tlvRoot, 0x01); // 0x01 - dummy tag
1232 if (!cdol_data_tlv) {
1233 PrintAndLogEx(WARNING, "Error: can't create CDOL1 TLV.");
1234 dreturn(6);
1235 }
1236
1237 PrintAndLogEx(NORMAL, "CDOL1 data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len));
1238
1239 PrintAndLogEx(NORMAL, "* * AC1");
1240 // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD
1241 res = EMVAC(channel, 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);
1242
1243 if (res) {
1244 PrintAndLogEx(NORMAL, "AC1 error(%d): %4x. Exit...", res, sw);
1245 dreturn(7);
1246 }
1247
1248 // process Format1 (0x80) and print Format2 (0x77)
1249 ProcessACResponseFormat1(tlvRoot, buf, len, decodeTLV);
1250
1251 PrintAndLogEx(NORMAL, "\n* * Processing online request\n");
1252
1253 // authorization response code from acquirer
1254 const char HostResponse[] = "00"; //0 x3030
1255 PrintAndLogEx(NORMAL, "* * Host Response: `%s`", HostResponse);
1256 tlvdb_change_or_add_node(tlvRoot, 0x8a, sizeof(HostResponse) - 1, (const unsigned char *)HostResponse);
1257
1258 }
1259
1260 if (channel == ECC_CONTACTLESS) {
1261 DropField();
1262 }
1263
1264 // Destroy TLV's
1265 free(pdol_data_tlv);
1266 tlvdb_free(tlvSelect);
1267 tlvdb_free(tlvRoot);
1268
1269 PrintAndLogEx(NORMAL, "\n* Transaction completed.");
1270 return 0;
1271 }
1272
1273 int CmdEMVScan(const char *cmd) {
1274 uint8_t AID[APDU_DATA_LEN] = {0};
1275 size_t AIDlen = 0;
1276 uint8_t buf[APDU_RESPONSE_LEN] = {0};
1277 size_t len = 0;
1278 uint16_t sw = 0;
1279 int res;
1280 json_t *root;
1281 json_error_t error;
1282
1283 CLIParserInit("emv scan",
1284 "Scan EMV card and save it contents to a file.",
1285 "It executes EMV contactless transaction and saves result to a file which can be used for emulation\n"
1286 "Usage:\n\temv scan -at -> scan MSD transaction mode and show APDU and TLV\n"
1287 "\temv scan -c -> scan CDA transaction mode\n");
1288
1289 void* argtable[] = {
1290 arg_param_begin,
1291 arg_lit0("aA", "apdu", "show APDU reqests and responses."),
1292 arg_lit0("tT", "tlv", "TLV decode results."),
1293 arg_lit0("eE", "extract", "Extract TLV elements and fill Application Data"),
1294 arg_lit0("jJ", "jload", "Load transaction parameters from `emv/defparams.json` file."),
1295 arg_rem("By default:", "Transaction type - MSD"),
1296 arg_lit0("vV", "qvsdc", "Transaction type - qVSDC or M/Chip."),
1297 arg_lit0("cC", "qvsdccda", "Transaction type - qVSDC or M/Chip plus CDA (SDAD generation)."),
1298 arg_lit0("xX", "vsdc", "Transaction type - VSDC. For test only. Not a standart behavior."),
1299 arg_lit0("gG", "acgpo", "VISA. generate AC from GPO."),
1300 arg_lit0("mM", "merge", "Merge output file with card's data. (warning: the file may be corrupted!)"),
1301 #ifdef WITH_SMARTCARD
1302 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
1303 #endif
1304 arg_str1(NULL, NULL, "output.json", "JSON output file name"),
1305 arg_param_end
1306 };
1307 CLIExecWithReturn(cmd, argtable, true);
1308
1309 bool showAPDU = arg_get_lit(1);
1310 bool decodeTLV = arg_get_lit(2);
1311 bool extractTLVElements = arg_get_lit(3);
1312 bool paramLoadJSON = arg_get_lit(4);
1313
1314 enum TransactionType TrType = TT_MSD;
1315 if (arg_get_lit(6))
1316 TrType = TT_QVSDCMCHIP;
1317 if (arg_get_lit(7))
1318 TrType = TT_CDA;
1319 if (arg_get_lit(8))
1320 TrType = TT_VSDC;
1321
1322 bool GenACGPO = arg_get_lit(9);
1323 bool MergeJSON = arg_get_lit(10);
1324 EMVCommandChannel channel = ECC_CONTACTLESS;
1325 uint8_t relfname[250] = {0};
1326 char *crelfname = (char *)relfname;
1327 int relfnamelen = 0;
1328 #ifdef WITH_SMARTCARD
1329 if (arg_get_lit(11)) {
1330 channel = ECC_CONTACT;
1331 }
1332 CLIGetStrWithReturn(12, relfname, &relfnamelen);
1333 #else
1334 CLIGetStrWithReturn(11, relfname, &relfnamelen);
1335 #endif
1336 PrintChannel(channel);
1337 uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2;
1338 CLIParserFree();
1339
1340 SetAPDULogging(showAPDU);
1341
1342 // TODO
1343 if (channel == ECC_CONTACT) {
1344 PrintAndLogEx(ERR, "Do not use contact interface. Exit.");
1345 return 1;
1346 }
1347
1348 // current path + file name
1349 if (!strstr(crelfname, ".json"))
1350 strcat(crelfname, ".json");
1351 char fname[strlen(get_my_executable_directory()) + strlen(crelfname) + 1];
1352 strcpy(fname, get_my_executable_directory());
1353 strcat(fname, crelfname);
1354
1355 if (MergeJSON) {
1356 root = json_load_file(fname, 0, &error);
1357 if (!root) {
1358 PrintAndLogEx(ERR, "json error on line %d: %s", error.line, error.text);
1359 return 1;
1360 }
1361
1362 if (!json_is_object(root)) {
1363 PrintAndLogEx(ERR, "Invalid json format. root must be an object.");
1364 return 1;
1365 }
1366 } else {
1367 root = json_object();
1368 }
1369
1370 // drop field at start
1371 if (channel == ECC_CONTACTLESS) {
1372 DropField();
1373 }
1374
1375 // iso 14443 select
1376 PrintAndLogEx(NORMAL, "--> GET UID, ATS.");
1377
1378 iso14a_card_select_t card;
1379 if (Hf14443_4aGetCardData(&card)) {
1380 return 2;
1381 }
1382
1383 JsonSaveStr(root, "$.File.Created", "proxmark3 `emv scan`");
1384
1385 JsonSaveStr(root, "$.Card.Communication", "iso14443-4a");
1386 JsonSaveBufAsHex(root, "$.Card.UID", (uint8_t *)&card.uid, card.uidlen);
1387 JsonSaveHex(root, "$.Card.ATQA", card.atqa[0] + (card.atqa[1] << 2), 2);
1388 JsonSaveHex(root, "$.Card.SAK", card.sak, 0);
1389 JsonSaveBufAsHex(root, "$.Card.ATS", (uint8_t *)card.ats, card.ats_len);
1390
1391 // init applets list tree
1392 const char *al = "Applets list";
1393 struct tlvdb *tlvSelect = tlvdb_fixed(1, strlen(al), (const unsigned char *)al);
1394
1395 // EMV PPSE
1396 PrintAndLogEx(NORMAL, "--> PPSE.");
1397 res = EMVSelectPSE(channel, true, true, 2, buf, sizeof(buf), &len, &sw);
1398
1399 if (!res && sw == 0x9000){
1400 if (decodeTLV)
1401 TLVPrintFromBuffer(buf, len);
1402
1403 JsonSaveBufAsHex(root, "$.PPSE.AID", (uint8_t *)"2PAY.SYS.DDF01", 14);
1404
1405 struct tlvdb *fci = tlvdb_parse_multi(buf, len);
1406 if (extractTLVElements)
1407 JsonSaveTLVTree(root, root, "$.PPSE.FCITemplate", fci);
1408 else
1409 JsonSaveTLVTreeElm(root, "$.PPSE.FCITemplate", fci, true, true, false);
1410 JsonSaveTLVValue(root, "$.Application.KernelID", tlvdb_find_full(fci, 0x9f2a));
1411 tlvdb_free(fci);
1412 }
1413
1414 res = EMVSearchPSE(channel, false, true, psenum, decodeTLV, tlvSelect);
1415
1416 // check PPSE and select application id
1417 if (!res) {
1418 TLVPrintAIDlistFromSelectTLV(tlvSelect);
1419 } else {
1420 // EMV SEARCH with AID list
1421 SetAPDULogging(false);
1422 PrintAndLogEx(NORMAL, "--> AID search.");
1423 if (EMVSearch(channel, false, true, decodeTLV, tlvSelect)) {
1424 PrintAndLogEx(ERR, "Can't found any of EMV AID. Exit...");
1425 tlvdb_free(tlvSelect);
1426 DropField();
1427 return 3;
1428 }
1429
1430 // check search and select application id
1431 TLVPrintAIDlistFromSelectTLV(tlvSelect);
1432 }
1433
1434 // EMV SELECT application
1435 SetAPDULogging(showAPDU);
1436 EMVSelectApplication(tlvSelect, AID, &AIDlen);
1437
1438 tlvdb_free(tlvSelect);
1439
1440 if (!AIDlen) {
1441 PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit...");
1442 if (channel == ECC_CONTACTLESS) {
1443 DropField();
1444 }
1445 return 4;
1446 }
1447
1448 JsonSaveBufAsHex(root, "$.Application.AID", AID, AIDlen);
1449
1450 // Init TLV tree
1451 const char *alr = "Root terminal TLV tree";
1452 struct tlvdb *tlvRoot = tlvdb_fixed(1, strlen(alr), (const unsigned char *)alr);
1453
1454 // EMV SELECT applet
1455
1456 PrintAndLogEx(NORMAL, "\n-->Selecting AID:%s.", sprint_hex_inrow(AID, AIDlen));
1457 SetAPDULogging(showAPDU);
1458 res = EMVSelect(channel, false, true, AID, AIDlen, buf, sizeof(buf), &len, &sw, tlvRoot);
1459
1460 if (res) {
1461 PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res);
1462 tlvdb_free(tlvRoot);
1463 DropField();
1464 return 5;
1465 }
1466
1467 if (decodeTLV)
1468 TLVPrintFromBuffer(buf, len);
1469
1470 // save mode
1471 if (tlvdb_get(tlvRoot, 0x9f38, NULL)) {
1472 JsonSaveStr(root, "$.Application.Mode", TransactionTypeStr[TrType]);
1473 }
1474
1475 struct tlvdb *fci = tlvdb_parse_multi(buf, len);
1476 if (extractTLVElements)
1477 JsonSaveTLVTree(root, root, "$.Application.FCITemplate", fci);
1478 else
1479 JsonSaveTLVTreeElm(root, "$.Application.FCITemplate", fci, true, true, false);
1480 tlvdb_free(fci);
1481
1482 // create transaction parameters
1483 PrintAndLogEx(NORMAL, "-->Init transaction parameters.");
1484 InitTransactionParameters(tlvRoot, paramLoadJSON, TrType, GenACGPO);
1485
1486 PrintAndLogEx(NORMAL, "-->Calc PDOL.");
1487 struct tlv *pdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x9f38, NULL), tlvRoot, 0x83);
1488 if (!pdol_data_tlv){
1489 PrintAndLogEx(ERR, "Can't create PDOL TLV.");
1490 tlvdb_free(tlvRoot);
1491 if (channel == ECC_CONTACTLESS) {
1492 DropField();
1493 }
1494 return 6;
1495 }
1496
1497 size_t pdol_data_tlv_data_len;
1498 unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len);
1499 if (!pdol_data_tlv_data) {
1500 PrintAndLogEx(ERR, "Can't create PDOL data.");
1501 tlvdb_free(tlvRoot);
1502 DropField();
1503 return 6;
1504 }
1505 PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len));
1506
1507 PrintAndLogEx(INFO, "-->GPO.");
1508 res = EMVGPO(channel, true, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot);
1509
1510 free(pdol_data_tlv_data);
1511 free(pdol_data_tlv);
1512
1513 if (res) {
1514 PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw);
1515 tlvdb_free(tlvRoot);
1516 if (channel == ECC_CONTACTLESS) {
1517 DropField();
1518 }
1519 return 7;
1520 }
1521 ProcessGPOResponseFormat1(tlvRoot, buf, len, decodeTLV);
1522
1523 struct tlvdb *gpofci = tlvdb_parse_multi(buf, len);
1524 if (extractTLVElements)
1525 JsonSaveTLVTree(root, root, "$.Application.GPO", gpofci);
1526 else
1527 JsonSaveTLVTreeElm(root, "$.Application.GPO", gpofci, true, true, false);
1528
1529 JsonSaveTLVValue(root, "$.ApplicationData.AIP", tlvdb_find_full(gpofci, 0x82));
1530 JsonSaveTLVValue(root, "$.ApplicationData.AFL", tlvdb_find_full(gpofci, 0x94));
1531
1532 tlvdb_free(gpofci);
1533
1534 PrintAndLogEx(INFO, "-->Read records from AFL.");
1535 const struct tlv *AFL = tlvdb_get(tlvRoot, 0x94, NULL);
1536
1537 while(AFL && AFL->len) {
1538 if (AFL->len % 4) {
1539 PrintAndLogEx(ERR, "Wrong AFL length: %d", AFL->len);
1540 break;
1541 }
1542
1543 json_t *sfijson = json_path_get(root, "$.Application.Records");
1544 if (!sfijson) {
1545 json_t *app = json_path_get(root, "$.Application");
1546 json_object_set_new(app, "Records", json_array());
1547
1548 sfijson = json_path_get(root, "$.Application.Records");
1549 }
1550 if (!json_is_array(sfijson)) {
1551 PrintAndLogEx(ERR, "Internal logic error. `$.Application.Records` is not an array.");
1552 break;
1553 }
1554 for (int i = 0; i < AFL->len / 4; i++) {
1555 uint8_t SFI = AFL->value[i * 4 + 0] >> 3;
1556 uint8_t SFIstart = AFL->value[i * 4 + 1];
1557 uint8_t SFIend = AFL->value[i * 4 + 2];
1558 uint8_t SFIoffline = AFL->value[i * 4 + 3];
1559
1560 PrintAndLogEx(INFO, "--->SFI[%02x] start:%02x end:%02x offline:%02x", SFI, SFIstart, SFIend, SFIoffline);
1561 if (SFI == 0 || SFI == 31 || SFIstart == 0 || SFIstart > SFIend) {
1562 PrintAndLogEx(ERR, "SFI ERROR! Skipped...");
1563 continue;
1564 }
1565
1566 for(int n = SFIstart; n <= SFIend; n++) {
1567 PrintAndLogEx(INFO, "---->SFI[%02x] %d", SFI, n);
1568
1569 res = EMVReadRecord(channel, true, SFI, n, buf, sizeof(buf), &len, &sw, tlvRoot);
1570 if (res) {
1571 PrintAndLogEx(ERR, "SFI[%02x]. APDU error %4x", SFI, sw);
1572 continue;
1573 }
1574
1575 if (decodeTLV) {
1576 TLVPrintFromBuffer(buf, len);
1577 PrintAndLogEx(NORMAL, "");
1578 }
1579
1580 json_t *jsonelm = json_object();
1581 json_array_append_new(sfijson, jsonelm);
1582
1583 JsonSaveHex(jsonelm, "SFI", SFI, 1);
1584 JsonSaveHex(jsonelm, "RecordNum", n, 1);
1585 JsonSaveHex(jsonelm, "Offline", SFIoffline, 1);
1586
1587 struct tlvdb *rsfi = tlvdb_parse_multi(buf, len);
1588 if (extractTLVElements)
1589 JsonSaveTLVTree(root, jsonelm, "$.Data", rsfi);
1590 else
1591 JsonSaveTLVTreeElm(jsonelm, "$.Data", rsfi, true, true, false);
1592 tlvdb_free(rsfi);
1593 }
1594 }
1595
1596 break;
1597 }
1598
1599 // getting certificates
1600 if (tlvdb_get(tlvRoot, 0x90, NULL)) {
1601 PrintAndLogEx(INFO, "-->Recovering certificates.");
1602 PKISetStrictExecution(false);
1603 RecoveryCertificates(tlvRoot, root);
1604 PKISetStrictExecution(true);
1605 }
1606
1607 // free tlv object
1608 tlvdb_free(tlvRoot);
1609
1610 if (channel == ECC_CONTACTLESS) {
1611 DropField();
1612 }
1613
1614 res = json_dump_file(root, fname, JSON_INDENT(2));
1615 if (res) {
1616 PrintAndLogEx(ERR, "Can't save the file: %s", fname);
1617 return 200;
1618 }
1619 PrintAndLogEx(SUCCESS, "File `%s` saved.", fname);
1620
1621 // free json object
1622 json_decref(root);
1623
1624 return 0;
1625 }
1626
1627 int CmdEMVTest(const char *cmd) {
1628 return ExecuteCryptoTests(true);
1629 }
1630
1631 int CmdEMVRoca(const char *cmd) {
1632 uint8_t AID[APDU_DATA_LEN] = {0};
1633 size_t AIDlen = 0;
1634 uint8_t buf[APDU_RESPONSE_LEN] = {0};
1635 size_t len = 0;
1636 uint16_t sw = 0;
1637 int res;
1638
1639 CLIParserInit("emv roca",
1640 "Tries to extract public keys and run the ROCA test against them.\n",
1641 "Usage:\n"
1642 "\temv roca -w -> select --CONTACT-- card and run test\n"
1643 "\temv roca -> select --CONTACTLESS-- card and run test\n"
1644 );
1645
1646 void* argtable[] = {
1647 arg_param_begin,
1648 arg_lit0("tT", "selftest", "self test"),
1649 arg_lit0("wW", "wired", "Send data via contact (iso7816) interface. Contactless interface set by default."),
1650 arg_param_end
1651 };
1652 CLIExecWithReturn(cmd, argtable, true);
1653
1654 EMVCommandChannel channel = ECC_CONTACTLESS;
1655 if (arg_get_lit(1))
1656 return roca_self_test();
1657 #ifdef WITH_SMARTCARD
1658 if (arg_get_lit(2))
1659 channel = ECC_CONTACT;
1660 #endif
1661 PrintChannel(channel);
1662
1663 // select card
1664 uint8_t psenum = (channel == ECC_CONTACT) ? 1 : 2;
1665 char *PSE_or_PPSE = psenum == 1 ? "PSE" : "PPSE";
1666
1667 SetAPDULogging(false);
1668
1669 // init applets list tree
1670 const char *al = "Applets list";
1671 struct tlvdb *tlvSelect = tlvdb_fixed(1, strlen(al), (const unsigned char *)al);
1672
1673 // EMV PSE/PPSE
1674 PrintAndLogEx(NORMAL, "--> %s.", PSE_or_PPSE);
1675 res = EMVSearchPSE(channel, true, true, psenum, false, tlvSelect);
1676
1677 // check PSE/PPSE and select application id
1678 if (!res) {
1679 TLVPrintAIDlistFromSelectTLV(tlvSelect);
1680 } else {
1681 // EMV SEARCH with AID list
1682 PrintAndLogEx(NORMAL, "--> AID search.");
1683 if (EMVSearch(channel, false, true, false, tlvSelect)) {
1684 PrintAndLogEx(ERR, "Couldn't find any known EMV AID. Exit...");
1685 tlvdb_free(tlvSelect);
1686 DropField();
1687 return 3;
1688 }
1689
1690 // check search and select application id
1691 TLVPrintAIDlistFromSelectTLV(tlvSelect);
1692 }
1693
1694 // EMV SELECT application
1695 SetAPDULogging(true);
1696 EMVSelectApplication(tlvSelect, AID, &AIDlen);
1697
1698 tlvdb_free(tlvSelect);
1699
1700 if (!AIDlen) {
1701 PrintAndLogEx(INFO, "Can't select AID. EMV AID not found. Exit...");
1702 if (channel == ECC_CONTACTLESS) {
1703 DropField();
1704 }
1705 return 4;
1706 }
1707
1708 // Init TLV tree
1709 const char *alr = "Root terminal TLV tree";
1710 struct tlvdb *tlvRoot = tlvdb_fixed(1, strlen(alr), (const unsigned char *)alr);
1711
1712 // EMV SELECT applet
1713 PrintAndLogEx(NORMAL, "\n-->Selecting AID:%s.", sprint_hex_inrow(AID, AIDlen));
1714 res = EMVSelect(channel, false, true, AID, AIDlen, buf, sizeof(buf), &len, &sw, tlvRoot);
1715
1716 if (res) {
1717 PrintAndLogEx(ERR, "Can't select AID (%d). Exit...", res);
1718 tlvdb_free(tlvRoot);
1719 if (channel == ECC_CONTACTLESS) {
1720 DropField();
1721 }
1722 return 5;
1723 }
1724
1725 PrintAndLog("\n* Init transaction parameters.");
1726 InitTransactionParameters(tlvRoot, true, TT_QVSDCMCHIP, false);
1727
1728 PrintAndLogEx(NORMAL, "-->Calc PDOL.");
1729 struct tlv *pdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x9f38, NULL), tlvRoot, 0x83);
1730 if (!pdol_data_tlv){
1731 PrintAndLogEx(ERR, "Can't create PDOL TLV.");
1732 tlvdb_free(tlvRoot);
1733 if (channel == ECC_CONTACTLESS) {
1734 DropField();
1735 }
1736 return 6;
1737 }
1738
1739 size_t pdol_data_tlv_data_len;
1740 unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len);
1741 if (!pdol_data_tlv_data) {
1742 PrintAndLogEx(ERR, "Can't create PDOL data.");
1743 tlvdb_free(tlvRoot);
1744 DropField();
1745 return 6;
1746 }
1747 PrintAndLogEx(INFO, "PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len));
1748
1749 PrintAndLogEx(INFO, "-->GPO.");
1750 res = EMVGPO(channel, true, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot);
1751
1752 free(pdol_data_tlv_data);
1753 free(pdol_data_tlv);
1754
1755 if (res) {
1756 PrintAndLogEx(ERR, "GPO error(%d): %4x. Exit...", res, sw);
1757 tlvdb_free(tlvRoot);
1758 if (channel == ECC_CONTACTLESS) {
1759 DropField();
1760 }
1761 return 7;
1762 }
1763 ProcessGPOResponseFormat1(tlvRoot, buf, len, false);
1764
1765 PrintAndLogEx(INFO, "-->Read records from AFL.");
1766 const struct tlv *AFL = tlvdb_get(tlvRoot, 0x94, NULL);
1767
1768 while(AFL && AFL->len) {
1769 if (AFL->len % 4) {
1770 PrintAndLogEx(ERR, "Wrong AFL length: %d", AFL->len);
1771 break;
1772 }
1773
1774 for (int i = 0; i < AFL->len / 4; i++) {
1775 uint8_t SFI = AFL->value[i * 4 + 0] >> 3;
1776 uint8_t SFIstart = AFL->value[i * 4 + 1];
1777 uint8_t SFIend = AFL->value[i * 4 + 2];
1778 uint8_t SFIoffline = AFL->value[i * 4 + 3];
1779
1780 PrintAndLogEx(INFO, "--->SFI[%02x] start:%02x end:%02x offline:%02x", SFI, SFIstart, SFIend, SFIoffline);
1781 if (SFI == 0 || SFI == 31 || SFIstart == 0 || SFIstart > SFIend) {
1782 PrintAndLogEx(ERR, "SFI ERROR! Skipped...");
1783 continue;
1784 }
1785
1786 for(int n = SFIstart; n <= SFIend; n++) {
1787 PrintAndLogEx(INFO, "---->SFI[%02x] %d", SFI, n);
1788
1789 res = EMVReadRecord(channel, true, SFI, n, buf, sizeof(buf), &len, &sw, tlvRoot);
1790 if (res) {
1791 PrintAndLogEx(ERR, "SFI[%02x]. APDU error %4x", SFI, sw);
1792 continue;
1793 }
1794 }
1795 }
1796
1797 break;
1798 }
1799
1800 // getting certificates
1801 if (tlvdb_get(tlvRoot, 0x90, NULL)) {
1802 PrintAndLogEx(INFO, "-->Recovering certificates.");
1803 PKISetStrictExecution(false);
1804
1805 struct emv_pk *pk = get_ca_pk(tlvRoot);
1806 if (!pk) {
1807 PrintAndLogEx(ERR, "CA Public Key not found. Exit.");
1808 goto out;
1809 }
1810
1811 struct emv_pk *issuer_pk = emv_pki_recover_issuer_cert(pk, tlvRoot);
1812 if (!issuer_pk) {
1813 emv_pk_free(pk);
1814 PrintAndLogEx(WARNING, "WARNING: Issuer certificate not found. Exit.");
1815 goto out;
1816 }
1817
1818 char RID[15] = {0};
1819 memcpy(RID, sprint_hex(issuer_pk->rid, 5), 14);
1820 PrintAndLogEx(SUCCESS, "Issuer PK recovered. RID %s IDX %02hhx CSN %s",
1821 RID,
1822 issuer_pk->index,
1823 sprint_hex(issuer_pk->serial, 3)
1824 );
1825
1826
1827 struct emv_pk *icc_pk = emv_pki_recover_icc_cert(issuer_pk, tlvRoot, NULL);
1828 if (!icc_pk) {
1829 emv_pk_free(pk);
1830 emv_pk_free(issuer_pk);
1831 PrintAndLogEx(WARNING, "WARNING: ICC certificate not found. Exit.");
1832 goto out;
1833 }
1834
1835 memcpy(RID, sprint_hex(icc_pk->rid, 5), 14);
1836 PrintAndLogEx(SUCCESS, "ICC PK recovered. RID %s IDX %02hhx CSN %s\n",
1837 RID,
1838 icc_pk->index,
1839 sprint_hex(icc_pk->serial, 3)
1840 );
1841
1842 PrintAndLogEx(INFO, "ICC pk modulus: %s", sprint_hex_inrow(icc_pk->modulus, icc_pk->mlen));
1843
1844 // icc_pk->exp, icc_pk->elen
1845 // icc_pk->modulus, icc_pk->mlen
1846 if (icc_pk->elen > 0 && icc_pk->mlen > 0) {
1847 if (emv_rocacheck(icc_pk->modulus, icc_pk->mlen, true)) {
1848 PrintAndLogEx(INFO, "ICC pk is a subject to ROCA vulnerability, insecure..");
1849 } else {
1850 PrintAndLogEx(INFO, "ICC pk is OK(");
1851 }
1852 }
1853
1854 PKISetStrictExecution(true);
1855 }
1856
1857 out:
1858
1859 // free tlv object
1860 tlvdb_free(tlvRoot);
1861
1862 if (channel == ECC_CONTACTLESS) {
1863 DropField();
1864 }
1865
1866 return 0;
1867 }
1868
1869 int CmdHelp(const char *Cmd);
1870
1871 static command_t CommandTable[] = {
1872 {"help", CmdHelp, 1, "This help"},
1873 {"exec", CmdEMVExec, 1, "Executes EMV contactless transaction."},
1874 {"pse", CmdEMVPPSE, 1, "Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory."},
1875 {"search", CmdEMVSearch, 1, "Try to select all applets from applets list and print installed applets."},
1876 {"select", CmdEMVSelect, 1, "Select applet."},
1877 {"gpo", CmdEMVGPO, 1, "Execute GetProcessingOptions."},
1878 {"readrec", CmdEMVReadRecord, 1, "Read files from card."},
1879 {"genac", CmdEMVAC, 1, "Generate ApplicationCryptogram."},
1880 {"challenge", CmdEMVGenerateChallenge, 1, "Generate challenge."},
1881 {"intauth", CmdEMVInternalAuthenticate, 1, "Internal authentication."},
1882 {"scan", CmdEMVScan, 1, "Scan EMV card and save it contents to json file for emulator."},
1883 {"test", CmdEMVTest, 1, "Crypto logic test."},
1884 {"roca", CmdEMVRoca, 1, "Extract public keys and run ROCA test"},
1885 {NULL, NULL, 0, NULL}
1886 };
1887
1888 int CmdEMV(const char *Cmd) {
1889 CmdsParse(CommandTable, Cmd);
1890 return 0;
1891 }
1892
1893 int CmdHelp(const char *Cmd) {
1894 CmdsHelp(CommandTable);
1895 return 0;
1896 }
Impressum, Datenschutz