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