]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/mifaresniff.c
Added library to read card info, made use of it from within mfkeys.lua script
[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
6e82300d 34// UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
39864b0b
M
35\r
36 LED_B_ON();\r
6e82300d 37 cmd_send(CMD_ACK,0,0,0,0,0);\r
38// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
39864b0b
M
39 LED_B_OFF();\r
40\r
41 return 0;\r
42}\r
43\r
71d90e54 44int RAMFUNC MfSniffLogic(const uint8_t * data, int len, uint32_t parity, int bitCnt, int reader) {\r
39864b0b 45\r
55acbb2a 46 if ((len == 1) && (bitCnt = 9) && (data[0] > 0x0F)) { \r
39864b0b
M
47 sniffState = SNF_INIT;\r
48 }\r
49\r
50 switch (sniffState) {\r
51 case SNF_INIT:{\r
52 if ((reader) && (len == 1) && (bitCnt == 9) && ((data[0] == 0x26) || (data[0] == 0x52))) { \r
53 sniffUIDType = SNF_UID_4;\r
54 memset(sniffUID, 0x00, 8);\r
55 memset(sniffATQA, 0x00, 2);\r
56 sniffSAK = 0;\r
57\r
58 sniffState = SNF_WUPREQ;\r
59 }\r
60 break;\r
61 }\r
62 case SNF_WUPREQ:{\r
63 if ((!reader) && (len == 2)) { \r
64 memcpy(sniffATQA, data, 2);\r
65\r
66 sniffState = SNF_ATQA;\r
67 }\r
68 break;\r
69 }\r
70 case SNF_ATQA:{\r
71 if ((reader) && (len == 2) && (data[0] == 0x93) && (data[1] == 0x20)) { \r
72 sniffState = SNF_ANTICOL1;\r
73 }\r
74 break;\r
75 }\r
76 case SNF_ANTICOL1:{\r
77 if ((!reader) && (len == 5) && ((data[0] ^ data[1] ^ data[2] ^ data[3]) == data[4])) { \r
78 memcpy(sniffUID + 3, data, 4);\r
79 \r
80 sniffState = SNF_UID1;\r
81 }\r
82 break;\r
83 }\r
84 case SNF_UID1:{\r
85 if ((reader) && (len == 9) && (data[0] == 0x93) && (data[1] == 0x70) && (CheckCrc14443(CRC_14443_A, data, 9))) { \r
86 sniffState = SNF_SAK;\r
87 }\r
88 break;\r
89 }\r
90 case SNF_SAK:{\r
91 if ((!reader) && (len == 3) && (CheckCrc14443(CRC_14443_A, data, 3))) { \r
92 sniffSAK = data[0];\r
93 if (sniffUID[3] == 0x88) {\r
94 sniffState = SNF_ANTICOL2;\r
95 } else {\r
96 sniffState = SNF_CARD_IDLE;\r
97 }\r
98 }\r
99 break;\r
100 }\r
101 case SNF_ANTICOL2:{\r
102 if ((!reader) && (len == 5) && ((data[0] ^ data[1] ^ data[2] ^ data[3]) == data[4])) { \r
103 memcpy(sniffUID, data, 4);\r
104 sniffUIDType = SNF_UID_7;\r
105 \r
106 sniffState = SNF_UID2;\r
107 }\r
108 break;\r
109 }\r
110 case SNF_UID2:{\r
111 if ((reader) && (len == 9) && (data[0] == 0x95) && (data[1] == 0x70) && (CheckCrc14443(CRC_14443_A, data, 9))) { \r
112 sniffState = SNF_SAK;\r
113 Dbprintf("SNF_SAK"); \r
114 }\r
115 break;\r
116 }\r
117 case SNF_CARD_IDLE:{\r
118 sniffBuf[0] = 0xFF;\r
119 sniffBuf[1] = 0xFF;\r
120 memcpy(sniffBuf + 2, sniffUID, 7);\r
121 memcpy(sniffBuf + 9, sniffATQA, 2);\r
122 sniffBuf[11] = sniffSAK;\r
123 sniffBuf[12] = 0xFF;\r
124 sniffBuf[13] = 0xFF;\r
71d90e54 125 LogTrace(sniffBuf, 14, 0, parity, true);\r
39864b0b
M
126 timerData = GetTickCount();\r
127 }\r
128 case SNF_CARD_CMD:{\r
71d90e54 129 LogTrace(data, len, 0, parity, true);\r
39864b0b
M
130\r
131 sniffState = SNF_CARD_RESP;\r
132 timerData = GetTickCount();\r
133 break;\r
134 }\r
135 case SNF_CARD_RESP:{\r
71d90e54 136 LogTrace(data, len, 0, parity, false);\r
39864b0b
M
137\r
138 sniffState = SNF_CARD_CMD;\r
139 timerData = GetTickCount();\r
140 break;\r
141 }\r
142 \r
143 default:\r
144 sniffState = SNF_INIT;\r
145 break;\r
146 }\r
147\r
148 return 0;\r
149}\r
150\r
151int RAMFUNC MfSniffSend(int maxTimeoutMs) {\r
152 if (traceLen && (timerData + maxTimeoutMs < GetTickCount())) {\r
153 return intMfSniffSend();\r
154 }\r
155 return 0;\r
156}\r
157\r
158// internal seding function. not a RAMFUNC.\r
159int intMfSniffSend() {\r
160 \r
161 int pckSize = 0;\r
162 int pckLen = traceLen;\r
163 int pckNum = 0;\r
164 \r
165 if (!traceLen) return 0;\r
166\r
55acbb2a 167 FpgaDisableSscDma();\r
39864b0b
M
168\r
169 while (pckLen > 0) {\r
902cb3c0 170 pckSize = MIN(32, pckLen);\r
6e82300d 171// UsbCommand ack = {CMD_ACK, {1, pckSize, pckNum}};\r
172// memcpy(ack.d.asBytes, trace + traceLen - pckLen, pckSize);\r
39864b0b
M
173 \r
174 LED_B_ON();\r
6e82300d 175 cmd_send(CMD_ACK,1,pckSize,pckNum,trace + traceLen - pckLen,pckSize);\r
176// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
177// SpinDelay(20);\r
39864b0b
M
178 LED_B_OFF();\r
179\r
180 pckLen -= pckSize;\r
181 pckNum++;\r
182 }\r
183\r
6e82300d 184// UsbCommand ack = {CMD_ACK, {2, 0, 0}};\r
39864b0b
M
185\r
186 LED_B_ON();\r
6e82300d 187 cmd_send(CMD_ACK,2,0,0,0,0);\r
188// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
39864b0b
M
189 LED_B_OFF();\r
190\r
191 traceLen = 0;\r
192 memset(trace, 0x44, TRACE_SIZE);\r
193 \r
194 return 1;\r
195}\r
Impressum, Datenschutz