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