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