]> git.zerfleddert.de Git - proxmark3-svn/blob - armsrc/mifaresniff.c
592034786604b0b49f0080cffc168eb7ff25003d
[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 = 0;
16 static uint8_t sniffUID[10] = {0,0,0,0,0,0,0,0,0,0};
17 static uint8_t sniffATQA[2] = {0,0};
18 static uint8_t sniffSAK = 0;
19 static uint8_t sniffBuf[19];
20 static uint32_t timerData = 0;
21
22
23 void MfSniffInit(void){
24 memset(sniffUID, 0x00, sizeof(sniffUID));
25 memset(sniffATQA, 0x00, sizeof(sniffATQA));
26 memset(sniffBuf, 0x00, sizeof(sniffBuf));
27 sniffSAK = 0;
28 sniffUIDType = SNF_UID_4;
29 }
30
31 void MfSniffEnd(void){
32 LED_B_ON();
33 cmd_send(CMD_ACK,0,0,0,0,0);
34 LED_B_OFF();
35 }
36
37 bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, uint16_t bitCnt, bool reader) {
38
39 // reset on 7-Bit commands from reader
40 if (reader && (len == 1) && (bitCnt == 7)) {
41 sniffState = SNF_INIT;
42 }
43
44 switch (sniffState) {
45 case SNF_INIT:{
46 // REQA or WUPA from reader
47 if ((len == 1) && (reader) && (bitCnt == 7) ) {
48 MfSniffInit();
49 sniffState = SNF_WUPREQ;
50 }
51 break;
52 }
53 case SNF_WUPREQ:{
54 // ATQA from tag
55 if ((!reader) && (len == 2)) {
56 sniffATQA[0] = data[0];
57 sniffATQA[1] = data[1];
58 sniffState = SNF_ATQA;
59 }
60 break;
61 }
62 case SNF_ATQA:{
63 // Select ALL from reader
64 if ((reader) && (len == 2) && (data[0] == 0x93) && (data[1] == 0x20)) {
65 sniffState = SNF_ANTICOL1;
66 }
67 break;
68 }
69 case SNF_ANTICOL1:{
70 // UID from tag (CL1)
71 if ((!reader) && (len == 5) && ((data[0] ^ data[1] ^ data[2] ^ data[3]) == data[4])) {
72 memcpy(sniffUID + 3, data, 4);
73 sniffState = SNF_UID1;
74 }
75 break;
76 }
77 case SNF_UID1:{
78 // Select 4 Byte UID from reader
79 if ((reader) && (len == 9) && (data[0] == 0x93) && (data[1] == 0x70) && (CheckCrc14443(CRC_14443_A, data, 9))) {
80 sniffState = SNF_SAK;
81 }
82 break;
83 }
84 case SNF_SAK:{
85 if ((!reader) && (len == 3) && (CheckCrc14443(CRC_14443_A, data, 3))) { // SAK from card?
86 sniffSAK = data[0];
87 if (sniffUID[3] == 0x88) { // CL2 UID part to be expected
88 sniffState = SNF_ANTICOL2;
89 } else { // select completed
90 sniffState = SNF_CARD_IDLE;
91 }
92 }
93 break;
94 }
95 case SNF_ANTICOL2:{
96 // CL2 UID
97 if ((!reader) && (len == 5) && ((data[0] ^ data[1] ^ data[2] ^ data[3]) == data[4])) {
98 memcpy(sniffUID, sniffUID+4, 3);
99 memcpy(sniffUID+3, data, 4);
100 sniffUIDType = SNF_UID_7;
101 sniffState = SNF_UID2;
102 }
103 break;
104 }
105 case SNF_UID2:{
106 // Select 2nd part of 7 Byte UID
107 if ((reader) && (len == 9) && (data[0] == 0x95) && (data[1] == 0x70) && (CheckCrc14443(CRC_14443_A, data, 9))) {
108 sniffState = SNF_SAK;
109 }
110 break;
111 }
112 case SNF_ANTICOL3:{
113 // CL3 UID
114 if ((!reader) && (len == 5) && ((data[0] ^ data[1] ^ data[2] ^ data[3]) == data[4])) {
115 memcpy(sniffUID, sniffUID+4, 3);
116 memcpy(sniffUID+3, data, 4);
117 sniffUIDType = SNF_UID_10;
118 sniffState = SNF_UID3;
119 }
120 break;
121 }
122 case SNF_UID3:{
123 // Select 3nd part of 10 Byte UID
124 if ((reader) && (len == 9) && (data[0] == 0x97) && (data[1] == 0x70) && (CheckCrc14443(CRC_14443_A, data, 9))) {
125 sniffState = SNF_SAK;
126 }
127 break;
128 }
129 case SNF_CARD_IDLE:{ // trace the card select sequence
130 sniffBuf[0] = 0xFF;
131 sniffBuf[1] = 0xFF;
132 memcpy(sniffBuf + 2, sniffUID, sizeof(sniffUID));
133 memcpy(sniffBuf + 9, sniffATQA, sizeof(sniffATQA));
134 sniffBuf[14] = sniffSAK;
135 sniffBuf[15] = 0xFF;
136 sniffBuf[16] = 0xFF;
137 LogTrace(sniffBuf, sizeof(sniffBuf), 0, 0, NULL, TRUE);
138 } // intentionally no break;
139 case SNF_CARD_CMD:{
140 LogTrace(data, len, 0, 0, NULL, TRUE);
141 sniffState = SNF_CARD_RESP;
142 timerData = GetTickCount();
143 break;
144 }
145 case SNF_CARD_RESP:{
146 LogTrace(data, len, 0, 0, NULL, FALSE);
147 sniffState = SNF_CARD_CMD;
148 timerData = GetTickCount();
149 break;
150 }
151 default:
152 sniffState = SNF_INIT;
153 break;
154 }
155 return FALSE;
156 }
157
158 bool RAMFUNC MfSniffSend(uint16_t maxTimeoutMs) {
159 if (BigBuf_get_traceLen() && (GetTickCount() > timerData + maxTimeoutMs)) {
160 return intMfSniffSend();
161 }
162 return FALSE;
163 }
164
165 // internal sending function. not a RAMFUNC.
166 bool intMfSniffSend() {
167
168 int pckSize = 0;
169 int pckLen = BigBuf_get_traceLen();
170 int pckNum = 0;
171 uint8_t *trace = BigBuf_get_addr();
172
173 FpgaDisableSscDma();
174 while (pckLen > 0) {
175 pckSize = MIN(USB_CMD_DATA_SIZE, pckLen);
176 LED_B_ON();
177 cmd_send(CMD_ACK, 1, BigBuf_get_traceLen(), pckSize, trace + BigBuf_get_traceLen() - pckLen, pckSize);
178 LED_B_OFF();
179 pckLen -= pckSize;
180 pckNum++;
181 }
182
183 LED_B_ON();
184 cmd_send(CMD_ACK,2,0,0,0,0);
185 LED_B_OFF();
186
187 clear_trace();
188 return TRUE;
189 }
Impressum, Datenschutz