1 //-----------------------------------------------------------------------------
2 // Copyright (C) Merlok - 2017
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 // Command: hf mf list. It shows data from arm buffer.
9 //-----------------------------------------------------------------------------
11 #include "cmdhflist.h"
21 #include "iso14443crc.h"
23 #include "protocols.h"
35 static enum MifareAuthSeq MifareAuthState
;
38 * @brief iso14443A_CRC_check Checks CRC in command or response
42 * @return 0 : CRC-command, CRC not ok
43 * 1 : CRC-command, CRC ok
46 uint8_t iso14443A_CRC_check(bool isResponse
, uint8_t* data
, uint8_t len
)
50 if(len
<= 2) return 2;
52 if(isResponse
& (len
< 6)) return 2;
54 ComputeCrc14443(CRC_14443_A
, data
, len
-2, &b1
, &b2
);
55 if (b1
!= data
[len
-2] || b2
!= data
[len
-1]) {
62 uint8_t mifare_CRC_check(bool isResponse
, uint8_t* data
, uint8_t len
)
64 switch(MifareAuthState
) {
69 return iso14443A_CRC_check(isResponse
, data
, len
);
75 void annotateIso14443a(char *exp
, size_t size
, uint8_t* cmd
, uint8_t cmdsize
)
79 case ISO14443A_CMD_WUPA
: snprintf(exp
,size
,"WUPA"); break;
80 case ISO14443A_CMD_ANTICOLL_OR_SELECT
:{
81 // 93 20 = Anticollision (usage: 9320 - answer: 4bytes UID+1byte UID-bytes-xor)
82 // 93 70 = Select (usage: 9370+5bytes 9320 answer - answer: 1byte SAK)
85 snprintf(exp
,size
,"SELECT_UID"); break;
88 snprintf(exp
,size
,"ANTICOLL"); break;
91 case ISO14443A_CMD_ANTICOLL_OR_SELECT_2
:{
92 //95 20 = Anticollision of cascade level2
93 //95 70 = Select of cascade level2
96 snprintf(exp
,size
,"SELECT_UID-2"); break;
99 snprintf(exp
,size
,"ANTICOLL-2"); break;
102 case ISO14443A_CMD_REQA
: snprintf(exp
,size
,"REQA"); break;
103 case ISO14443A_CMD_READBLOCK
: snprintf(exp
,size
,"READBLOCK(%d)",cmd
[1]); break;
104 case ISO14443A_CMD_WRITEBLOCK
: snprintf(exp
,size
,"WRITEBLOCK(%d)",cmd
[1]); break;
105 case ISO14443A_CMD_HALT
:
106 snprintf(exp
,size
,"HALT");
107 MifareAuthState
= masNone
;
109 case ISO14443A_CMD_RATS
: snprintf(exp
,size
,"RATS"); break;
110 case MIFARE_CMD_INC
: snprintf(exp
,size
,"INC(%d)",cmd
[1]); break;
111 case MIFARE_CMD_DEC
: snprintf(exp
,size
,"DEC(%d)",cmd
[1]); break;
112 case MIFARE_CMD_RESTORE
: snprintf(exp
,size
,"RESTORE(%d)",cmd
[1]); break;
113 case MIFARE_CMD_TRANSFER
: snprintf(exp
,size
,"TRANSFER(%d)",cmd
[1]); break;
114 case MIFARE_AUTH_KEYA
:
116 snprintf(exp
,size
,"AUTH-A(%d)",cmd
[1]);
117 MifareAuthState
= masNt
;
119 // case MIFARE_ULEV1_VERSION : both 0x60.
120 snprintf(exp
,size
,"EV1 VERSION");
123 case MIFARE_AUTH_KEYB
:
124 MifareAuthState
= masNt
;
125 snprintf(exp
,size
,"AUTH-B(%d)",cmd
[1]);
127 case MIFARE_MAGICWUPC1
: snprintf(exp
,size
,"MAGIC WUPC1"); break;
128 case MIFARE_MAGICWUPC2
: snprintf(exp
,size
,"MAGIC WUPC2"); break;
129 case MIFARE_MAGICWIPEC
: snprintf(exp
,size
,"MAGIC WIPEC"); break;
130 case MIFARE_ULC_AUTH_1
: snprintf(exp
,size
,"AUTH "); break;
131 case MIFARE_ULC_AUTH_2
: snprintf(exp
,size
,"AUTH_ANSW"); break;
132 case MIFARE_ULEV1_AUTH
:
134 snprintf(exp
,size
,"PWD-AUTH KEY: 0x%02x%02x%02x%02x", cmd
[1], cmd
[2], cmd
[3], cmd
[4] );
136 snprintf(exp
,size
,"PWD-AUTH");
138 case MIFARE_ULEV1_FASTREAD
:{
139 if ( cmdsize
>=3 && cmd
[2] <= 0xE6)
140 snprintf(exp
,size
,"READ RANGE (%d-%d)",cmd
[1],cmd
[2]);
142 snprintf(exp
,size
,"?");
145 case MIFARE_ULC_WRITE
:{
147 snprintf(exp
,size
,"WRITEBLOCK(%d)",cmd
[1]);
149 snprintf(exp
,size
,"?");
152 case MIFARE_ULEV1_READ_CNT
:{
154 snprintf(exp
,size
,"READ CNT(%d)",cmd
[1]);
156 snprintf(exp
,size
,"?");
159 case MIFARE_ULEV1_INCR_CNT
:{
161 snprintf(exp
,size
,"INCR(%d)",cmd
[1]);
163 snprintf(exp
,size
,"?");
166 case MIFARE_ULEV1_READSIG
: snprintf(exp
,size
,"READ_SIG"); break;
167 case MIFARE_ULEV1_CHECKTEAR
: snprintf(exp
,size
,"CHK_TEARING(%d)",cmd
[1]); break;
168 case MIFARE_ULEV1_VCSL
: snprintf(exp
,size
,"VCSL"); break;
169 default: snprintf(exp
,size
,"?"); break;
174 void annotateMifare(char *exp
, size_t size
, uint8_t* cmd
, uint8_t cmdsize
, bool isResponse
) {
175 // uint32_t uid; // UID
176 static uint32_t nt
; // tag challenge
177 // uint32_t nt_enc; // encrypted tag challenge
178 // uint8_t nt_enc_par; // encrypted tag challenge parity
179 static uint32_t nr_enc
; // encrypted reader challenge
180 static uint32_t ar_enc
; // encrypted reader response
181 // uint8_t ar_enc_par; // encrypted reader response parity
182 static uint32_t at_enc
; // encrypted tag response
183 // uint8_t at_enc_par; // encrypted tag response parity
185 switch(MifareAuthState
) {
187 if (cmdsize
== 4 && isResponse
) {
188 snprintf(exp
,size
,"AUTH: nt %s", (nt
) ? "(enc)" : "");
189 MifareAuthState
= masNrAr
;
190 nt
= bytes_to_num(cmd
, cmdsize
);
193 MifareAuthState
= masError
;
197 if (cmdsize
== 8 && !isResponse
) {
198 snprintf(exp
,size
,"AUTH: nr ar (enc)");
199 MifareAuthState
= masAt
;
200 nr_enc
= bytes_to_num(cmd
, cmdsize
);
201 ar_enc
= bytes_to_num(&cmd
[3], cmdsize
);
204 MifareAuthState
= masError
;
208 if (cmdsize
== 4 && isResponse
) {
209 snprintf(exp
,size
,"AUTH: at (enc)");
210 MifareAuthState
= masData
;
211 at_enc
= bytes_to_num(cmd
, cmdsize
);
214 MifareAuthState
= masError
;
222 annotateIso14443a(exp
, size
, cmd
, cmdsize
);