]>
git.zerfleddert.de Git - proxmark3-svn/blob - armsrc/mifaresniff.c
1 //-----------------------------------------------------------------------------
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 // Routines to support mifare classic sniffer.
9 //-----------------------------------------------------------------------------
11 #include "mifaresniff.h"
13 static int sniffState
= SNF_INIT
;
14 static uint8_t sniffUIDType
= 0;
15 static uint8_t sniffUID
[10] = {0,0,0,0,0,0,0,0,0,0};
16 static uint8_t sniffATQA
[2] = {0,0};
17 static uint8_t sniffSAK
= 0;
18 static uint8_t sniffBuf
[17];
19 static uint32_t timerData
= 0;
21 void MfSniffInit(void){
22 memset(sniffUID
, 0x00, sizeof(sniffUID
));
23 memset(sniffATQA
, 0x00, sizeof(sniffATQA
));
24 memset(sniffBuf
, 0x00, sizeof(sniffBuf
));
26 sniffUIDType
= SNF_UID_4
;
29 void MfSniffEnd(void){
31 cmd_send(CMD_ACK
,0,0,0,0,0);
35 bool RAMFUNC
MfSniffLogic(const uint8_t *data
, uint16_t len
, uint8_t *parity
, uint16_t bitCnt
, bool reader
) {
37 // reset on 7-Bit commands from reader
38 if (reader
&& (len
== 1) && (bitCnt
== 7)) {
39 sniffState
= SNF_INIT
;
44 // REQA or WUPA from reader
45 if ((len
== 1) && (reader
) && (bitCnt
== 7) ) {
47 sniffState
= SNF_WUPREQ
;
53 if ((!reader
) && (len
== 2)) {
54 sniffATQA
[0] = data
[0];
55 sniffATQA
[1] = data
[1];
56 sniffState
= SNF_ATQA
;
61 // Select ALL from reader
62 if ((reader
) && (len
== 2) && (data
[0] == 0x93) && (data
[1] == 0x20))
63 sniffState
= SNF_ANTICOL1
;
68 if ((!reader
) && (len
== 5) && ((data
[0] ^ data
[1] ^ data
[2] ^ data
[3]) == data
[4])) {
69 memcpy(sniffUID
, data
, 4);
70 sniffState
= SNF_UID1
;
75 // Select 4 Byte UID from reader
76 if ((reader
) && (len
== 9) && (data
[0] == 0x93) && (data
[1] == 0x70) && (CheckCrc14443(CRC_14443_A
, data
, 9)))
81 if ((!reader
) && (len
== 3) && (CheckCrc14443(CRC_14443_A
, data
, 3))) { // SAK from card?
83 if (sniffUID
[0] == 0x88) // CL2/3 UID part to be expected
84 sniffState
= (sniffState
== SNF_ANTICOL2
) ? SNF_ANTICOL3
: SNF_ANTICOL2
;
85 else // select completed
86 sniffState
= SNF_CARD_IDLE
;
92 if ((!reader
) && (len
== 5) && ((data
[0] ^ data
[1] ^ data
[2] ^ data
[3]) == data
[4])) {
93 sniffUID
[0] = sniffUID
[1];
94 sniffUID
[1] = sniffUID
[2];
95 sniffUID
[2] = sniffUID
[3];
96 memcpy(sniffUID
+3, data
, 4);
97 sniffUIDType
= SNF_UID_7
;
98 sniffState
= SNF_UID2
;
103 // Select 2nd part of 7 Byte UID
104 if ((reader
) && (len
== 9) && (data
[0] == 0x95) && (data
[1] == 0x70) && (CheckCrc14443(CRC_14443_A
, data
, 9)))
105 sniffState
= SNF_SAK
;
110 if ((!reader
) && (len
== 5) && ((data
[0] ^ data
[1] ^ data
[2] ^ data
[3]) == data
[4])) {
112 sniffUID
[3] = sniffUID
[4];
113 sniffUID
[4] = sniffUID
[5];
114 sniffUID
[5] = sniffUID
[6];
115 memcpy(sniffUID
+6, data
, 4);
116 sniffUIDType
= SNF_UID_10
;
117 sniffState
= SNF_UID3
;
122 // Select 3nd part of 10 Byte UID
123 if ((reader
) && (len
== 9) && (data
[0] == 0x97) && (data
[1] == 0x70) && (CheckCrc14443(CRC_14443_A
, data
, 9)))
124 sniffState
= SNF_SAK
;
127 case SNF_CARD_IDLE
:{ // trace the card select sequence
130 memcpy(sniffBuf
+ 2, sniffUID
, sizeof(sniffUID
));
131 memcpy(sniffBuf
+ 12, sniffATQA
, sizeof(sniffATQA
));
132 sniffBuf
[14] = sniffSAK
;
135 LogTrace(sniffBuf
, sizeof(sniffBuf
), 0, 0, NULL
, TRUE
);
136 } // intentionally no break;
138 LogTrace(data
, len
, 0, 0, NULL
, TRUE
);
139 sniffState
= SNF_CARD_RESP
;
140 timerData
= GetTickCount();
144 LogTrace(data
, len
, 0, 0, NULL
, FALSE
);
145 sniffState
= SNF_CARD_CMD
;
146 timerData
= GetTickCount();
150 sniffState
= SNF_INIT
;
156 bool RAMFUNC
MfSniffSend(uint16_t maxTimeoutMs
) {
157 if (BigBuf_get_traceLen() && (GetTickCount() > timerData
+ maxTimeoutMs
)) {
158 return intMfSniffSend();
163 // internal sending function. not a RAMFUNC.
164 bool intMfSniffSend() {
167 int pckLen
= BigBuf_get_traceLen();
169 uint8_t *data
= BigBuf_get_addr();
173 pckSize
= MIN(USB_CMD_DATA_SIZE
, pckLen
);
175 cmd_send(CMD_ACK
, 1, BigBuf_get_traceLen(), pckSize
, data
+ BigBuf_get_traceLen() - pckLen
, pckSize
);
182 cmd_send(CMD_ACK
,2,0,0,0,0); // 2 == data transfer is finished.