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