]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/mifaresniff.c
major USB update
[proxmark3-svn] / armsrc / mifaresniff.c
CommitLineData
b62a5a84
M
1//-----------------------------------------------------------------------------\r
2// Merlok - 2012\r
3//\r
4// This code is licensed to you under the terms of the GNU GPL, version 2 or,\r
5// at your option, any later version. See the LICENSE.txt file for the text of\r
6// the license.\r
7//-----------------------------------------------------------------------------\r
8// Routines to support mifare classic sniffer.\r
9//-----------------------------------------------------------------------------\r
10\r
11#include "mifaresniff.h"\r
12#include "apps.h"\r
13\r
39864b0b
M
14static int sniffState = SNF_INIT;\r
15static uint8_t sniffUIDType;\r
16static uint8_t sniffUID[8];\r
17static uint8_t sniffATQA[2];\r
18static uint8_t sniffSAK;\r
19static uint8_t sniffBuf[16];\r
20static int timerData = 0;\r
b62a5a84
M
21\r
22\r
39864b0b
M
23int MfSniffInit(void){\r
24 rsamples = 0;\r
25 memset(sniffUID, 0x00, 8);\r
26 memset(sniffATQA, 0x00, 2);\r
27 sniffSAK = 0;\r
28 sniffUIDType = SNF_UID_4;\r
29\r
30 return 0;\r
31}\r
32\r
33int MfSniffEnd(void){\r
34 UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
35\r
36 LED_B_ON();\r
37 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
38 LED_B_OFF();\r
39\r
40 return 0;\r
41}\r
42\r
71d90e54 43int RAMFUNC MfSniffLogic(const uint8_t * data, int len, uint32_t parity, int bitCnt, int reader) {\r
39864b0b 44\r
55acbb2a 45 if ((len == 1) && (bitCnt = 9) && (data[0] > 0x0F)) { \r
39864b0b
M
46 sniffState = SNF_INIT;\r
47 }\r
48\r
49 switch (sniffState) {\r
50 case SNF_INIT:{\r
51 if ((reader) && (len == 1) && (bitCnt == 9) && ((data[0] == 0x26) || (data[0] == 0x52))) { \r
52 sniffUIDType = SNF_UID_4;\r
53 memset(sniffUID, 0x00, 8);\r
54 memset(sniffATQA, 0x00, 2);\r
55 sniffSAK = 0;\r
56\r
57 sniffState = SNF_WUPREQ;\r
58 }\r
59 break;\r
60 }\r
61 case SNF_WUPREQ:{\r
62 if ((!reader) && (len == 2)) { \r
63 memcpy(sniffATQA, data, 2);\r
64\r
65 sniffState = SNF_ATQA;\r
66 }\r
67 break;\r
68 }\r
69 case SNF_ATQA:{\r
70 if ((reader) && (len == 2) && (data[0] == 0x93) && (data[1] == 0x20)) { \r
71 sniffState = SNF_ANTICOL1;\r
72 }\r
73 break;\r
74 }\r
75 case SNF_ANTICOL1:{\r
76 if ((!reader) && (len == 5) && ((data[0] ^ data[1] ^ data[2] ^ data[3]) == data[4])) { \r
77 memcpy(sniffUID + 3, data, 4);\r
78 \r
79 sniffState = SNF_UID1;\r
80 }\r
81 break;\r
82 }\r
83 case SNF_UID1:{\r
84 if ((reader) && (len == 9) && (data[0] == 0x93) && (data[1] == 0x70) && (CheckCrc14443(CRC_14443_A, data, 9))) { \r
85 sniffState = SNF_SAK;\r
86 }\r
87 break;\r
88 }\r
89 case SNF_SAK:{\r
90 if ((!reader) && (len == 3) && (CheckCrc14443(CRC_14443_A, data, 3))) { \r
91 sniffSAK = data[0];\r
92 if (sniffUID[3] == 0x88) {\r
93 sniffState = SNF_ANTICOL2;\r
94 } else {\r
95 sniffState = SNF_CARD_IDLE;\r
96 }\r
97 }\r
98 break;\r
99 }\r
100 case SNF_ANTICOL2:{\r
101 if ((!reader) && (len == 5) && ((data[0] ^ data[1] ^ data[2] ^ data[3]) == data[4])) { \r
102 memcpy(sniffUID, data, 4);\r
103 sniffUIDType = SNF_UID_7;\r
104 \r
105 sniffState = SNF_UID2;\r
106 }\r
107 break;\r
108 }\r
109 case SNF_UID2:{\r
110 if ((reader) && (len == 9) && (data[0] == 0x95) && (data[1] == 0x70) && (CheckCrc14443(CRC_14443_A, data, 9))) { \r
111 sniffState = SNF_SAK;\r
112 Dbprintf("SNF_SAK"); \r
113 }\r
114 break;\r
115 }\r
116 case SNF_CARD_IDLE:{\r
117 sniffBuf[0] = 0xFF;\r
118 sniffBuf[1] = 0xFF;\r
119 memcpy(sniffBuf + 2, sniffUID, 7);\r
120 memcpy(sniffBuf + 9, sniffATQA, 2);\r
121 sniffBuf[11] = sniffSAK;\r
122 sniffBuf[12] = 0xFF;\r
123 sniffBuf[13] = 0xFF;\r
71d90e54 124 LogTrace(sniffBuf, 14, 0, parity, true);\r
39864b0b
M
125 timerData = GetTickCount();\r
126 }\r
127 case SNF_CARD_CMD:{\r
71d90e54 128 LogTrace(data, len, 0, parity, true);\r
39864b0b
M
129\r
130 sniffState = SNF_CARD_RESP;\r
131 timerData = GetTickCount();\r
132 break;\r
133 }\r
134 case SNF_CARD_RESP:{\r
71d90e54 135 LogTrace(data, len, 0, parity, false);\r
39864b0b
M
136\r
137 sniffState = SNF_CARD_CMD;\r
138 timerData = GetTickCount();\r
139 break;\r
140 }\r
141 \r
142 default:\r
143 sniffState = SNF_INIT;\r
144 break;\r
145 }\r
146\r
147 return 0;\r
148}\r
149\r
150int RAMFUNC MfSniffSend(int maxTimeoutMs) {\r
151 if (traceLen && (timerData + maxTimeoutMs < GetTickCount())) {\r
152 return intMfSniffSend();\r
153 }\r
154 return 0;\r
155}\r
156\r
157// internal seding function. not a RAMFUNC.\r
158int intMfSniffSend() {\r
159 \r
160 int pckSize = 0;\r
161 int pckLen = traceLen;\r
162 int pckNum = 0;\r
163 \r
164 if (!traceLen) return 0;\r
165\r
55acbb2a 166 FpgaDisableSscDma();\r
39864b0b
M
167\r
168 while (pckLen > 0) {\r
902cb3c0 169 pckSize = MIN(32, pckLen);\r
39864b0b
M
170 UsbCommand ack = {CMD_ACK, {1, pckSize, pckNum}};\r
171 memcpy(ack.d.asBytes, trace + traceLen - pckLen, pckSize);\r
172 \r
173 LED_B_ON();\r
174 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
175 SpinDelay(20);\r
176 LED_B_OFF();\r
177\r
178 pckLen -= pckSize;\r
179 pckNum++;\r
180 }\r
181\r
182 UsbCommand ack = {CMD_ACK, {2, 0, 0}};\r
183\r
184 LED_B_ON();\r
185 UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
186 LED_B_OFF();\r
187\r
188 traceLen = 0;\r
189 memset(trace, 0x44, TRACE_SIZE);\r
190 \r
191 return 1;\r
192}\r
Impressum, Datenschutz