1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2018 Merlok
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
7 //-----------------------------------------------------------------------------
8 // High frequency MIFARE Plus commands
9 //-----------------------------------------------------------------------------
25 static int CmdHelp(const char *Cmd
);
27 int CmdHFMFPInfo(const char *cmd
) {
29 if (cmd
&& strlen(cmd
) > 0)
30 PrintAndLog("WARNING: command don't have any parameters.\n");
32 // info about 14a part
36 UsbCommand c
= {CMD_READER_ISO_14443a
, {ISO14A_CONNECT
| ISO14A_NO_DISCONNECT
, 0, 0}};
40 WaitForResponse(CMD_ACK
,&resp
);
42 iso14a_card_select_t card
;
43 memcpy(&card
, (iso14a_card_select_t
*)resp
.d
.asBytes
, sizeof(iso14a_card_select_t
));
45 uint64_t select_status
= resp
.arg
[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
47 if (select_status
== 1 || select_status
== 2) {
48 PrintAndLog("----------------------------------------------");
49 PrintAndLog("Mifare Plus info:");
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");
59 uint8_t SLmode
= 0xff;
60 if (card
.sak
== 0x08) {
61 PrintAndLog("SAK: Mifare Plus 2k 7bUID");
62 if (select_status
== 2) SLmode
= 1;
64 if (card
.sak
== 0x18) {
65 PrintAndLog("SAK: Mifare Plus 4k 7bUID");
66 if (select_status
== 2) SLmode
= 1;
68 if (card
.sak
== 0x10) {
69 PrintAndLog("SAK: Mifare Plus 2k");
70 if (select_status
== 2) SLmode
= 2;
72 if (card
.sak
== 0x11) {
73 PrintAndLog("SAK: Mifare Plus 4k");
74 if (select_status
== 2) SLmode
= 2;
76 if (card
.sak
== 0x20) {
77 PrintAndLog("SAK: Mifare Plus SL0/SL3 or Mifare desfire");
78 if (card
.ats_len
> 0) {
82 uint8_t data
[250] = {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) {
94 PrintAndLog("Mifare Plus SL mode: SL%d", SLmode
);
96 PrintAndLog("Mifare Plus SL mode: unknown(");
98 PrintAndLog("Mifare Plus info not available.");
106 static command_t CommandTable
[] =
108 {"help", CmdHelp
, 1, "This help"},
109 {"info", CmdHFMFPInfo
, 0, "Info about Mifare Plus tag"},
110 {NULL
, NULL
, 0, NULL
}
113 int CmdHFMFP(const char *Cmd
) {
114 (void)WaitForResponseTimeout(CMD_ACK
,NULL
,100);
115 CmdsParse(CommandTable
, Cmd
);
119 int CmdHelp(const char *Cmd
) {
120 CmdsHelp(CommandTable
);