]>
Commit | Line | Data |
---|---|---|
1 | //----------------------------------------------------------------------------- | |
2 | // Copyright (C) 2018 Merlok | |
3 | // | |
4 | // This code is licensed to you under the terms of the GNU GPL, version 2 or, | |
5 | // at your option, any later version. See the LICENSE.txt file for the text of | |
6 | // the license. | |
7 | //----------------------------------------------------------------------------- | |
8 | // High frequency MIFARE Plus commands | |
9 | //----------------------------------------------------------------------------- | |
10 | ||
11 | #include "cmdhfmfp.h" | |
12 | ||
13 | #include <inttypes.h> | |
14 | #include <string.h> | |
15 | #include <stdio.h> | |
16 | #include <stdlib.h> | |
17 | #include <ctype.h> | |
18 | #include "comms.h" | |
19 | #include "cmdmain.h" | |
20 | #include "util.h" | |
21 | #include "ui.h" | |
22 | #include "cmdhf14a.h" | |
23 | #include "mifare.h" | |
24 | ||
25 | static int CmdHelp(const char *Cmd); | |
26 | ||
27 | int CmdHFMFPInfo(const char *cmd) { | |
28 | ||
29 | if (cmd && strlen(cmd) > 0) | |
30 | PrintAndLog("WARNING: command don't have any parameters.\n"); | |
31 | ||
32 | // info about 14a part | |
33 | CmdHF14AInfo(""); | |
34 | ||
35 | // Mifare Plus info | |
36 | UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}}; | |
37 | SendCommand(&c); | |
38 | ||
39 | UsbCommand resp; | |
40 | WaitForResponse(CMD_ACK,&resp); | |
41 | ||
42 | iso14a_card_select_t card; | |
43 | memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t)); | |
44 | ||
45 | uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision | |
46 | ||
47 | if (select_status == 1 || select_status == 2) { | |
48 | PrintAndLog("----------------------------------------------"); | |
49 | PrintAndLog("Mifare Plus info:"); | |
50 | ||
51 | // MIFARE Type Identification Procedure | |
52 | // https://www.nxp.com/docs/en/application-note/AN10833.pdf | |
53 | uint16_t ATQA = card.atqa[0] + (card.atqa[1] << 8); | |
54 | if (ATQA == 0x0004) PrintAndLog("ATQA: Mifare Plus 2k 4bUID"); | |
55 | if (ATQA == 0x0002) PrintAndLog("ATQA: Mifare Plus 4k 4bUID"); | |
56 | if (ATQA == 0x0044) PrintAndLog("ATQA: Mifare Plus 2k 7bUID"); | |
57 | if (ATQA == 0x0042) PrintAndLog("ATQA: Mifare Plus 4k 7bUID"); | |
58 | ||
59 | uint8_t SLmode = 0xff; | |
60 | if (card.sak == 0x08) { | |
61 | PrintAndLog("SAK: Mifare Plus 2k 7bUID"); | |
62 | if (select_status == 2) SLmode = 1; | |
63 | } | |
64 | if (card.sak == 0x18) { | |
65 | PrintAndLog("SAK: Mifare Plus 4k 7bUID"); | |
66 | if (select_status == 2) SLmode = 1; | |
67 | } | |
68 | if (card.sak == 0x10) { | |
69 | PrintAndLog("SAK: Mifare Plus 2k"); | |
70 | if (select_status == 2) SLmode = 2; | |
71 | } | |
72 | if (card.sak == 0x11) { | |
73 | PrintAndLog("SAK: Mifare Plus 4k"); | |
74 | if (select_status == 2) SLmode = 2; | |
75 | } | |
76 | if (card.sak == 0x20) { | |
77 | PrintAndLog("SAK: Mifare Plus SL0/SL3 or Mifare desfire"); | |
78 | if (card.ats_len > 0) { | |
79 | SLmode = 3; | |
80 | ||
81 | // check SL0 | |
82 | uint8_t data[250] = {0}; | |
83 | int datalen = 0; | |
84 | // https://github.com/Proxmark/proxmark3/blob/master/client/scripts/mifarePlus.lua#L161 | |
85 | uint8_t cmd[3 + 16] = {0xa8, 0x90, 0x90, 0x00}; | |
86 | int res = ExchangeRAW14a(cmd, sizeof(cmd), false, false, data, sizeof(data), &datalen); | |
87 | if (!res && datalen > 1 && data[0] == 0x09) { | |
88 | SLmode = 0; | |
89 | } | |
90 | } | |
91 | } | |
92 | ||
93 | if (SLmode != 0xff) | |
94 | PrintAndLog("Mifare Plus SL mode: SL%d", SLmode); | |
95 | else | |
96 | PrintAndLog("Mifare Plus SL mode: unknown("); | |
97 | } else { | |
98 | PrintAndLog("Mifare Plus info not available."); | |
99 | } | |
100 | ||
101 | DropField(); | |
102 | ||
103 | return 0; | |
104 | } | |
105 | ||
106 | static command_t CommandTable[] = | |
107 | { | |
108 | {"help", CmdHelp, 1, "This help"}, | |
109 | {"info", CmdHFMFPInfo, 0, "Info about Mifare Plus tag"}, | |
110 | {NULL, NULL, 0, NULL} | |
111 | }; | |
112 | ||
113 | int CmdHFMFP(const char *Cmd) { | |
114 | (void)WaitForResponseTimeout(CMD_ACK,NULL,100); | |
115 | CmdsParse(CommandTable, Cmd); | |
116 | return 0; | |
117 | } | |
118 | ||
119 | int CmdHelp(const char *Cmd) { | |
120 | CmdsHelp(CommandTable); | |
121 | return 0; | |
122 | } |