recover_pk.py: replace secp192r1 by prime192v1
[RRG-proxmark3.git] / client / src / cmdnfc.c
blob9a1233f29e470cf54cda0811de8b55760941502d
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // NFC commands
17 //-----------------------------------------------------------------------------
18 #include "cmdnfc.h"
19 #include "nfc/ndef.h"
20 #include "cliparser.h"
21 #include "ui.h"
22 #include "cmdparser.h"
23 #include "cmdhf14a.h"
24 #include "cmdhf14b.h"
25 #include "cmdhfmf.h"
26 #include "cmdhfmfp.h"
27 #include "cmdhfmfu.h"
28 #include "cmdhfst25ta.h"
29 #include "cmdhfthinfilm.h"
30 #include "cmdhftopaz.h"
31 #include "cmdnfc.h"
32 #include "fileutils.h"
33 #include "mifare/mifaredefault.h"
34 #include "mifare/mad.h"
36 void print_type4_cc_info(uint8_t *d, uint8_t n) {
37 if (n < 0x0F) {
38 PrintAndLogEx(WARNING, "Not enough bytes read from CC file");
39 return;
42 PrintAndLogEx(NORMAL, "");
43 PrintAndLogEx(SUCCESS, "------------ " _CYAN_("Capability Container file") " ------------");
44 PrintAndLogEx(SUCCESS, " Version... %s ( " _GREEN_("0x%02X") " )", (d[2] == 0x20) ? "v2.0" : "v1.0", d[2]);
45 PrintAndLogEx(SUCCESS, " Len....... %u bytes ( " _GREEN_("0x%02X") " )", d[1], d[1]);
46 uint16_t maxr = (d[3] << 8 | d[4]);
47 PrintAndLogEx(SUCCESS, " Max bytes read %u bytes ( 0x%04X )", maxr, maxr);
48 uint16_t maxw = (d[5] << 8 | d[6]);
49 PrintAndLogEx(SUCCESS, " Max bytes write %u bytes ( 0x%04X )", maxw, maxw);
50 PrintAndLogEx(NORMAL, "");
51 PrintAndLogEx(SUCCESS, " NDEF file control TLV");
52 PrintAndLogEx(SUCCESS, " (t) type of file.... %02X", d[7]);
53 PrintAndLogEx(SUCCESS, " (v) ................ %02X", d[8]);
54 PrintAndLogEx(SUCCESS, " file id............. %02X%02X", d[9], d[10]);
56 uint16_t maxndef = (d[11] << 8 | d[12]);
57 PrintAndLogEx(SUCCESS, " Max NDEF filesize... %u bytes ( 0x%04X )", maxndef, maxndef);
58 PrintAndLogEx(SUCCESS, " " _CYAN_("Access rights"));
59 PrintAndLogEx(SUCCESS, " read ( %02X ) protection: %s", d[13], ((d[13] & 0x80) == 0x80) ? _RED_("enabled") : _GREEN_("disabled"));
60 PrintAndLogEx(SUCCESS, " write ( %02X ) protection: %s", d[14], ((d[14] & 0x80) == 0x80) ? _RED_("enabled") : _GREEN_("disabled"));
61 PrintAndLogEx(SUCCESS, "");
62 PrintAndLogEx(SUCCESS, "----------------- " _CYAN_("raw") " -----------------");
63 PrintAndLogEx(SUCCESS, "%s", sprint_hex_inrow(d, n));
64 PrintAndLogEx(NORMAL, "");
67 static int CmdNfcDecode(const char *Cmd) {
69 #ifndef MAX_NDEF_LEN
70 #define MAX_NDEF_LEN 2048
71 #endif
73 CLIParserContext *ctx;
74 CLIParserInit(&ctx, "nfc decode",
75 "Decode and print NFC Data Exchange Format (NDEF)\n"
76 "You must provide either data in hex or a filename, but not both",
77 "nfc decode -d 9101085402656e48656c6c6f5101085402656e576f726c64\n"
78 "nfc decode -d 0103d020240203e02c040300fe\n"
79 "nfc decode -f myfilename"
82 void *argtable[] = {
83 arg_param_begin,
84 arg_str0("d", "data", "<hex>", "NDEF data to decode"),
85 arg_str0("f", "file", "<fn>", "file to load"),
86 arg_lit0("v", "verbose", "verbose output"),
87 arg_param_end
89 CLIExecWithReturn(ctx, Cmd, argtable, false);
91 int datalen = 0;
92 uint8_t data[MAX_NDEF_LEN] = {0};
93 CLIGetHexWithReturn(ctx, 1, data, &datalen);
95 int fnlen = 0;
96 char filename[FILE_PATH_SIZE] = {0};
97 CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
99 bool verbose = arg_get_lit(ctx, 3);
100 CLIParserFree(ctx);
101 if (((datalen != 0) && (fnlen != 0)) || ((datalen == 0) && (fnlen == 0))) {
102 PrintAndLogEx(ERR, "You must provide either data in hex or a filename");
103 return PM3_EINVARG;
105 int res = PM3_SUCCESS;
106 if (fnlen != 0) {
108 // read dump file
109 uint8_t *dump = NULL;
110 size_t bytes_read = 4096;
111 res = pm3_load_dump(filename, (void **)&dump, &bytes_read, 4096);
112 if (res != PM3_SUCCESS || dump == NULL || bytes_read > 4096) {
113 return res;
116 uint8_t *tmp = dump;
118 // if not MIFARE Classic default sizes, assume its Ultralight/NTAG
119 if (bytes_read != MIFARE_4K_MAX_BYTES
120 && bytes_read != MIFARE_2K_MAX_BYTES
121 && bytes_read != MIFARE_1K_MAX_BYTES
122 && bytes_read != MIFARE_MINI_MAX_BYTES) {
124 uint8_t **pd = &tmp;
125 mfu_df_e df = detect_mfu_dump_format(pd, verbose);
126 if (df == MFU_DF_OLDBIN) {
127 tmp += OLD_MFU_DUMP_PREFIX_LENGTH + (4 * 4);
128 bytes_read -= OLD_MFU_DUMP_PREFIX_LENGTH + (4 * 4);
129 } else if (df == MFU_DF_NEWBIN) {
130 tmp += MFU_DUMP_PREFIX_LENGTH + (4 * 4);
131 bytes_read -= MFU_DUMP_PREFIX_LENGTH + (4 * 4);
133 pd = NULL;
135 } else {
137 // convert from MFC dump file to a pure NDEF byte array
138 if (HasMADKey(tmp)) {
139 PrintAndLogEx(SUCCESS, "MFC dump file detected. Converting...");
140 uint8_t ndef[4096] = {0};
141 uint16_t ndeflen = 0;
143 if (convert_mad_to_arr(tmp, bytes_read, ndef, &ndeflen) != PM3_SUCCESS) {
144 PrintAndLogEx(FAILED, "Failed converting, aborting...");
145 free(dump);
146 return PM3_ESOFT;
149 memcpy(tmp, ndef, ndeflen);
150 bytes_read = ndeflen;
154 res = NDEFDecodeAndPrint(tmp, bytes_read, verbose);
155 if (res != PM3_SUCCESS) {
156 PrintAndLogEx(INFO, "Trying to parse NDEF records w/o NDEF header");
157 res = NDEFRecordsDecodeAndPrint(tmp, bytes_read, verbose);
160 free(dump);
162 } else {
163 res = NDEFDecodeAndPrint(data, datalen, verbose);
164 if (res != PM3_SUCCESS) {
165 PrintAndLogEx(INFO, "Trying to parse NDEF records w/o NDEF header");
166 res = NDEFRecordsDecodeAndPrint(data, datalen, verbose);
169 return res;
172 static int CmdNFCType1Read(const char *Cmd) {
173 return CmdHFTopazInfo(Cmd);
176 static int CmdNFCType1Help(const char *Cmd);
178 static command_t CommandNFCType1Table[] = {
180 {"--------", CmdNFCType1Help, AlwaysAvailable, "-------------- " _CYAN_("NFC Forum Tag Type 1") " ---------------"},
181 // {"format", CmdNFCType1Format, IfPm3Iso14443a, "format ISO-14443-a tag as NFC Tag"},
182 {"read", CmdNFCType1Read, IfPm3Iso14443a, "read NFC Forum Tag Type 1"},
183 // {"write", CmdNFCType1Write, IfPm3Iso14443a, "write NFC Forum Tag Type 1"},
184 {"--------", CmdNFCType1Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
185 {"help", CmdNFCType1Help, AlwaysAvailable, "This help"},
186 {NULL, NULL, NULL, NULL}
189 static int CmdNFCType1(const char *Cmd) {
190 clearCommandBuffer();
191 return CmdsParse(CommandNFCType1Table, Cmd);
194 static int CmdNFCType1Help(const char *Cmd) {
195 (void)Cmd; // Cmd is not used so far
196 CmdsHelp(CommandNFCType1Table);
197 return PM3_SUCCESS;
200 static int CmdNFCType2Read(const char *Cmd) {
201 return CmdHF14MfuNDEFRead(Cmd);
204 static int CmdNFCType2Help(const char *Cmd);
206 static command_t CommandNFCType2Table[] = {
208 {"--------", CmdNFCType2Help, AlwaysAvailable, "-------------- " _CYAN_("NFC Forum Tag Type 2") " ---------------"},
209 // {"format", CmdNFCType2Format, IfPm3Iso14443a, "format ISO-14443-a tag as NFC Tag"},
210 {"read", CmdNFCType2Read, IfPm3Iso14443a, "read NFC Forum Tag Type 2"},
211 // {"write", CmdNFCType2Write, IfPm3Iso14443a, "write NFC Forum Tag Type 2"},
212 {"--------", CmdNFCType2Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
213 {"help", CmdNFCType2Help, AlwaysAvailable, "This help"},
214 {NULL, NULL, NULL, NULL}
217 static int CmdNFCType2(const char *Cmd) {
218 clearCommandBuffer();
219 return CmdsParse(CommandNFCType2Table, Cmd);
222 static int CmdNFCType2Help(const char *Cmd) {
223 (void)Cmd; // Cmd is not used so far
224 CmdsHelp(CommandNFCType2Table);
225 return PM3_SUCCESS;
229 static int CmdNFCType3Read(const char *Cmd) {
230 return CmdHFFelicaXXX(Cmd);
233 static int CmdNFCType3Help(const char *Cmd);
235 static command_t CommandNFCType3Table[] = {
237 {"--------", CmdNFCType3Help, AlwaysAvailable, "-------------- " _CYAN_("NFC Forum Tag Type 3") " ---------------"},
238 // {"format", CmdNFCType3Format, IfPm3Felica, "format FeliCa tag as NFC Tag"},
239 {"read", CmdNFCType3Read, IfPm3Felica, "read NFC Forum Tag Type 3"},
240 // {"write", CmdNFCType3Write, IfPm3Felica, "write NFC Forum Tag Type 3"},
241 {"--------", CmdNFCType3Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
242 {"help", CmdNFCType3Help, AlwaysAvailable, "This help"},
243 {NULL, NULL, NULL, NULL}
246 static int CmdNFCType3(const char *Cmd) {
247 clearCommandBuffer();
248 return CmdsParse(CommandNFCType3Table, Cmd);
251 static int CmdNFCType3Help(const char *Cmd) {
252 (void)Cmd; // Cmd is not used so far
253 CmdsHelp(CommandNFCType3Table);
254 return PM3_SUCCESS;
258 static int CmdNFCType4ARead(const char *Cmd) {
259 return CmdHF14ANdefRead(Cmd);
262 static int CmdNFCST25TARead(const char *Cmd) {
263 return CmdHFST25TANdefRead(Cmd);
266 static int CmdNFCType4AFormat(const char *Cmd) {
267 return CmdHF14ANdefFormat(Cmd);
270 static int CmdNFCType4AWrite(const char *Cmd) {
271 return CmdHF14ANdefWrite(Cmd);
274 static int CmdNFCType4AHelp(const char *Cmd);
276 static command_t CommandNFCType4ATable[] = {
278 {"--------", CmdNFCType4AHelp, AlwaysAvailable, "--------- " _CYAN_("NFC Forum Tag Type 4 ISO14443A") " ----------"},
279 {"format", CmdNFCType4AFormat, IfPm3Iso14443a, "format ISO-14443-a tag as NFC Tag"},
280 {"read", CmdNFCType4ARead, IfPm3Iso14443a, "read NFC Forum Tag Type 4 A"},
281 {"write", CmdNFCType4AWrite, IfPm3Iso14443a, "write NFC Forum Tag Type 4 A"},
282 // {"mfdesread", CmdNFCMFDESRead, IfPm3Iso14443a, "read NDEF from MIFARE DESfire"}, // hf mfdes ndefread
283 // {"mfdesformat", CmdNFCMFDESFormat, IfPm3Iso14443a, "format MIFARE DESfire as NFC Forum Tag Type 4"},
284 {"st25taread", CmdNFCST25TARead, IfPm3Iso14443a, "read ST25TA as NFC Forum Tag Type 4"},
286 {"--------", CmdNFCType4AHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
287 {"help", CmdNFCType4AHelp, AlwaysAvailable, "This help"},
288 {NULL, NULL, NULL, NULL}
291 static int CmdNFCType4A(const char *Cmd) {
292 clearCommandBuffer();
293 return CmdsParse(CommandNFCType4ATable, Cmd);
296 static int CmdNFCType4AHelp(const char *Cmd) {
297 (void)Cmd; // Cmd is not used so far
298 CmdsHelp(CommandNFCType4ATable);
299 return PM3_SUCCESS;
302 static int CmdNFCType4BRead(const char *Cmd) {
303 return CmdHF14BNdefRead(Cmd);
306 static int CmdNFCType4BHelp(const char *Cmd);
308 static command_t CommandNFCType4BTable[] = {
310 {"--------", CmdNFCType4BHelp, AlwaysAvailable, "--------- " _CYAN_("NFC Forum Tag Type 4 ISO14443B") " -------------"},
311 // {"format", CmdNFCType4BFormat, IfPm3Iso14443b, "format ISO-14443-b tag as NFC Tag"},
312 {"read", CmdNFCType4BRead, IfPm3Iso14443b, "read NFC Forum Tag Type 4 B"},
313 // {"write", CmdNFCType4BWrite, IfPm3Iso14443b, "write NFC Forum Tag Type 4 B"},
314 {"--------", CmdNFCType4BHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
315 {"help", CmdNFCType4BHelp, AlwaysAvailable, "This help"},
316 {NULL, NULL, NULL, NULL}
319 static int CmdNFCType4B(const char *Cmd) {
320 clearCommandBuffer();
321 return CmdsParse(CommandNFCType4BTable, Cmd);
324 static int CmdNFCType4BHelp(const char *Cmd) {
325 (void)Cmd; // Cmd is not used so far
326 CmdsHelp(CommandNFCType4BTable);
327 return PM3_SUCCESS;
331 static int CmdNFCType5Read(const char *Cmd) {
332 return CmdHF15XXX(Cmd);
335 static int CmdNFCType5Help(const char *Cmd);
337 static command_t CommandNFCType5Table[] = {
339 {"--------", CmdNFCType5Help, AlwaysAvailable, "-------------- " _CYAN_("NFC Forum Tag Type 5") " ---------------"},
340 // {"format", CmdNFCType5Format, IfPm3Iso15693, "format ISO-15693 tag as NFC Tag"},
341 {"read", CmdNFCType5Read, IfPm3Iso15693, "read NFC Forum Tag Type 5"},
342 // {"write", CmdNFCType5Write, IfPm3Iso15693, "write NFC Forum Tag Type 5"},
343 {"--------", CmdNFCType5Help, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
344 {"help", CmdNFCType5Help, AlwaysAvailable, "This help"},
345 {NULL, NULL, NULL, NULL}
348 static int CmdNFCType5(const char *Cmd) {
349 clearCommandBuffer();
350 return CmdsParse(CommandNFCType5Table, Cmd);
353 static int CmdNFCType5Help(const char *Cmd) {
354 (void)Cmd; // Cmd is not used so far
355 CmdsHelp(CommandNFCType5Table);
356 return PM3_SUCCESS;
360 static int CmdNFCMFCRead(const char *Cmd) {
361 return CmdHFMFNDEFRead(Cmd);
364 static int CmdNFCMFCFormat(const char *Cmd) {
365 return CmdHFMFNDEFFormat(Cmd);
368 static int CmdNFCMFCWrite(const char *Cmd) {
369 return CmdHFMFNDEFWrite(Cmd);
373 static int CmdNFCMFPRead(const char *Cmd) {
374 return CmdHFMFPNDEFRead(Cmd);
377 static int CmdNFCMFHelp(const char *Cmd);
379 static command_t CommandMFTable[] = {
381 {"--------", CmdNFCMFHelp, AlwaysAvailable, "--------- " _CYAN_("NFC Type MIFARE Classic/Plus Tag") " --------"},
382 {"cformat", CmdNFCMFCFormat, IfPm3Iso14443a, "format MIFARE Classic Tag as NFC Tag"},
383 {"cread", CmdNFCMFCRead, IfPm3Iso14443a, "read NFC Type MIFARE Classic Tag"},
384 {"cwrite", CmdNFCMFCWrite, IfPm3Iso14443a, "write NFC Type MIFARE Classic Tag"},
385 {"pread", CmdNFCMFPRead, IfPm3Iso14443a, "read NFC Type MIFARE Plus Tag"},
386 {"--------", CmdNFCMFHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
387 {"help", CmdNFCMFHelp, AlwaysAvailable, "This help"},
388 {NULL, NULL, NULL, NULL}
391 static int CmdNFCMF(const char *Cmd) {
392 clearCommandBuffer();
393 return CmdsParse(CommandMFTable, Cmd);
396 static int CmdNFCMFHelp(const char *Cmd) {
397 (void)Cmd; // Cmd is not used so far
398 CmdsHelp(CommandMFTable);
399 return PM3_SUCCESS;
402 static int CmdNFCBarcodeRead(const char *Cmd) {
403 return CmdHfThinFilmInfo(Cmd);
406 static int CmdNFCBarcodeSim(const char *Cmd) {
407 return CmdHfThinFilmSim(Cmd);
410 static int CmdNFCBarcodeHelp(const char *Cmd);
412 static command_t CommandBarcodeTable[] = {
414 {"--------", CmdNFCBarcodeHelp, AlwaysAvailable, "------------------ " _CYAN_("NFC Barcode") " --------------------"},
415 {"read", CmdNFCBarcodeRead, IfPm3Iso14443a, "read NFC Barcode"},
416 {"sim", CmdNFCBarcodeSim, IfPm3Iso14443a, "simulate NFC Barcode"},
417 {"--------", CmdNFCBarcodeHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
418 {"help", CmdNFCBarcodeHelp, AlwaysAvailable, "This help"},
419 {NULL, NULL, NULL, NULL}
422 static int CmdNFCBarcode(const char *Cmd) {
423 clearCommandBuffer();
424 return CmdsParse(CommandBarcodeTable, Cmd);
427 static int CmdNFCBarcodeHelp(const char *Cmd) {
428 (void)Cmd; // Cmd is not used so far
429 CmdsHelp(CommandBarcodeTable);
430 return PM3_SUCCESS;
433 static int CmdHelp(const char *Cmd);
435 static command_t CommandTable[] = {
437 {"--------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("NFC Tags") " --------------------"},
438 {"type1", CmdNFCType1, AlwaysAvailable, "{ NFC Forum Tag Type 1... }"},
439 {"type2", CmdNFCType2, AlwaysAvailable, "{ NFC Forum Tag Type 2... }"},
440 // {"type3", CmdNFCType3, AlwaysAvailable, "{ NFC Forum Tag Type 3... }"},
441 {"type4a", CmdNFCType4A, AlwaysAvailable, "{ NFC Forum Tag Type 4 ISO14443A... }"},
442 {"type4b", CmdNFCType4B, AlwaysAvailable, "{ NFC Forum Tag Type 4 ISO14443B... }"},
443 // {"type5", CmdNFCType5, AlwaysAvailable, "{ NFC Forum Tag Type 5... }"},
444 {"mf", CmdNFCMF, AlwaysAvailable, "{ NFC Type MIFARE Classic/Plus Tag... }"},
445 {"barcode", CmdNFCBarcode, AlwaysAvailable, "{ NFC Barcode Tag... }"},
446 // {"--------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("NFC peer-to-peer") " ------------"},
447 // {"isodep", CmdISODEP, AlwaysAvailable, "{ ISO-DEP protocol... }"},
448 // {"llcp", CmdNFCLLCP, AlwaysAvailable, "{ Logical Link Control Protocol... }"},
449 // {"snep", CmdNFCSNEP, AlwaysAvailable, "{ Simple NDEF Exchange Protocol... }"},
450 {"--------", CmdHelp, AlwaysAvailable, "--------------------- " _CYAN_("General") " ---------------------"},
451 {"help", CmdHelp, AlwaysAvailable, "This help"},
452 {"decode", CmdNfcDecode, AlwaysAvailable, "Decode NDEF records"},
453 // {"encode", CmdNfcEncode, AlwaysAvailable, "Encode NDEF records"},
454 {NULL, NULL, NULL, NULL}
457 int CmdNFC(const char *Cmd) {
458 clearCommandBuffer();
459 return CmdsParse(CommandTable, Cmd);
462 int CmdHelp(const char *Cmd) {
463 (void)Cmd; // Cmd is not used so far
464 CmdsHelp(CommandTable);
465 return PM3_SUCCESS;