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