]> git.zerfleddert.de Git - proxmark3-svn/blame - client/emv/cmdemv.c
`hf emv readrec` works and some changes in help
[proxmark3-svn] / client / emv / cmdemv.c
CommitLineData
3c5fce2b
OM
1//-----------------------------------------------------------------------------
2// Copyright (C) 2017 Merlok
3//
4// This code is licensed to you under the terms of the GNU GPL, version 2 or,
5// at your option, any later version. See the LICENSE.txt file for the text of
6// the license.
7//-----------------------------------------------------------------------------
8// EMV commands
9//-----------------------------------------------------------------------------
10
3ded0f97 11#include <ctype.h>
3c5fce2b 12#include "cmdemv.h"
d03fb293 13#include "test/cryptotest.h"
6d31653c 14#include "cliparser/cliparser.h"
3c5fce2b 15
3c5fce2b
OM
16int CmdHFEMVSelect(const char *cmd) {
17 uint8_t data[APDU_AID_LEN] = {0};
18 int datalen = 0;
3c5fce2b 19
3c5fce2b 20
3668df05 21 CLIParserInit("hf 14a select",
22 "Executes select applet command",
a4662ca9 23 "Usage:\n\thf emv select -s a00000000101 -> select card, select applet\n\thf emv select -st a00000000101 -> select card, select applet, show result in TLV\n");
3c5fce2b 24
3668df05 25 void* argtable[] = {
26 arg_param_begin,
27 arg_lit0("sS", "select", "activate field and select card"),
28 arg_lit0("kK", "keep", "keep field for next command"),
29 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
30 arg_lit0("tT", "tlv", "TLV decode results"),
31 arg_str0(NULL, NULL, "<HEX applet AID>", NULL),
32 arg_param_end
33 };
34 CLIExecWithReturn(cmd, argtable, true);
35
36 bool activateField = arg_get_lit(1);
37 bool leaveSignalON = arg_get_lit(2);
38 bool APDULogging = arg_get_lit(3);
39 bool decodeTLV = arg_get_lit(4);
cd2f1acd 40 CLIGetStrWithReturn(5, data, &datalen);
3668df05 41 CLIParserFree();
42
43 SetAPDULogging(APDULogging);
3c5fce2b
OM
44
45 // exec
46 uint8_t buf[APDU_RES_LEN] = {0};
47 size_t len = 0;
48 uint16_t sw = 0;
49 int res = EMVSelect(activateField, leaveSignalON, data, datalen, buf, sizeof(buf), &len, &sw, NULL);
50
51 if (sw)
52 PrintAndLog("APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
53
54 if (res)
55 return res;
56
57 if (decodeTLV)
58 TLVPrintFromBuffer(buf, len);
59
60 return 0;
61}
62
3c5fce2b
OM
63int CmdHFEMVSearch(const char *cmd) {
64
6d31653c 65 CLIParserInit("hf 14a select",
66 "Tries to select all applets from applet list:\n",
a4662ca9 67 "Usage:\n\thf emv search -s -> select card and search\n\thf emv search -st -> select card, search and show result in TLV\n");
6d31653c 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 ON for next command"),
73 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
74 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
75 arg_param_end
76 };
77 CLIExecWithReturn(cmd, argtable, true);
3c5fce2b 78
6d31653c 79 bool activateField = arg_get_lit(1);
80 bool leaveSignalON = arg_get_lit(2);
81 bool APDULogging = arg_get_lit(3);
82 bool decodeTLV = arg_get_lit(4);
3668df05 83 CLIParserFree();
6d31653c 84
85 SetAPDULogging(APDULogging);
3c5fce2b 86
3c5fce2b
OM
87 struct tlvdb *t = NULL;
88 const char *al = "Applets list";
89 t = tlvdb_fixed(1, strlen(al), (const unsigned char *)al);
90
91 if (EMVSearch(activateField, leaveSignalON, decodeTLV, t)) {
92 tlvdb_free(t);
93 return 2;
94 }
95
96 PrintAndLog("Search completed.");
97
98 // print list here
99 if (!decodeTLV) {
100 TLVPrintAIDlistFromSelectTLV(t);
101 }
102
103 tlvdb_free(t);
104
105 return 0;
106}
107
3c5fce2b
OM
108int CmdHFEMVPPSE(const char *cmd) {
109
a4662ca9 110 CLIParserInit("hf 14a pse",
111 "Executes PSE/PPSE select command. It returns list of applet on the card:\n",
112 "Usage:\n\thf emv pse -s1 -> select, get pse\n\thf emv pse -st2 -> select, get ppse, show result in TLV\n");
3c5fce2b 113
a4662ca9 114 void* argtable[] = {
115 arg_param_begin,
116 arg_lit0("sS", "select", "activate field and select card"),
117 arg_lit0("kK", "keep", "keep field ON for next command"),
118 arg_lit0("1", "pse", "pse (1PAY.SYS.DDF01) mode"),
119 arg_lit0("2", "ppse", "ppse (2PAY.SYS.DDF01) mode (default mode)"),
120 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
121 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
122 arg_param_end
123 };
124 CLIExecWithReturn(cmd, argtable, true);
125
126 bool activateField = arg_get_lit(1);
127 bool leaveSignalON = arg_get_lit(2);
128 uint8_t PSENum = 2;
129 if (arg_get_lit(3))
130 PSENum = 1;
131 if (arg_get_lit(4))
132 PSENum = 2;
133 bool APDULogging = arg_get_lit(5);
134 bool decodeTLV = arg_get_lit(6);
135 CLIParserFree();
136
137 SetAPDULogging(APDULogging);
3c5fce2b
OM
138
139 // exec
140 uint8_t buf[APDU_RES_LEN] = {0};
141 size_t len = 0;
142 uint16_t sw = 0;
143 int res = EMVSelectPSE(activateField, leaveSignalON, PSENum, buf, sizeof(buf), &len, &sw);
144
145 if (sw)
146 PrintAndLog("APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
147
148 if (res)
149 return res;
150
151
152 if (decodeTLV)
153 TLVPrintFromBuffer(buf, len);
154
155 return 0;
156}
157
ab2d91f8 158#define TLV_ADD(tag, value)( tlvdb_add(tlvRoot, tlvdb_fixed(tag, sizeof(value) - 1, (const unsigned char *)value)) )
159
a4662ca9 160int CmdHFEMVGPO(const char *cmd) {
cd2f1acd 161 uint8_t data[APDU_RES_LEN] = {0};
162 int datalen = 0;
163
164 CLIParserInit("hf 14a gpo",
ab2d91f8 165 "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.",
166 "Usage:\n\thf emv gpo -k -> execute GPO\n\thf emv gpo -st 01020304 -> execute GPO with 4-byte PDOL data, show result in TLV\n");
167 // here need to add load params from file and gen pdol
cd2f1acd 168
169 void* argtable[] = {
170 arg_param_begin,
171 arg_lit0("kK", "keep", "keep field ON for next command"),
172 arg_lit0("pP", "params", "load parameters for PDOL making from `emv/defparams.json` file (by default uses default parameters) (NOT WORK!!!)"),
173 arg_lit0("mM", "make", "make PDOLdata from PDOL (tag 9F38) and parameters (NOT WORK!!!)"),
174 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
175 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
176 arg_str0(NULL, NULL, "<HEX PDOLdata/PDOL>", NULL),
177 arg_param_end
178 };
179 CLIExecWithReturn(cmd, argtable, true);
180
181 bool leaveSignalON = arg_get_lit(1);
182 bool paramsLoadFromFile = arg_get_lit(2);
183 bool dataMakeFromPDOL = arg_get_lit(3);
184 bool APDULogging = arg_get_lit(4);
185 bool decodeTLV = arg_get_lit(5);
186 CLIGetStrWithReturn(6, data, &datalen);
187 CLIParserFree();
188
189 SetAPDULogging(APDULogging);
190
191 // Init TLV tree
192 const char *alr = "Root terminal TLV tree";
193 struct tlvdb *tlvRoot = tlvdb_fixed(1, strlen(alr), (const unsigned char *)alr);
194
195 // calc PDOL
196 struct tlv *pdol_data_tlv = NULL;
197 struct tlv data_tlv = {
198 .tag = 0x83, //was 01
199 .len = datalen,
200 .value = (uint8_t *)data,
201 };
202 if (dataMakeFromPDOL) {
203 // TODO
204 PrintAndLog("Make PDOL data not implemented!");
ab2d91f8 205
206 //9F02:(Amount, authorized (Numeric)) len:6
207 TLV_ADD(0x9F02, "\x00\x00\x00\x00\x01\x00");
208 //9F1A:(Terminal Country Code) len:2
209 TLV_ADD(0x9F1A, "ru");
210 //5F2A:(Transaction Currency Code) len:2
211 // USD 840, EUR 978, RUR 810, RUB 643, RUR 810(old), UAH 980, AZN 031, n/a 999
212 TLV_ADD(0x5F2A, "\x09\x80");
213 //9A:(Transaction Date) len:3
214 TLV_ADD(0x9A, "\x00\x00\x00");
215 //9C:(Transaction Type) len:1 | 00 => Goods and service #01 => Cash
216 TLV_ADD(0x9C, "\x00");
217 // 9F37 Unpredictable Number len:4
218 TLV_ADD(0x9F37, "\x01\x02\x03\x04");
219 // 9F6A Unpredictable Number (MSD for UDOL) len:4
220 TLV_ADD(0x9F6A, "\x01\x02\x03\x04");
221 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
222 TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC
223
cd2f1acd 224 if (paramsLoadFromFile) {
225 };
226/* pdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x9f38, NULL), tlvRoot, 0x83);
227 if (!pdol_data_tlv){
228 PrintAndLog("ERROR: can't create PDOL TLV.");
229 tlvdb_free(tlvRoot);
230 return 4;
231 }*/
232 return 0;
233 } else {
234 pdol_data_tlv = &data_tlv;
235 }
236
237 size_t pdol_data_tlv_data_len = 0;
238 unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len);
239 if (!pdol_data_tlv_data) {
240 PrintAndLog("ERROR: can't create PDOL data.");
241 tlvdb_free(tlvRoot);
242 return 4;
243 }
244 PrintAndLog("PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len));
245
246 // exec
247 uint8_t buf[APDU_RES_LEN] = {0};
248 size_t len = 0;
249 uint16_t sw = 0;
250 int res = EMVGPO(leaveSignalON, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot);
251
252 free(pdol_data_tlv_data);
253 tlvdb_free(tlvRoot);
254
255 if (sw)
256 PrintAndLog("APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
257
258 if (res)
259 return res;
260
261 if (decodeTLV)
262 TLVPrintFromBuffer(buf, len);
a4662ca9 263
626e650f 264 return 0;
a4662ca9 265}
266
267int CmdHFEMVReadRecord(const char *cmd) {
cd2f1acd 268 uint8_t data[APDU_RES_LEN] = {0};
269 int datalen = 0;
270
271 CLIParserInit("hf 14a readrec",
ab2d91f8 272 "Executes Read Record command. It returns data in TLV format.\nNeeds a bank applet to be selected and sometimes needs GPO to be executed.",
273 "Usage:\n\thf emv readrec -k 0101 -> read file SFI=01, SFIrec=01\n\thf emv readrec -kt 0201-> read file 0201 and show result in TLV\n");
cd2f1acd 274
275 void* argtable[] = {
276 arg_param_begin,
277 arg_lit0("kK", "keep", "keep field ON for next command"),
278 arg_lit0("aA", "apdu", "show APDU reqests and responses"),
279 arg_lit0("tT", "tlv", "TLV decode results of selected applets"),
ab2d91f8 280 arg_str1(NULL, NULL, "<SFI 1byte HEX><SFIrec 1byte HEX>", NULL),
cd2f1acd 281 arg_param_end
282 };
283 CLIExecWithReturn(cmd, argtable, true);
284
285 bool leaveSignalON = arg_get_lit(1);
286 bool APDULogging = arg_get_lit(2);
287 bool decodeTLV = arg_get_lit(3);
288 CLIGetStrWithReturn(4, data, &datalen);
289 CLIParserFree();
290
291 if (datalen != 2) {
292 PrintAndLog("ERROR: Command needs to have 2 bytes of data");
293 return 1;
294 }
295
296 SetAPDULogging(APDULogging);
297
298 // exec
299 uint8_t buf[APDU_RES_LEN] = {0};
300 size_t len = 0;
301 uint16_t sw = 0;
302 int res = EMVReadRecord(leaveSignalON, data[0], data[1], buf, sizeof(buf), &len, &sw, NULL);
303
304 if (sw)
305 PrintAndLog("APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
306
307 if (res)
308 return res;
309
310
311 if (decodeTLV)
312 TLVPrintFromBuffer(buf, len);
a4662ca9 313
626e650f 314 return 0;
a4662ca9 315}
316
317int CmdHFEMVAC(const char *cmd) {
318
626e650f 319 return 0;
a4662ca9 320}
321
322int CmdHFEMVGenerateChallenge(const char *cmd) {
323
626e650f 324 return 0;
a4662ca9 325}
326
327int CmdHFEMVInternalAuthenticate(const char *cmd) {
328
626e650f 329 return 0;
a4662ca9 330}
331
3c5fce2b
OM
332int UsageCmdHFEMVExec(void) {
333 PrintAndLog("HELP : Executes EMV contactless transaction:\n");
d03fb293 334 PrintAndLog("Usage: hf emv exec [-s][-a][-t][-f][-v][-c][-x][-g]\n");
3c5fce2b
OM
335 PrintAndLog(" Options:");
336 PrintAndLog(" -s : select card");
337 PrintAndLog(" -a : show APDU reqests and responses\n");
338 PrintAndLog(" -t : TLV decode results\n");
339 PrintAndLog(" -f : force search AID. Search AID instead of execute PPSE.\n");
10d4f823 340 PrintAndLog(" -v : transaction type - qVSDC or M/Chip.\n");
341 PrintAndLog(" -c : transaction type - qVSDC or M/Chip plus CDA (SDAD generation).\n");
342 PrintAndLog(" -x : transaction type - VSDC. For test only. Not a standart behavior.\n");
d03fb293 343 PrintAndLog(" -g : VISA. generate AC from GPO\n");
10d4f823 344 PrintAndLog("By default : transaction type - MSD.\n");
3c5fce2b 345 PrintAndLog("Samples:");
d03fb293
OM
346 PrintAndLog(" hf emv exec -s -a -t -> execute MSD transaction");
347 PrintAndLog(" hf emv exec -s -a -t -c -> execute CDA transaction");
3c5fce2b
OM
348 return 0;
349}
350
d03fb293 351#define dreturn(n) {free(pdol_data_tlv);tlvdb_free(tlvSelect);tlvdb_free(tlvRoot);DropField();return n;}
3c5fce2b
OM
352
353int CmdHFEMVExec(const char *cmd) {
354 bool activateField = false;
355 bool showAPDU = false;
356 bool decodeTLV = false;
357 bool forceSearch = false;
10d4f823 358 enum TransactionType TrType = TT_MSD;
d03fb293 359 bool GenACGPO = false;
3c5fce2b
OM
360
361 uint8_t buf[APDU_RES_LEN] = {0};
362 size_t len = 0;
363 uint16_t sw = 0;
364 uint8_t AID[APDU_AID_LEN] = {0};
365 size_t AIDlen = 0;
d03fb293
OM
366 uint8_t ODAiList[4096];
367 size_t ODAiListLen = 0;
3c5fce2b
OM
368
369 int res;
370
d03fb293
OM
371 struct tlvdb *tlvSelect = NULL;
372 struct tlvdb *tlvRoot = NULL;
373 struct tlv *pdol_data_tlv = NULL;
374
3c5fce2b
OM
375 if (strlen(cmd) < 1) {
376 UsageCmdHFEMVExec();
377 return 0;
378 }
379
380 int cmdp = 0;
381 while(param_getchar(cmd, cmdp) != 0x00) {
382 char c = param_getchar(cmd, cmdp);
383 if ((c == '-') && (param_getlength(cmd, cmdp) == 2))
384 switch (param_getchar_indx(cmd, 1, cmdp)) {
385 case 'h':
386 case 'H':
7a7afeba 387 UsageCmdHFEMVExec();
3c5fce2b
OM
388 return 0;
389 case 's':
390 case 'S':
391 activateField = true;
392 break;
393 case 'a':
394 case 'A':
395 showAPDU = true;
396 break;
397 case 't':
398 case 'T':
399 decodeTLV = true;
400 break;
401 case 'f':
402 case 'F':
403 forceSearch = true;
404 break;
10d4f823 405 case 'x':
406 case 'X':
407 TrType = TT_VSDC;
408 break;
409 case 'v':
410 case 'V':
411 TrType = TT_QVSDCMCHIP;
412 break;
413 case 'c':
414 case 'C':
415 TrType = TT_CDA;
416 break;
d03fb293
OM
417 case 'g':
418 case 'G':
419 GenACGPO = true;
420 break;
3c5fce2b
OM
421 default:
422 PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
423 return 1;
424 }
425 cmdp++;
426 }
427
428
429 // init applets list tree
3c5fce2b
OM
430 const char *al = "Applets list";
431 tlvSelect = tlvdb_fixed(1, strlen(al), (const unsigned char *)al);
432
433 // Application Selection
434 // https://www.openscdp.org/scripts/tutorial/emv/applicationselection.html
435 if (!forceSearch) {
436 // PPSE
437 PrintAndLog("\n* PPSE.");
438 SetAPDULogging(showAPDU);
439 res = EMVSearchPSE(activateField, true, decodeTLV, tlvSelect);
440
441 // check PPSE and select application id
442 if (!res) {
443 TLVPrintAIDlistFromSelectTLV(tlvSelect);
444 EMVSelectApplication(tlvSelect, AID, &AIDlen);
445 }
446 }
447
448 // Search
449 if (!AIDlen) {
450 PrintAndLog("\n* Search AID in list.");
451 SetAPDULogging(false);
452 if (EMVSearch(activateField, true, decodeTLV, tlvSelect)) {
d03fb293 453 dreturn(2);
3c5fce2b
OM
454 }
455
456 // check search and select application id
457 TLVPrintAIDlistFromSelectTLV(tlvSelect);
458 EMVSelectApplication(tlvSelect, AID, &AIDlen);
459 }
460
461 // Init TLV tree
3c5fce2b
OM
462 const char *alr = "Root terminal TLV tree";
463 tlvRoot = tlvdb_fixed(1, strlen(alr), (const unsigned char *)alr);
464
465 // check if we found EMV application on card
466 if (!AIDlen) {
467 PrintAndLog("Can't select AID. EMV AID not found");
d03fb293 468 dreturn(2);
3c5fce2b
OM
469 }
470
471 // Select
472 PrintAndLog("\n* Selecting AID:%s", sprint_hex_inrow(AID, AIDlen));
473 SetAPDULogging(showAPDU);
474 res = EMVSelect(false, true, AID, AIDlen, buf, sizeof(buf), &len, &sw, tlvRoot);
475
476 if (res) {
477 PrintAndLog("Can't select AID (%d). Exit...", res);
d03fb293 478 dreturn(3);
3c5fce2b
OM
479 }
480
481 if (decodeTLV)
482 TLVPrintFromBuffer(buf, len);
483 PrintAndLog("* Selected.");
484
3c5fce2b
OM
485 PrintAndLog("\n* Init transaction parameters.");
486
487 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
d03fb293
OM
488 char *qVSDC = "\x26\x00\x00\x00";
489 if (GenACGPO) {
490 qVSDC = "\x26\x80\x00\x00";
491 }
10d4f823 492 switch(TrType) {
493 case TT_MSD:
494 TLV_ADD(0x9F66, "\x86\x00\x00\x00"); // MSD
495 break;
d03fb293 496 // not standard for contactless. just for test.
10d4f823 497 case TT_VSDC:
498 TLV_ADD(0x9F66, "\x46\x00\x00\x00"); // VSDC
499 break;
500 case TT_QVSDCMCHIP:
d03fb293 501 TLV_ADD(0x9F66, qVSDC); // qVSDC
10d4f823 502 break;
503 case TT_CDA:
d03fb293 504 TLV_ADD(0x9F66, qVSDC); // qVSDC (VISA CDA not enabled)
10d4f823 505 break;
506 default:
507 TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC
508 break;
509 }
d03fb293
OM
510
511 //9F02:(Amount, authorized (Numeric)) len:6
3c5fce2b
OM
512 TLV_ADD(0x9F02, "\x00\x00\x00\x00\x01\x00");
513 //9F1A:(Terminal Country Code) len:2
514 TLV_ADD(0x9F1A, "ru");
515 //5F2A:(Transaction Currency Code) len:2
516 // USD 840, EUR 978, RUR 810, RUB 643, RUR 810(old), UAH 980, AZN 031, n/a 999
517 TLV_ADD(0x5F2A, "\x09\x80");
518 //9A:(Transaction Date) len:3
519 TLV_ADD(0x9A, "\x00\x00\x00");
520 //9C:(Transaction Type) len:1 | 00 => Goods and service #01 => Cash
521 TLV_ADD(0x9C, "\x00");
522 // 9F37 Unpredictable Number len:4
523 TLV_ADD(0x9F37, "\x01\x02\x03\x04");
66efdc1f 524 // 9F6A Unpredictable Number (MSD for UDOL) len:4
525 TLV_ADD(0x9F6A, "\x01\x02\x03\x04");
3c5fce2b 526
66efdc1f 527 TLVPrintFromTLV(tlvRoot); // TODO delete!!!
3c5fce2b
OM
528
529 PrintAndLog("\n* Calc PDOL.");
d03fb293 530 pdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x9f38, NULL), tlvRoot, 0x83);
3c5fce2b
OM
531 if (!pdol_data_tlv){
532 PrintAndLog("ERROR: can't create PDOL TLV.");
d03fb293 533 dreturn(4);
3c5fce2b
OM
534 }
535
536 size_t pdol_data_tlv_data_len;
537 unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len);
538 if (!pdol_data_tlv_data) {
539 PrintAndLog("ERROR: can't create PDOL data.");
d03fb293 540 dreturn(4);
3c5fce2b
OM
541 }
542 PrintAndLog("PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len));
543
3c5fce2b
OM
544 PrintAndLog("\n* GPO.");
545 res = EMVGPO(true, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot);
546
10d4f823 547 free(pdol_data_tlv_data);
d03fb293 548 //free(pdol_data_tlv); --- free on exit.
3c5fce2b
OM
549
550 if (res) {
551 PrintAndLog("GPO error(%d): %4x. Exit...", res, sw);
d03fb293 552 dreturn(5);
3c5fce2b
OM
553 }
554
555 // process response template format 1 [id:80 2b AIP + x4b AFL] and format 2 [id:77 TLV]
556 if (buf[0] == 0x80) {
3c5fce2b
OM
557 if (decodeTLV){
558 PrintAndLog("GPO response format1:");
559 TLVPrintFromBuffer(buf, len);
560 }
3c5fce2b 561
66efdc1f 562 if (len < 4 || (len - 4) % 4) {
563 PrintAndLog("ERROR: GPO response format1 parsing error. length=%d", len);
564 } else {
565 // AIP
566 struct tlvdb * f1AIP = tlvdb_fixed(0x82, 2, buf + 2);
567 tlvdb_add(tlvRoot, f1AIP);
568 if (decodeTLV){
569 PrintAndLog("\n* * Decode response format 1 (0x80) AIP and AFL:");
570 TLVPrintFromTLV(f1AIP);
571 }
572
573 // AFL
574 struct tlvdb * f1AFL = tlvdb_fixed(0x94, len - 4, buf + 2 + 2);
575 tlvdb_add(tlvRoot, f1AFL);
576 if (decodeTLV)
577 TLVPrintFromTLV(f1AFL);
578 }
579 } else {
3c5fce2b
OM
580 if (decodeTLV)
581 TLVPrintFromBuffer(buf, len);
582 }
583
66efdc1f 584 // extract PAN from track2
585 {
586 const struct tlv *track2 = tlvdb_get(tlvRoot, 0x57, NULL);
587 if (!tlvdb_get(tlvRoot, 0x5a, NULL) && track2 && track2->len >= 8) {
588 struct tlvdb *pan = GetPANFromTrack2(track2);
589 if (pan) {
590 tlvdb_add(tlvRoot, pan);
591
592 const struct tlv *pantlv = tlvdb_get(tlvRoot, 0x5a, NULL);
593 PrintAndLog("\n* * Extracted PAN from track2: %s", sprint_hex(pantlv->value, pantlv->len));
594 } else {
595 PrintAndLog("\n* * WARNING: Can't extract PAN from track2.");
596 }
597 }
598 }
599
3c5fce2b
OM
600 PrintAndLog("\n* Read records from AFL.");
601 const struct tlv *AFL = tlvdb_get(tlvRoot, 0x94, NULL);
602 if (!AFL || !AFL->len) {
603 PrintAndLog("WARNING: AFL not found.");
604 }
605
606 while(AFL && AFL->len) {
607 if (AFL->len % 4) {
608 PrintAndLog("ERROR: Wrong AFL length: %d", AFL->len);
609 break;
610 }
611
612 for (int i = 0; i < AFL->len / 4; i++) {
613 uint8_t SFI = AFL->value[i * 4 + 0] >> 3;
614 uint8_t SFIstart = AFL->value[i * 4 + 1];
615 uint8_t SFIend = AFL->value[i * 4 + 2];
616 uint8_t SFIoffline = AFL->value[i * 4 + 3];
617
618 PrintAndLog("* * SFI[%02x] start:%02x end:%02x offline:%02x", SFI, SFIstart, SFIend, SFIoffline);
619 if (SFI == 0 || SFI == 31 || SFIstart == 0 || SFIstart > SFIend) {
620 PrintAndLog("SFI ERROR! Skipped...");
621 continue;
622 }
623
624 for(int n = SFIstart; n <= SFIend; n++) {
625 PrintAndLog("* * * SFI[%02x] %d", SFI, n);
626
627 res = EMVReadRecord(true, SFI, n, buf, sizeof(buf), &len, &sw, tlvRoot);
628 if (res) {
629 PrintAndLog("ERROR SFI[%02x]. APDU error %4x", SFI, sw);
630 continue;
631 }
632
633 if (decodeTLV) {
634 TLVPrintFromBuffer(buf, len);
635 PrintAndLog("");
636 }
637
d03fb293
OM
638 // Build Input list for Offline Data Authentication
639 // EMV 4.3 book3 10.3, page 96
3c5fce2b 640 if (SFIoffline) {
d03fb293
OM
641 if (SFI < 11) {
642 const unsigned char *abuf = buf;
643 size_t elmlen = len;
644 struct tlv e;
645 if (tlv_parse_tl(&abuf, &elmlen, &e)) {
646 memcpy(&ODAiList[ODAiListLen], &buf[len - elmlen], elmlen);
647 ODAiListLen += elmlen;
648 } else {
649 PrintAndLog("ERROR SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI);
650 }
651 } else {
652 memcpy(&ODAiList[ODAiListLen], buf, len);
653 ODAiListLen += len;
654 }
3c5fce2b
OM
655 }
656 }
657 }
658
659 break;
660 }
661
d03fb293
OM
662 // copy Input list for Offline Data Authentication
663 if (ODAiListLen) {
664 struct tlvdb *oda = tlvdb_fixed(0x21, ODAiListLen, ODAiList); // not a standard tag
665 tlvdb_add(tlvRoot, oda);
666 PrintAndLog("* Input list for Offline Data Authentication added to TLV. len=%d \n", ODAiListLen);
667 }
668
10d4f823 669 // get AIP
66efdc1f 670 const struct tlv *AIPtlv = tlvdb_get(tlvRoot, 0x82, NULL);
671 uint16_t AIP = AIPtlv->value[0] + AIPtlv->value[1] * 0x100;
10d4f823 672 PrintAndLog("* * AIP=%04x", AIP);
66efdc1f 673
10d4f823 674 // SDA
675 if (AIP & 0x0040) {
676 PrintAndLog("\n* SDA");
d03fb293 677 trSDA(tlvRoot);
10d4f823 678 }
679
680 // DDA
681 if (AIP & 0x0020) {
682 PrintAndLog("\n* DDA");
d03fb293 683 trDDA(decodeTLV, tlvRoot);
10d4f823 684 }
685
686 // transaction check
687
66efdc1f 688 // qVSDC
10d4f823 689 if (TrType == TT_QVSDCMCHIP|| TrType == TT_CDA){
66efdc1f 690 // 9F26: Application Cryptogram
691 const struct tlv *AC = tlvdb_get(tlvRoot, 0x9F26, NULL);
692 if (AC) {
693 PrintAndLog("\n--> qVSDC transaction.");
694 PrintAndLog("* AC path");
695
696 // 9F36: Application Transaction Counter (ATC)
697 const struct tlv *ATC = tlvdb_get(tlvRoot, 0x9F36, NULL);
698 if (ATC) {
699
700 // 9F10: Issuer Application Data - optional
701 const struct tlv *IAD = tlvdb_get(tlvRoot, 0x9F10, NULL);
702
703 // print AC data
704 PrintAndLog("ATC: %s", sprint_hex(ATC->value, ATC->len));
705 PrintAndLog("AC: %s", sprint_hex(AC->value, AC->len));
706 if (IAD){
707 PrintAndLog("IAD: %s", sprint_hex(IAD->value, IAD->len));
708
709 if (IAD->len >= IAD->value[0] + 1) {
710 PrintAndLog("\tKey index: 0x%02x", IAD->value[1]);
711 PrintAndLog("\tCrypto ver: 0x%02x(%03d)", IAD->value[2], IAD->value[2]);
712 PrintAndLog("\tCVR:", sprint_hex(&IAD->value[3], IAD->value[0] - 2));
713 struct tlvdb * cvr = tlvdb_fixed(0x20, IAD->value[0] - 2, &IAD->value[3]);
714 TLVPrintFromTLVLev(cvr, 1);
715 }
716 } else {
717 PrintAndLog("WARNING: IAD not found.");
718 }
719
720 } else {
721 PrintAndLog("ERROR AC: Application Transaction Counter (ATC) not found.");
722 }
723 }
724 }
725
10d4f823 726 // Mastercard M/CHIP
727 if (GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD && (TrType == TT_QVSDCMCHIP || TrType == TT_CDA)){
66efdc1f 728 const struct tlv *CDOL1 = tlvdb_get(tlvRoot, 0x8c, NULL);
729 if (CDOL1 && GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD) { // and m/chip transaction flag
10d4f823 730 PrintAndLog("\n--> Mastercard M/Chip transaction.");
731
732 PrintAndLog("* * Generate challenge");
733 res = EMVGenerateChallenge(true, buf, sizeof(buf), &len, &sw, tlvRoot);
734 if (res) {
735 PrintAndLog("ERROR GetChallenge. APDU error %4x", sw);
d03fb293 736 dreturn(6);
10d4f823 737 }
738 if (len < 4) {
739 PrintAndLog("ERROR GetChallenge. Wrong challenge length %d", len);
d03fb293 740 dreturn(6);
10d4f823 741 }
742
743 // ICC Dynamic Number
744 struct tlvdb * ICCDynN = tlvdb_fixed(0x9f4c, len, buf);
745 tlvdb_add(tlvRoot, ICCDynN);
746 if (decodeTLV){
747 PrintAndLog("\n* * ICC Dynamic Number:");
748 TLVPrintFromTLV(ICCDynN);
749 }
750
751 PrintAndLog("* * Calc CDOL1");
752 struct tlv *cdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8c, NULL), tlvRoot, 0x01); // 0x01 - dummy tag
753 if (!cdol_data_tlv){
754 PrintAndLog("ERROR: can't create CDOL1 TLV.");
d03fb293 755 dreturn(6);
10d4f823 756 }
757 PrintAndLog("CDOL1 data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len));
758
759 PrintAndLog("* * AC1");
760 // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD
761 res = EMVAC(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);
762
10d4f823 763 if (res) {
764 PrintAndLog("AC1 error(%d): %4x. Exit...", res, sw);
d03fb293 765 dreturn(7);
10d4f823 766 }
767
768 if (decodeTLV)
769 TLVPrintFromBuffer(buf, len);
770
d03fb293
OM
771 // CDA
772 PrintAndLog("\n* CDA:");
773 struct tlvdb *ac_tlv = tlvdb_parse_multi(buf, len);
774 res = trCDA(tlvRoot, ac_tlv, pdol_data_tlv, cdol_data_tlv);
775 if (res) {
776 PrintAndLog("CDA error (%d)", res);
777 }
778 free(ac_tlv);
779 free(cdol_data_tlv);
780
781 PrintAndLog("\n* M/Chip transaction result:");
10d4f823 782 // 9F27: Cryptogram Information Data (CID)
783 const struct tlv *CID = tlvdb_get(tlvRoot, 0x9F27, NULL);
784 if (CID) {
785 emv_tag_dump(CID, stdout, 0);
786 PrintAndLog("------------------------------");
787 if (CID->len > 0) {
788 switch(CID->value[0] & EMVAC_AC_MASK){
789 case EMVAC_AAC:
790 PrintAndLog("Transaction DECLINED.");
791 break;
792 case EMVAC_TC:
793 PrintAndLog("Transaction approved OFFLINE.");
794 break;
795 case EMVAC_ARQC:
796 PrintAndLog("Transaction approved ONLINE.");
797 break;
798 default:
799 PrintAndLog("ERROR: CID transaction code error %2x", CID->value[0] & EMVAC_AC_MASK);
800 break;
801 }
802 } else {
803 PrintAndLog("ERROR: Wrong CID length %d", CID->len);
804 }
805 } else {
806 PrintAndLog("ERROR: CID(9F27) not found.");
807 }
66efdc1f 808
809 }
810 }
811
812 // MSD
10d4f823 813 if (AIP & 0x8000 && TrType == TT_MSD) {
66efdc1f 814 PrintAndLog("\n--> MSD transaction.");
815
66efdc1f 816 PrintAndLog("* MSD dCVV path. Check dCVV");
817
818 const struct tlv *track2 = tlvdb_get(tlvRoot, 0x57, NULL);
819 if (track2) {
820 PrintAndLog("Track2: %s", sprint_hex(track2->value, track2->len));
821
822 struct tlvdb *dCVV = GetdCVVRawFromTrack2(track2);
823 PrintAndLog("dCVV raw data:");
824 TLVPrintFromTLV(dCVV);
825
826 if (GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD) {
827 PrintAndLog("\n* Mastercard calculate UDOL");
828
829 // UDOL (9F69)
830 const struct tlv *UDOL = tlvdb_get(tlvRoot, 0x9F69, NULL);
831 // UDOL(9F69) default: 9F6A (Unpredictable number) 4 bytes
832 const struct tlv defUDOL = {
833 .tag = 0x01,
834 .len = 3,
835 .value = (uint8_t *)"\x9f\x6a\x04",
836 };
837 if (!UDOL)
838 PrintAndLog("Use default UDOL.");
839
10d4f823 840 struct tlv *udol_data_tlv = dol_process(UDOL ? UDOL : &defUDOL, tlvRoot, 0x01); // 0x01 - dummy tag
66efdc1f 841 if (!udol_data_tlv){
842 PrintAndLog("ERROR: can't create UDOL TLV.");
d03fb293 843 dreturn(8);
66efdc1f 844 }
66efdc1f 845
78528074 846 PrintAndLog("UDOL data[%d]: %s", udol_data_tlv->len, sprint_hex(udol_data_tlv->value, udol_data_tlv->len));
66efdc1f 847
848 PrintAndLog("\n* Mastercard compute cryptographic checksum(UDOL)");
849
78528074 850 res = MSCComputeCryptoChecksum(true, (uint8_t *)udol_data_tlv->value, udol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot);
66efdc1f 851 if (res) {
852 PrintAndLog("ERROR Compute Crypto Checksum. APDU error %4x", sw);
d03fb293
OM
853 free(udol_data_tlv);
854 dreturn(9);
66efdc1f 855 }
856
857 if (decodeTLV) {
858 TLVPrintFromBuffer(buf, len);
859 PrintAndLog("");
860 }
d03fb293 861 free(udol_data_tlv);
66efdc1f 862
863 }
864 } else {
865 PrintAndLog("ERROR MSD: Track2 data not found.");
866 }
867 }
d03fb293 868
3c5fce2b
OM
869 // DropField
870 DropField();
871
872 // Destroy TLV's
d03fb293 873 free(pdol_data_tlv);
3c5fce2b
OM
874 tlvdb_free(tlvSelect);
875 tlvdb_free(tlvRoot);
876
877 PrintAndLog("\n* Transaction completed.");
878
879 return 0;
880}
881
d03fb293
OM
882int CmdHFEMVTest(const char *cmd) {
883 return ExecuteCryptoTests(true);
884}
885
3c5fce2b
OM
886int CmdHelp(const char *Cmd);
887static command_t CommandTable[] = {
626e650f 888 {"help", CmdHelp, 1, "This help"},
889 {"exec", CmdHFEMVExec, 0, "Executes EMV contactless transaction."},
890 {"pse", CmdHFEMVPPSE, 0, "Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory."},
891 {"search", CmdHFEMVSearch, 0, "Try to select all applets from applets list and print installed applets."},
892 {"select", CmdHFEMVSelect, 0, "Select applet."},
893 {"gpo", CmdHFEMVGPO, 0, "Execute GetProcessingOptions."},
894 {"readrec", CmdHFEMVReadRecord, 0, "Read files from card."},
895 {"genac", CmdHFEMVAC, 0, "Generate ApplicationCryptogram."},
896 {"challenge", CmdHFEMVGenerateChallenge, 0, "Generate challenge."},
897 {"intauth", CmdHFEMVInternalAuthenticate, 0, "Internal authentication."},
898 {"test", CmdHFEMVTest, 0, "Crypto logic test."},
3c5fce2b
OM
899 {NULL, NULL, 0, NULL}
900};
901
902int CmdHFEMV(const char *Cmd) {
903 CmdsParse(CommandTable, Cmd);
904 return 0;
905}
906
907int CmdHelp(const char *Cmd) {
908 CmdsHelp(CommandTable);
909 return 0;
910}
Impressum, Datenschutz