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