]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/iso14443a.c
Attempt at getting the windows client to at least compile without bombing out with...
[proxmark3-svn] / armsrc / iso14443a.c
CommitLineData
6658905f 1//-----------------------------------------------------------------------------\r
2// Routines to support ISO 14443 type A.\r
3//\r
4// Gerhard de Koning Gans - May 2008\r
5//-----------------------------------------------------------------------------\r
6#include <proxmark3.h>\r
7#include "apps.h"\r
7fe9b0b7 8#include "iso14443crc.h"\r
6658905f 9\r
d24438f8 10static BYTE *trace = (BYTE *) BigBuf;\r
11static int traceLen = 0;\r
12static int rsamples = 0;\r
32cfae43 13static BOOL tracing = TRUE;\r
d24438f8 14\r
6658905f 15typedef enum {\r
16 SEC_D = 1,\r
17 SEC_E = 2,\r
18 SEC_F = 3,\r
19 SEC_X = 4,\r
20 SEC_Y = 5,\r
21 SEC_Z = 6\r
22} SecType;\r
23\r
d24438f8 24static const BYTE OddByteParity[256] = {\r
25 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\r
26 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
27 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
28 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\r
29 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
30 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\r
31 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\r
32 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
33 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
34 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\r
35 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\r
36 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
37 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,\r
38 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
39 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,\r
40 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1\r
41};\r
42\r
84c02e97 43// BIG CHANGE - UNDERSTAND THIS BEFORE WE COMMIT\r
44#define RECV_CMD_OFFSET 3032\r
45#define RECV_RES_OFFSET 3096\r
46#define DMA_BUFFER_OFFSET 3160\r
47#define DMA_BUFFER_SIZE 4096\r
48#define TRACE_LENGTH 3000\r
49\r
d24438f8 50//-----------------------------------------------------------------------------\r
51// Generate the parity value for a byte sequence\r
52// \r
53//-----------------------------------------------------------------------------\r
54DWORD GetParity(const BYTE * pbtCmd, int iLen)\r
55{\r
56 int i;\r
57 DWORD dwPar = 0;\r
58 \r
59 // Generate the encrypted data\r
60 for (i = 0; i < iLen; i++) {\r
61 // Save the encrypted parity bit\r
62 dwPar |= ((OddByteParity[pbtCmd[i]]) << i);\r
63 }\r
64 return dwPar;\r
65}\r
66\r
84c02e97 67static void AppendCrc14443a(BYTE* data, int len)\r
68{\r
69 ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1);\r
70}\r
71\r
72BOOL LogTrace(const BYTE * btBytes, int iLen, int iSamples, DWORD dwParity, BOOL bReader)\r
73{\r
74 // Return when trace is full\r
75 if (traceLen >= TRACE_LENGTH) return FALSE;\r
76 \r
77 // Trace the random, i'm curious\r
78 rsamples += iSamples;\r
79 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
80 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
81 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
82 trace[traceLen++] = ((rsamples >> 24) & 0xff);\r
83 if (!bReader) {\r
84 trace[traceLen - 1] |= 0x80;\r
85 }\r
86 trace[traceLen++] = ((dwParity >> 0) & 0xff);\r
87 trace[traceLen++] = ((dwParity >> 8) & 0xff);\r
88 trace[traceLen++] = ((dwParity >> 16) & 0xff);\r
89 trace[traceLen++] = ((dwParity >> 24) & 0xff);\r
90 trace[traceLen++] = iLen;\r
91 memcpy(trace + traceLen, btBytes, iLen);\r
92 traceLen += iLen;\r
93 return TRUE;\r
94}\r
95\r
32cfae43 96BOOL LogTraceInfo(byte_t* data, size_t len)\r
97{\r
98 return LogTrace(data,len,0,GetParity(data,len),TRUE);\r
99}\r
100\r
6658905f 101//-----------------------------------------------------------------------------\r
102// The software UART that receives commands from the reader, and its state\r
103// variables.\r
104//-----------------------------------------------------------------------------\r
105static struct {\r
106 enum {\r
107 STATE_UNSYNCD,\r
108 STATE_START_OF_COMMUNICATION,\r
109 STATE_MILLER_X,\r
110 STATE_MILLER_Y,\r
111 STATE_MILLER_Z,\r
112 STATE_ERROR_WAIT\r
113 } state;\r
114 WORD shiftReg;\r
115 int bitCnt;\r
116 int byteCnt;\r
117 int byteCntMax;\r
118 int posCnt;\r
119 int syncBit;\r
120 int parityBits;\r
121 int samples;\r
122 int highCnt;\r
123 int bitBuffer;\r
124 enum {\r
125 DROP_NONE,\r
126 DROP_FIRST_HALF,\r
127 DROP_SECOND_HALF\r
128 } drop;\r
129 BYTE *output;\r
130} Uart;\r
131\r
132static BOOL MillerDecoding(int bit)\r
133{\r
134 int error = 0;\r
135 int bitright;\r
136\r
137 if(!Uart.bitBuffer) {\r
138 Uart.bitBuffer = bit ^ 0xFF0;\r
139 return FALSE;\r
140 }\r
141 else {\r
142 Uart.bitBuffer <<= 4;\r
143 Uart.bitBuffer ^= bit;\r
144 }\r
145\r
146 BOOL EOC = FALSE;\r
147\r
148 if(Uart.state != STATE_UNSYNCD) {\r
149 Uart.posCnt++;\r
150\r
151 if((Uart.bitBuffer & Uart.syncBit) ^ Uart.syncBit) {\r
152 bit = 0x00;\r
153 }\r
154 else {\r
155 bit = 0x01;\r
156 }\r
157 if(((Uart.bitBuffer << 1) & Uart.syncBit) ^ Uart.syncBit) {\r
158 bitright = 0x00;\r
159 }\r
160 else {\r
161 bitright = 0x01;\r
162 }\r
163 if(bit != bitright) { bit = bitright; }\r
164\r
165 if(Uart.posCnt == 1) {\r
166 // measurement first half bitperiod\r
167 if(!bit) {\r
168 Uart.drop = DROP_FIRST_HALF;\r
169 }\r
170 }\r
171 else {\r
172 // measurement second half bitperiod\r
173 if(!bit & (Uart.drop == DROP_NONE)) {\r
174 Uart.drop = DROP_SECOND_HALF;\r
175 }\r
176 else if(!bit) {\r
177 // measured a drop in first and second half\r
178 // which should not be possible\r
179 Uart.state = STATE_ERROR_WAIT;\r
180 error = 0x01;\r
181 }\r
182\r
183 Uart.posCnt = 0;\r
184\r
185 switch(Uart.state) {\r
186 case STATE_START_OF_COMMUNICATION:\r
187 Uart.shiftReg = 0;\r
188 if(Uart.drop == DROP_SECOND_HALF) {\r
189 // error, should not happen in SOC\r
190 Uart.state = STATE_ERROR_WAIT;\r
191 error = 0x02;\r
192 }\r
193 else {\r
194 // correct SOC\r
195 Uart.state = STATE_MILLER_Z;\r
196 }\r
197 break;\r
198\r
199 case STATE_MILLER_Z:\r
200 Uart.bitCnt++;\r
201 Uart.shiftReg >>= 1;\r
202 if(Uart.drop == DROP_NONE) {\r
203 // logic '0' followed by sequence Y\r
204 // end of communication\r
205 Uart.state = STATE_UNSYNCD;\r
206 EOC = TRUE;\r
207 }\r
208 // if(Uart.drop == DROP_FIRST_HALF) {\r
209 // Uart.state = STATE_MILLER_Z; stay the same\r
210 // we see a logic '0' }\r
211 if(Uart.drop == DROP_SECOND_HALF) {\r
212 // we see a logic '1'\r
213 Uart.shiftReg |= 0x100;\r
214 Uart.state = STATE_MILLER_X;\r
215 }\r
216 break;\r
217\r
218 case STATE_MILLER_X:\r
219 Uart.shiftReg >>= 1;\r
220 if(Uart.drop == DROP_NONE) {\r
221 // sequence Y, we see a '0'\r
222 Uart.state = STATE_MILLER_Y;\r
223 Uart.bitCnt++;\r
224 }\r
225 if(Uart.drop == DROP_FIRST_HALF) {\r
226 // Would be STATE_MILLER_Z\r
227 // but Z does not follow X, so error\r
228 Uart.state = STATE_ERROR_WAIT;\r
229 error = 0x03;\r
230 }\r
231 if(Uart.drop == DROP_SECOND_HALF) {\r
232 // We see a '1' and stay in state X\r
233 Uart.shiftReg |= 0x100;\r
234 Uart.bitCnt++;\r
235 }\r
236 break;\r
237\r
238 case STATE_MILLER_Y:\r
239 Uart.bitCnt++;\r
240 Uart.shiftReg >>= 1;\r
241 if(Uart.drop == DROP_NONE) {\r
242 // logic '0' followed by sequence Y\r
243 // end of communication\r
244 Uart.state = STATE_UNSYNCD;\r
245 EOC = TRUE;\r
246 }\r
247 if(Uart.drop == DROP_FIRST_HALF) {\r
248 // we see a '0'\r
249 Uart.state = STATE_MILLER_Z;\r
250 }\r
251 if(Uart.drop == DROP_SECOND_HALF) {\r
252 // We see a '1' and go to state X\r
253 Uart.shiftReg |= 0x100;\r
254 Uart.state = STATE_MILLER_X;\r
255 }\r
256 break;\r
257\r
258 case STATE_ERROR_WAIT:\r
259 // That went wrong. Now wait for at least two bit periods\r
260 // and try to sync again\r
261 if(Uart.drop == DROP_NONE) {\r
262 Uart.highCnt = 6;\r
263 Uart.state = STATE_UNSYNCD;\r
264 }\r
265 break;\r
266\r
267 default:\r
268 Uart.state = STATE_UNSYNCD;\r
269 Uart.highCnt = 0;\r
270 break;\r
271 }\r
272\r
273 Uart.drop = DROP_NONE;\r
274\r
275 // should have received at least one whole byte...\r
276 if((Uart.bitCnt == 2) && EOC && (Uart.byteCnt > 0)) {\r
277 return TRUE;\r
278 }\r
279\r
280 if(Uart.bitCnt == 9) {\r
281 Uart.output[Uart.byteCnt] = (Uart.shiftReg & 0xff);\r
282 Uart.byteCnt++;\r
283\r
284 Uart.parityBits <<= 1;\r
285 Uart.parityBits ^= ((Uart.shiftReg >> 8) & 0x01);\r
286\r
287 if(EOC) {\r
288 // when End of Communication received and\r
289 // all data bits processed..\r
290 return TRUE;\r
291 }\r
292 Uart.bitCnt = 0;\r
293 }\r
294\r
295 /*if(error) {\r
296 Uart.output[Uart.byteCnt] = 0xAA;\r
297 Uart.byteCnt++;\r
298 Uart.output[Uart.byteCnt] = error & 0xFF;\r
299 Uart.byteCnt++;\r
300 Uart.output[Uart.byteCnt] = 0xAA;\r
301 Uart.byteCnt++;\r
302 Uart.output[Uart.byteCnt] = (Uart.bitBuffer >> 8) & 0xFF;\r
303 Uart.byteCnt++;\r
304 Uart.output[Uart.byteCnt] = Uart.bitBuffer & 0xFF;\r
305 Uart.byteCnt++;\r
306 Uart.output[Uart.byteCnt] = (Uart.syncBit >> 3) & 0xFF;\r
307 Uart.byteCnt++;\r
308 Uart.output[Uart.byteCnt] = 0xAA;\r
309 Uart.byteCnt++;\r
310 return TRUE;\r
311 }*/\r
312 }\r
313\r
314 }\r
315 else {\r
316 bit = Uart.bitBuffer & 0xf0;\r
317 bit >>= 4;\r
318 bit ^= 0x0F;\r
319 if(bit) {\r
320 // should have been high or at least (4 * 128) / fc\r
321 // according to ISO this should be at least (9 * 128 + 20) / fc\r
322 if(Uart.highCnt == 8) {\r
323 // we went low, so this could be start of communication\r
324 // it turns out to be safer to choose a less significant\r
325 // syncbit... so we check whether the neighbour also represents the drop\r
326 Uart.posCnt = 1; // apparently we are busy with our first half bit period\r
327 Uart.syncBit = bit & 8;\r
328 Uart.samples = 3;\r
329 if(!Uart.syncBit) { Uart.syncBit = bit & 4; Uart.samples = 2; }\r
330 else if(bit & 4) { Uart.syncBit = bit & 4; Uart.samples = 2; bit <<= 2; }\r
331 if(!Uart.syncBit) { Uart.syncBit = bit & 2; Uart.samples = 1; }\r
332 else if(bit & 2) { Uart.syncBit = bit & 2; Uart.samples = 1; bit <<= 1; }\r
333 if(!Uart.syncBit) { Uart.syncBit = bit & 1; Uart.samples = 0;\r
334 if(Uart.syncBit & (Uart.bitBuffer & 8)) {\r
335 Uart.syncBit = 8;\r
336\r
337 // the first half bit period is expected in next sample\r
338 Uart.posCnt = 0;\r
339 Uart.samples = 3;\r
340 }\r
341 }\r
342 else if(bit & 1) { Uart.syncBit = bit & 1; Uart.samples = 0; }\r
343\r
344 Uart.syncBit <<= 4;\r
345 Uart.state = STATE_START_OF_COMMUNICATION;\r
346 Uart.drop = DROP_FIRST_HALF;\r
347 Uart.bitCnt = 0;\r
348 Uart.byteCnt = 0;\r
349 Uart.parityBits = 0;\r
350 error = 0;\r
351 }\r
352 else {\r
353 Uart.highCnt = 0;\r
354 }\r
355 }\r
356 else {\r
357 if(Uart.highCnt < 8) {\r
358 Uart.highCnt++;\r
359 }\r
360 }\r
361 }\r
362\r
363 return FALSE;\r
364}\r
365\r
366//=============================================================================\r
367// ISO 14443 Type A - Manchester\r
368//=============================================================================\r
369\r
370static struct {\r
371 enum {\r
372 DEMOD_UNSYNCD,\r
373 DEMOD_START_OF_COMMUNICATION,\r
374 DEMOD_MANCHESTER_D,\r
375 DEMOD_MANCHESTER_E,\r
376 DEMOD_MANCHESTER_F,\r
377 DEMOD_ERROR_WAIT\r
378 } state;\r
379 int bitCount;\r
380 int posCount;\r
381 int syncBit;\r
382 int parityBits;\r
383 WORD shiftReg;\r
384 int buffer;\r
385 int buff;\r
386 int samples;\r
387 int len;\r
388 enum {\r
389 SUB_NONE,\r
390 SUB_FIRST_HALF,\r
391 SUB_SECOND_HALF\r
392 } sub;\r
393 BYTE *output;\r
394} Demod;\r
395\r
396static BOOL ManchesterDecoding(int v)\r
397{\r
398 int bit;\r
399 int modulation;\r
400 int error = 0;\r
401\r
402 if(!Demod.buff) {\r
403 Demod.buff = 1;\r
404 Demod.buffer = v;\r
405 return FALSE;\r
406 }\r
407 else {\r
408 bit = Demod.buffer;\r
409 Demod.buffer = v;\r
410 }\r
411\r
412 if(Demod.state==DEMOD_UNSYNCD) {\r
413 Demod.output[Demod.len] = 0xfa;\r
414 Demod.syncBit = 0;\r
415 //Demod.samples = 0;\r
416 Demod.posCount = 1; // This is the first half bit period, so after syncing handle the second part\r
417 if(bit & 0x08) { Demod.syncBit = 0x08; }\r
418 if(!Demod.syncBit) {\r
419 if(bit & 0x04) { Demod.syncBit = 0x04; }\r
420 }\r
421 else if(bit & 0x04) { Demod.syncBit = 0x04; bit <<= 4; }\r
422 if(!Demod.syncBit) {\r
423 if(bit & 0x02) { Demod.syncBit = 0x02; }\r
424 }\r
425 else if(bit & 0x02) { Demod.syncBit = 0x02; bit <<= 4; }\r
426 if(!Demod.syncBit) {\r
427 if(bit & 0x01) { Demod.syncBit = 0x01; }\r
428\r
429 if(Demod.syncBit & (Demod.buffer & 0x08)) {\r
430 Demod.syncBit = 0x08;\r
431\r
432 // The first half bitperiod is expected in next sample\r
433 Demod.posCount = 0;\r
434 Demod.output[Demod.len] = 0xfb;\r
435 }\r
436 }\r
437 else if(bit & 0x01) { Demod.syncBit = 0x01; }\r
438\r
439 if(Demod.syncBit) {\r
440 Demod.len = 0;\r
441 Demod.state = DEMOD_START_OF_COMMUNICATION;\r
442 Demod.sub = SUB_FIRST_HALF;\r
443 Demod.bitCount = 0;\r
444 Demod.shiftReg = 0;\r
445 Demod.parityBits = 0;\r
446 Demod.samples = 0;\r
447 if(Demod.posCount) {\r
448 switch(Demod.syncBit) {\r
449 case 0x08: Demod.samples = 3; break;\r
450 case 0x04: Demod.samples = 2; break;\r
451 case 0x02: Demod.samples = 1; break;\r
452 case 0x01: Demod.samples = 0; break;\r
453 }\r
454 }\r
455 error = 0;\r
456 }\r
457 }\r
458 else {\r
459 //modulation = bit & Demod.syncBit;\r
460 modulation = ((bit << 1) ^ ((Demod.buffer & 0x08) >> 3)) & Demod.syncBit;\r
461\r
462 Demod.samples += 4;\r
463\r
464 if(Demod.posCount==0) {\r
465 Demod.posCount = 1;\r
466 if(modulation) {\r
467 Demod.sub = SUB_FIRST_HALF;\r
468 }\r
469 else {\r
470 Demod.sub = SUB_NONE;\r
471 }\r
472 }\r
473 else {\r
474 Demod.posCount = 0;\r
475 if(modulation && (Demod.sub == SUB_FIRST_HALF)) {\r
476 if(Demod.state!=DEMOD_ERROR_WAIT) {\r
477 Demod.state = DEMOD_ERROR_WAIT;\r
478 Demod.output[Demod.len] = 0xaa;\r
479 error = 0x01;\r
480 }\r
481 }\r
482 else if(modulation) {\r
483 Demod.sub = SUB_SECOND_HALF;\r
484 }\r
485\r
486 switch(Demod.state) {\r
487 case DEMOD_START_OF_COMMUNICATION:\r
488 if(Demod.sub == SUB_FIRST_HALF) {\r
489 Demod.state = DEMOD_MANCHESTER_D;\r
490 }\r
491 else {\r
492 Demod.output[Demod.len] = 0xab;\r
493 Demod.state = DEMOD_ERROR_WAIT;\r
494 error = 0x02;\r
495 }\r
496 break;\r
497\r
498 case DEMOD_MANCHESTER_D:\r
499 case DEMOD_MANCHESTER_E:\r
500 if(Demod.sub == SUB_FIRST_HALF) {\r
501 Demod.bitCount++;\r
502 Demod.shiftReg = (Demod.shiftReg >> 1) ^ 0x100;\r
503 Demod.state = DEMOD_MANCHESTER_D;\r
504 }\r
505 else if(Demod.sub == SUB_SECOND_HALF) {\r
506 Demod.bitCount++;\r
507 Demod.shiftReg >>= 1;\r
508 Demod.state = DEMOD_MANCHESTER_E;\r
509 }\r
510 else {\r
511 Demod.state = DEMOD_MANCHESTER_F;\r
512 }\r
513 break;\r
514\r
515 case DEMOD_MANCHESTER_F:\r
516 // Tag response does not need to be a complete byte!\r
517 if(Demod.len > 0 || Demod.bitCount > 0) {\r
518 if(Demod.bitCount > 0) {\r
519 Demod.shiftReg >>= (9 - Demod.bitCount);\r
520 Demod.output[Demod.len] = Demod.shiftReg & 0xff;\r
521 Demod.len++;\r
522 // No parity bit, so just shift a 0\r
523 Demod.parityBits <<= 1;\r
524 }\r
525\r
526 Demod.state = DEMOD_UNSYNCD;\r
527 return TRUE;\r
528 }\r
529 else {\r
530 Demod.output[Demod.len] = 0xad;\r
531 Demod.state = DEMOD_ERROR_WAIT;\r
532 error = 0x03;\r
533 }\r
534 break;\r
535\r
536 case DEMOD_ERROR_WAIT:\r
537 Demod.state = DEMOD_UNSYNCD;\r
538 break;\r
539\r
540 default:\r
541 Demod.output[Demod.len] = 0xdd;\r
542 Demod.state = DEMOD_UNSYNCD;\r
543 break;\r
544 }\r
545\r
546 if(Demod.bitCount>=9) {\r
547 Demod.output[Demod.len] = Demod.shiftReg & 0xff;\r
548 Demod.len++;\r
549\r
550 Demod.parityBits <<= 1;\r
551 Demod.parityBits ^= ((Demod.shiftReg >> 8) & 0x01);\r
552\r
553 Demod.bitCount = 0;\r
554 Demod.shiftReg = 0;\r
555 }\r
556\r
557 /*if(error) {\r
558 Demod.output[Demod.len] = 0xBB;\r
559 Demod.len++;\r
560 Demod.output[Demod.len] = error & 0xFF;\r
561 Demod.len++;\r
562 Demod.output[Demod.len] = 0xBB;\r
563 Demod.len++;\r
564 Demod.output[Demod.len] = bit & 0xFF;\r
565 Demod.len++;\r
566 Demod.output[Demod.len] = Demod.buffer & 0xFF;\r
567 Demod.len++;\r
568 Demod.output[Demod.len] = Demod.syncBit & 0xFF;\r
569 Demod.len++;\r
570 Demod.output[Demod.len] = 0xBB;\r
571 Demod.len++;\r
572 return TRUE;\r
573 }*/\r
574\r
575 }\r
576\r
577 } // end (state != UNSYNCED)\r
578\r
579 return FALSE;\r
580}\r
581\r
582//=============================================================================\r
583// Finally, a `sniffer' for ISO 14443 Type A\r
584// Both sides of communication!\r
585//=============================================================================\r
586\r
587//-----------------------------------------------------------------------------\r
588// Record the sequence of commands sent by the reader to the tag, with\r
589// triggering so that we start recording at the point that the tag is moved\r
590// near the reader.\r
591//-----------------------------------------------------------------------------\r
592void SnoopIso14443a(void)\r
593{\r
6658905f 594// #define RECV_CMD_OFFSET 2032 // original (working as of 21/2/09) values\r
595// #define RECV_RES_OFFSET 2096 // original (working as of 21/2/09) values\r
596// #define DMA_BUFFER_OFFSET 2160 // original (working as of 21/2/09) values\r
597// #define DMA_BUFFER_SIZE 4096 // original (working as of 21/2/09) values\r
598// #define TRACE_LENGTH 2000 // original (working as of 21/2/09) values\r
599\r
600 // We won't start recording the frames that we acquire until we trigger;\r
601 // a good trigger condition to get started is probably when we see a\r
602 // response from the tag.\r
603 BOOL triggered = TRUE; // FALSE to wait first for card\r
604\r
605 // The command (reader -> tag) that we're receiving.\r
606 // The length of a received command will in most cases be no more than 18 bytes.\r
607 // So 32 should be enough!\r
608 BYTE *receivedCmd = (((BYTE *)BigBuf) + RECV_CMD_OFFSET);\r
609 // The response (tag -> reader) that we're receiving.\r
610 BYTE *receivedResponse = (((BYTE *)BigBuf) + RECV_RES_OFFSET);\r
611\r
612 // As we receive stuff, we copy it from receivedCmd or receivedResponse\r
613 // into trace, along with its length and other annotations.\r
d24438f8 614 //BYTE *trace = (BYTE *)BigBuf;\r
615 //int traceLen = 0;\r
6658905f 616\r
617 // The DMA buffer, used to stream samples from the FPGA\r
618 SBYTE *dmaBuf = ((SBYTE *)BigBuf) + DMA_BUFFER_OFFSET;\r
619 int lastRxCounter;\r
620 SBYTE *upTo;\r
621 int smpl;\r
622 int maxBehindBy = 0;\r
623\r
624 // Count of samples received so far, so that we can include timing\r
625 // information in the trace buffer.\r
626 int samples = 0;\r
627 int rsamples = 0;\r
628\r
629 memset(trace, 0x44, RECV_CMD_OFFSET);\r
630\r
631 // Set up the demodulator for tag -> reader responses.\r
632 Demod.output = receivedResponse;\r
633 Demod.len = 0;\r
634 Demod.state = DEMOD_UNSYNCD;\r
635\r
636 // And the reader -> tag commands\r
637 memset(&Uart, 0, sizeof(Uart));\r
638 Uart.output = receivedCmd;\r
639 Uart.byteCntMax = 32; // was 100 (greg)////////////////////////////////////////////////////////////////////////\r
640 Uart.state = STATE_UNSYNCD;\r
641\r
642 // And put the FPGA in the appropriate mode\r
0e25ae11 643 // Signal field is off with the appropriate LED\r
644 LED_D_OFF();\r
6658905f 645 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER);\r
646 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
647\r
648 // Setup for the DMA.\r
649 FpgaSetupSsc();\r
650 upTo = dmaBuf;\r
651 lastRxCounter = DMA_BUFFER_SIZE;\r
652 FpgaSetupSscDma((BYTE *)dmaBuf, DMA_BUFFER_SIZE);\r
653\r
654 LED_A_ON();\r
655\r
656 // And now we loop, receiving samples.\r
657 for(;;) {\r
658 WDT_HIT();\r
6949aca9 659 int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &\r
6658905f 660 (DMA_BUFFER_SIZE-1);\r
661 if(behindBy > maxBehindBy) {\r
662 maxBehindBy = behindBy;\r
663 if(behindBy > 400) {\r
664 DbpString("blew circular buffer!");\r
665 goto done;\r
666 }\r
667 }\r
668 if(behindBy < 1) continue;\r
669\r
670 smpl = upTo[0];\r
671 upTo++;\r
672 lastRxCounter -= 1;\r
673 if(upTo - dmaBuf > DMA_BUFFER_SIZE) {\r
674 upTo -= DMA_BUFFER_SIZE;\r
675 lastRxCounter += DMA_BUFFER_SIZE;\r
6949aca9 676 AT91C_BASE_PDC_SSC->PDC_RNPR = (DWORD)upTo;\r
677 AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;\r
6658905f 678 }\r
679\r
680 samples += 4;\r
681#define HANDLE_BIT_IF_BODY \\r
682 LED_C_ON(); \\r
683 if(triggered) { \\r
684 trace[traceLen++] = ((rsamples >> 0) & 0xff); \\r
685 trace[traceLen++] = ((rsamples >> 8) & 0xff); \\r
686 trace[traceLen++] = ((rsamples >> 16) & 0xff); \\r
687 trace[traceLen++] = ((rsamples >> 24) & 0xff); \\r
688 trace[traceLen++] = ((Uart.parityBits >> 0) & 0xff); \\r
689 trace[traceLen++] = ((Uart.parityBits >> 8) & 0xff); \\r
690 trace[traceLen++] = ((Uart.parityBits >> 16) & 0xff); \\r
691 trace[traceLen++] = ((Uart.parityBits >> 24) & 0xff); \\r
692 trace[traceLen++] = Uart.byteCnt; \\r
693 memcpy(trace+traceLen, receivedCmd, Uart.byteCnt); \\r
694 traceLen += Uart.byteCnt; \\r
695 if(traceLen > TRACE_LENGTH) break; \\r
696 } \\r
697 /* And ready to receive another command. */ \\r
698 Uart.state = STATE_UNSYNCD; \\r
699 /* And also reset the demod code, which might have been */ \\r
700 /* false-triggered by the commands from the reader. */ \\r
701 Demod.state = DEMOD_UNSYNCD; \\r
702 LED_B_OFF(); \\r
703\r
704 if(MillerDecoding((smpl & 0xF0) >> 4)) {\r
705 rsamples = samples - Uart.samples;\r
706 HANDLE_BIT_IF_BODY\r
707 }\r
708 if(ManchesterDecoding(smpl & 0x0F)) {\r
709 rsamples = samples - Demod.samples;\r
710 LED_B_ON();\r
711\r
712 // timestamp, as a count of samples\r
713 trace[traceLen++] = ((rsamples >> 0) & 0xff);\r
714 trace[traceLen++] = ((rsamples >> 8) & 0xff);\r
715 trace[traceLen++] = ((rsamples >> 16) & 0xff);\r
716 trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);\r
717 trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);\r
718 trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);\r
719 trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);\r
720 trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);\r
721 // length\r
722 trace[traceLen++] = Demod.len;\r
723 memcpy(trace+traceLen, receivedResponse, Demod.len);\r
724 traceLen += Demod.len;\r
725 if(traceLen > TRACE_LENGTH) break;\r
726\r
727 triggered = TRUE;\r
728\r
729 // And ready to receive another response.\r
730 memset(&Demod, 0, sizeof(Demod));\r
731 Demod.output = receivedResponse;\r
732 Demod.state = DEMOD_UNSYNCD;\r
733 LED_C_OFF();\r
734 }\r
735\r
736 if(BUTTON_PRESS()) {\r
737 DbpString("cancelled_a");\r
738 goto done;\r
739 }\r
740 }\r
741\r
742 DbpString("COMMAND FINISHED");\r
743\r
850427c8 744 Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);\r
745 Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);\r
6658905f 746\r
747done:\r
6949aca9 748 AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;\r
850427c8 749 Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);\r
750 Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);\r
6658905f 751 LED_A_OFF();\r
752 LED_B_OFF();\r
753 LED_C_OFF();\r
754 LED_D_OFF();\r
755}\r
756\r
757// Prepare communication bits to send to FPGA\r
758void Sequence(SecType seq)\r
759{\r
760 ToSendMax++;\r
761 switch(seq) {\r
762 // CARD TO READER\r
763 case SEC_D:\r
764 // Sequence D: 11110000\r
765 // modulation with subcarrier during first half\r
766 ToSend[ToSendMax] = 0xf0;\r
767 break;\r
768 case SEC_E:\r
769 // Sequence E: 00001111\r
770 // modulation with subcarrier during second half\r
771 ToSend[ToSendMax] = 0x0f;\r
772 break;\r
773 case SEC_F:\r
774 // Sequence F: 00000000\r
775 // no modulation with subcarrier\r
776 ToSend[ToSendMax] = 0x00;\r
777 break;\r
778 // READER TO CARD\r
779 case SEC_X:\r
780 // Sequence X: 00001100\r
781 // drop after half a period\r
782 ToSend[ToSendMax] = 0x0c;\r
783 break;\r
784 case SEC_Y:\r
785 default:\r
786 // Sequence Y: 00000000\r
787 // no drop\r
788 ToSend[ToSendMax] = 0x00;\r
789 break;\r
790 case SEC_Z:\r
791 // Sequence Z: 11000000\r
792 // drop at start\r
793 ToSend[ToSendMax] = 0xc0;\r
794 break;\r
795 }\r
796}\r
797\r
798//-----------------------------------------------------------------------------\r
799// Prepare tag messages\r
800//-----------------------------------------------------------------------------\r
801static void CodeIso14443aAsTag(const BYTE *cmd, int len)\r
802{\r
803 int i;\r
804 int oddparity;\r
805\r
806 ToSendReset();\r
807\r
808 // Correction bit, might be removed when not needed\r
809 ToSendStuffBit(0);\r
810 ToSendStuffBit(0);\r
811 ToSendStuffBit(0);\r
812 ToSendStuffBit(0);\r
813 ToSendStuffBit(1); // 1\r
814 ToSendStuffBit(0);\r
815 ToSendStuffBit(0);\r
816 ToSendStuffBit(0);\r
817\r
818 // Send startbit\r
819 Sequence(SEC_D);\r
820\r
821 for(i = 0; i < len; i++) {\r
822 int j;\r
823 BYTE b = cmd[i];\r
824\r
825 // Data bits\r
826 oddparity = 0x01;\r
827 for(j = 0; j < 8; j++) {\r
828 oddparity ^= (b & 1);\r
829 if(b & 1) {\r
830 Sequence(SEC_D);\r
831 } else {\r
832 Sequence(SEC_E);\r
833 }\r
834 b >>= 1;\r
835 }\r
836\r
837 // Parity bit\r
838 if(oddparity) {\r
839 Sequence(SEC_D);\r
840 } else {\r
841 Sequence(SEC_E);\r
842 }\r
843 }\r
844\r
845 // Send stopbit\r
846 Sequence(SEC_F);\r
847\r
848 // Flush the buffer in FPGA!!\r
849 for(i = 0; i < 5; i++) {\r
850 Sequence(SEC_F);\r
851 }\r
852\r
853 // Convert from last byte pos to length\r
854 ToSendMax++;\r
855\r
856 // Add a few more for slop\r
857 ToSend[ToSendMax++] = 0x00;\r
858 ToSend[ToSendMax++] = 0x00;\r
859 //ToSendMax += 2;\r
860}\r
861\r
862//-----------------------------------------------------------------------------\r
863// This is to send a NACK kind of answer, its only 3 bits, I know it should be 4\r
864//-----------------------------------------------------------------------------\r
865static void CodeStrangeAnswer()\r
866{\r
867 int i;\r
868\r
869 ToSendReset();\r
870\r
871 // Correction bit, might be removed when not needed\r
872 ToSendStuffBit(0);\r
873 ToSendStuffBit(0);\r
874 ToSendStuffBit(0);\r
875 ToSendStuffBit(0);\r
876 ToSendStuffBit(1); // 1\r
877 ToSendStuffBit(0);\r
878 ToSendStuffBit(0);\r
879 ToSendStuffBit(0);\r
880\r
881 // Send startbit\r
882 Sequence(SEC_D);\r
883\r
884 // 0\r
885 Sequence(SEC_E);\r
886\r
887 // 0\r
888 Sequence(SEC_E);\r
889\r
890 // 1\r
891 Sequence(SEC_D);\r
892\r
893 // Send stopbit\r
894 Sequence(SEC_F);\r
895\r
896 // Flush the buffer in FPGA!!\r
897 for(i = 0; i < 5; i++) {\r
898 Sequence(SEC_F);\r
899 }\r
900\r
901 // Convert from last byte pos to length\r
902 ToSendMax++;\r
903\r
904 // Add a few more for slop\r
905 ToSend[ToSendMax++] = 0x00;\r
906 ToSend[ToSendMax++] = 0x00;\r
907 //ToSendMax += 2;\r
908}\r
909\r
910//-----------------------------------------------------------------------------\r
911// Wait for commands from reader\r
912// Stop when button is pressed\r
913// Or return TRUE when command is captured\r
914//-----------------------------------------------------------------------------\r
915static BOOL GetIso14443aCommandFromReader(BYTE *received, int *len, int maxLen)\r
916{\r
917 // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen\r
918 // only, since we are receiving, not transmitting).\r
0e25ae11 919 // Signal field is off with the appropriate LED\r
920 LED_D_OFF();\r
6658905f 921 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_LISTEN);\r
922\r
923 // Now run a `software UART' on the stream of incoming samples.\r
924 Uart.output = received;\r
925 Uart.byteCntMax = maxLen;\r
926 Uart.state = STATE_UNSYNCD;\r
927\r
928 for(;;) {\r
929 WDT_HIT();\r
930\r
931 if(BUTTON_PRESS()) return FALSE;\r
932\r
6949aca9 933 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {\r
934 AT91C_BASE_SSC->SSC_THR = 0x00;\r
6658905f 935 }\r
6949aca9 936 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {\r
937 BYTE b = (BYTE)AT91C_BASE_SSC->SSC_RHR;\r
6658905f 938 if(MillerDecoding((b & 0xf0) >> 4)) {\r
939 *len = Uart.byteCnt;\r
940 return TRUE;\r
941 }\r
942 if(MillerDecoding(b & 0x0f)) {\r
943 *len = Uart.byteCnt;\r
944 return TRUE;\r
945 }\r
946 }\r
947 }\r
948}\r
949\r
950//-----------------------------------------------------------------------------\r
951// Main loop of simulated tag: receive commands from reader, decide what\r
952// response to send, and send it.\r
953//-----------------------------------------------------------------------------\r
954void SimulateIso14443aTag(int tagType, int TagUid)\r
955{\r
956 // This function contains the tag emulation\r
957\r
958 // Prepare protocol messages\r
959 // static const BYTE cmd1[] = { 0x26 };\r
960// static const BYTE response1[] = { 0x02, 0x00 }; // Says: I am Mifare 4k - original line - greg\r
961//\r
962 static const BYTE response1[] = { 0x44, 0x03 }; // Says: I am a DESFire Tag, ph33r me\r
963// static const BYTE response1[] = { 0x44, 0x00 }; // Says: I am a ULTRALITE Tag, 0wn me\r
964\r
965 // UID response\r
966 // static const BYTE cmd2[] = { 0x93, 0x20 };\r
967 //static const BYTE response2[] = { 0x9a, 0xe5, 0xe4, 0x43, 0xd8 }; // original value - greg\r
968\r
969\r
970\r
971// my desfire\r
972 static const BYTE response2[] = { 0x88, 0x04, 0x21, 0x3f, 0x4d }; // known uid - note cascade (0x88), 2nd byte (0x04) = NXP/Phillips\r
0e25ae11 973\r
974\r
6658905f 975// When reader selects us during cascade1 it will send cmd3\r
976//BYTE response3[] = { 0x04, 0x00, 0x00 }; // SAK Select (cascade1) successful response (ULTRALITE)\r
977BYTE response3[] = { 0x24, 0x00, 0x00 }; // SAK Select (cascade1) successful response (DESFire)\r
978ComputeCrc14443(CRC_14443_A, response3, 1, &response3[1], &response3[2]);\r
979\r
980// send cascade2 2nd half of UID\r
981static const BYTE response2a[] = { 0x51, 0x48, 0x1d, 0x80, 0x84 }; // uid - cascade2 - 2nd half (4 bytes) of UID+ BCCheck\r
982// NOTE : THE CRC on the above may be wrong as I have obfuscated the actual UID\r
983\r
984\r
985// When reader selects us during cascade2 it will send cmd3a\r
986//BYTE response3a[] = { 0x00, 0x00, 0x00 }; // SAK Select (cascade2) successful response (ULTRALITE)\r
987BYTE response3a[] = { 0x20, 0x00, 0x00 }; // SAK Select (cascade2) successful response (DESFire)\r
988ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);\r
0e25ae11 989\r
6658905f 990 static const BYTE response5[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce\r
991\r
992 BYTE *resp;\r
993 int respLen;\r
994\r
995 // Longest possible response will be 16 bytes + 2 CRC = 18 bytes\r
996 // This will need\r
997 // 144 data bits (18 * 8)\r
998 // 18 parity bits\r
999 // 2 Start and stop\r
1000 // 1 Correction bit (Answer in 1172 or 1236 periods, see FPGA)\r
1001 // 1 just for the case\r
1002 // ----------- +\r
1003 // 166\r
1004 //\r
1005 // 166 bytes, since every bit that needs to be send costs us a byte\r
1006 //\r
1007\r
1008\r
1009 // Respond with card type\r
1010 BYTE *resp1 = (((BYTE *)BigBuf) + 800);\r
1011 int resp1Len;\r
1012\r
1013 // Anticollision cascade1 - respond with uid\r
1014 BYTE *resp2 = (((BYTE *)BigBuf) + 970);\r
1015 int resp2Len;\r
1016\r
1017 // Anticollision cascade2 - respond with 2nd half of uid if asked\r
1018 // we're only going to be asked if we set the 1st byte of the UID (during cascade1) to 0x88\r
1019 BYTE *resp2a = (((BYTE *)BigBuf) + 1140);\r
1020 int resp2aLen;\r
1021\r
1022 // Acknowledge select - cascade 1\r
1023 BYTE *resp3 = (((BYTE *)BigBuf) + 1310);\r
1024 int resp3Len;\r
1025\r
1026 // Acknowledge select - cascade 2\r
1027 BYTE *resp3a = (((BYTE *)BigBuf) + 1480);\r
1028 int resp3aLen;\r
1029\r
1030 // Response to a read request - not implemented atm\r
1031 BYTE *resp4 = (((BYTE *)BigBuf) + 1550);\r
1032 int resp4Len;\r
1033\r
1034 // Authenticate response - nonce\r
1035 BYTE *resp5 = (((BYTE *)BigBuf) + 1720);\r
1036 int resp5Len;\r
1037\r
1038 BYTE *receivedCmd = (BYTE *)BigBuf;\r
1039 int len;\r
1040\r
1041 int i;\r
1042 int u;\r
1043 BYTE b;\r
1044\r
1045 // To control where we are in the protocol\r
1046 int order = 0;\r
1047 int lastorder;\r
1048\r
1049 // Just to allow some checks\r
1050 int happened = 0;\r
1051 int happened2 = 0;\r
1052\r
1053 int cmdsRecvd = 0;\r
1054\r
1055 BOOL fdt_indicator;\r
1056\r
1057 memset(receivedCmd, 0x44, 400);\r
1058\r
1059 // Prepare the responses of the anticollision phase\r
1060 // there will be not enough time to do this at the moment the reader sends it REQA\r
1061\r
1062 // Answer to request\r
1063 CodeIso14443aAsTag(response1, sizeof(response1));\r
1064 memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax;\r
1065\r
1066 // Send our UID (cascade 1)\r
1067 CodeIso14443aAsTag(response2, sizeof(response2));\r
1068 memcpy(resp2, ToSend, ToSendMax); resp2Len = ToSendMax;\r
1069\r
1070 // Answer to select (cascade1)\r
1071 CodeIso14443aAsTag(response3, sizeof(response3));\r
1072 memcpy(resp3, ToSend, ToSendMax); resp3Len = ToSendMax;\r
1073\r
1074 // Send the cascade 2 2nd part of the uid\r
1075 CodeIso14443aAsTag(response2a, sizeof(response2a));\r
1076 memcpy(resp2a, ToSend, ToSendMax); resp2aLen = ToSendMax;\r
1077\r
1078 // Answer to select (cascade 2)\r
1079 CodeIso14443aAsTag(response3a, sizeof(response3a));\r
1080 memcpy(resp3a, ToSend, ToSendMax); resp3aLen = ToSendMax;\r
1081\r
1082 // Strange answer is an example of rare message size (3 bits)\r
1083 CodeStrangeAnswer();\r
1084 memcpy(resp4, ToSend, ToSendMax); resp4Len = ToSendMax;\r
1085\r
1086 // Authentication answer (random nonce)\r
1087 CodeIso14443aAsTag(response5, sizeof(response5));\r
1088 memcpy(resp5, ToSend, ToSendMax); resp5Len = ToSendMax;\r
1089\r
1090 // We need to listen to the high-frequency, peak-detected path.\r
1091 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
1092 FpgaSetupSsc();\r
1093\r
1094 cmdsRecvd = 0;\r
1095\r
1096 LED_A_ON();\r
1097 for(;;) {\r
1098\r
1099 if(!GetIso14443aCommandFromReader(receivedCmd, &len, 100)) {\r
1100 DbpString("button press");\r
1101 break;\r
1102 }\r
1103 // doob - added loads of debug strings so we can see what the reader is saying to us during the sim as hi14alist is not populated\r
1104 // Okay, look at the command now.\r
1105 lastorder = order;\r
1106 i = 1; // first byte transmitted\r
1107 if(receivedCmd[0] == 0x26) {\r
1108 // Received a REQUEST\r
1109 resp = resp1; respLen = resp1Len; order = 1;\r
1110 //DbpString("Hello request from reader:");\r
1111 } else if(receivedCmd[0] == 0x52) {\r
1112 // Received a WAKEUP\r
1113 resp = resp1; respLen = resp1Len; order = 6;\r
1114// //DbpString("Wakeup request from reader:");\r
1115\r
1116 } else if(receivedCmd[1] == 0x20 && receivedCmd[0] == 0x93) { // greg - cascade 1 anti-collision\r
1117 // Received request for UID (cascade 1)\r
1118 resp = resp2; respLen = resp2Len; order = 2;\r
1119// DbpString("UID (cascade 1) request from reader:");\r
1120// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1121\r
1122\r
1123 } else if(receivedCmd[1] == 0x20 && receivedCmd[0] ==0x95) { // greg - cascade 2 anti-collision\r
1124 // Received request for UID (cascade 2)\r
1125 resp = resp2a; respLen = resp2aLen; order = 20;\r
1126// DbpString("UID (cascade 2) request from reader:");\r
1127// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1128\r
1129\r
1130 } else if(receivedCmd[1] == 0x70 && receivedCmd[0] ==0x93) { // greg - cascade 1 select\r
1131 // Received a SELECT\r
1132 resp = resp3; respLen = resp3Len; order = 3;\r
1133// DbpString("Select (cascade 1) request from reader:");\r
1134// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1135\r
1136\r
1137 } else if(receivedCmd[1] == 0x70 && receivedCmd[0] ==0x95) { // greg - cascade 2 select\r
1138 // Received a SELECT\r
1139 resp = resp3a; respLen = resp3aLen; order = 30;\r
1140// DbpString("Select (cascade 2) request from reader:");\r
1141// DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1142\r
1143\r
1144 } else if(receivedCmd[0] == 0x30) {\r
1145 // Received a READ\r
1146 resp = resp4; respLen = resp4Len; order = 4; // Do nothing\r
850427c8 1147 Dbprintf("Read request from reader: %x %x %x",\r
1148 receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
6658905f 1149\r
1150\r
1151 } else if(receivedCmd[0] == 0x50) {\r
1152 // Received a HALT\r
1153 resp = resp1; respLen = 0; order = 5; // Do nothing\r
1154 DbpString("Reader requested we HALT!:");\r
1155\r
1156 } else if(receivedCmd[0] == 0x60) {\r
1157 // Received an authentication request\r
1158 resp = resp5; respLen = resp5Len; order = 7;\r
850427c8 1159 Dbprintf("Authenticate request from reader: %x %x %x",\r
1160 receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
6658905f 1161\r
1162 } else if(receivedCmd[0] == 0xE0) {\r
1163 // Received a RATS request\r
1164 resp = resp1; respLen = 0;order = 70;\r
850427c8 1165 Dbprintf("RATS request from reader: %x %x %x",\r
1166 receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
6658905f 1167 } else {\r
1168 // Never seen this command before\r
850427c8 1169 Dbprintf("Unknown command received from reader: %x %x %x %x %x %x %x %x %x",\r
1170 receivedCmd[0], receivedCmd[1], receivedCmd[2],\r
1171 receivedCmd[3], receivedCmd[3], receivedCmd[4],\r
1172 receivedCmd[5], receivedCmd[6], receivedCmd[7]);\r
6658905f 1173 // Do not respond\r
1174 resp = resp1; respLen = 0; order = 0;\r
1175 }\r
1176\r
1177 // Count number of wakeups received after a halt\r
1178 if(order == 6 && lastorder == 5) { happened++; }\r
1179\r
1180 // Count number of other messages after a halt\r
1181 if(order != 6 && lastorder == 5) { happened2++; }\r
1182\r
1183 // Look at last parity bit to determine timing of answer\r
1184 if((Uart.parityBits & 0x01) || receivedCmd[0] == 0x52) {\r
1185 // 1236, so correction bit needed\r
1186 i = 0;\r
1187 }\r
1188\r
1189 memset(receivedCmd, 0x44, 32);\r
1190\r
1191 if(cmdsRecvd > 999) {\r
1192 DbpString("1000 commands later...");\r
1193 break;\r
1194 }\r
1195 else {\r
1196 cmdsRecvd++;\r
1197 }\r
1198\r
1199 if(respLen <= 0) continue;\r
1200\r
1201 // Modulate Manchester\r
1202 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);\r
6949aca9 1203 AT91C_BASE_SSC->SSC_THR = 0x00;\r
6658905f 1204 FpgaSetupSsc();\r
1205\r
1206 // ### Transmit the response ###\r
1207 u = 0;\r
1208 b = 0x00;\r
1209 fdt_indicator = FALSE;\r
1210 for(;;) {\r
6949aca9 1211 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {\r
1212 volatile BYTE b = (BYTE)AT91C_BASE_SSC->SSC_RHR;\r
6658905f 1213 (void)b;\r
1214 }\r
6949aca9 1215 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {\r
6658905f 1216 if(i > respLen) {\r
1217 b = 0x00;\r
1218 u++;\r
1219 } else {\r
1220 b = resp[i];\r
1221 i++;\r
1222 }\r
6949aca9 1223 AT91C_BASE_SSC->SSC_THR = b;\r
6658905f 1224\r
1225 if(u > 4) {\r
1226 break;\r
1227 }\r
1228 }\r
1229 if(BUTTON_PRESS()) {\r
1230 break;\r
1231 }\r
1232 }\r
1233\r
1234 }\r
1235\r
850427c8 1236 Dbprintf("%x %x %x", happened, happened2, cmdsRecvd);\r
6658905f 1237 LED_A_OFF();\r
1238}\r
1239\r
1240//-----------------------------------------------------------------------------\r
1241// Transmit the command (to the tag) that was placed in ToSend[].\r
1242//-----------------------------------------------------------------------------\r
1243static void TransmitFor14443a(const BYTE *cmd, int len, int *samples, int *wait)\r
1244{\r
84c02e97 1245 int c;\r
1246 \r
1247 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
1248 \r
1249 if (wait)\r
1250 if(*wait < 10)\r
1251 *wait = 10;\r
1252 \r
1253 for(c = 0; c < *wait;) {\r
1254 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {\r
1255 AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing!\r
1256 c++;\r
6658905f 1257 }\r
84c02e97 1258 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {\r
1259 volatile DWORD r = AT91C_BASE_SSC->SSC_RHR;\r
1260 (void)r;\r
1261 }\r
1262 WDT_HIT();\r
1263 }\r
1264 \r
1265 c = 0;\r
1266 for(;;) {\r
1267 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {\r
1268 AT91C_BASE_SSC->SSC_THR = cmd[c];\r
1269 c++;\r
1270 if(c >= len) {\r
1271 break;\r
1272 }\r
6658905f 1273 }\r
84c02e97 1274 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {\r
1275 volatile DWORD r = AT91C_BASE_SSC->SSC_RHR;\r
1276 (void)r;\r
1277 }\r
1278 WDT_HIT();\r
1279 }\r
1280 if (samples) *samples = (c + *wait) << 3;\r
6658905f 1281}\r
1282\r
1283//-----------------------------------------------------------------------------\r
1284// To generate an arbitrary stream from reader\r
1285//\r
1286//-----------------------------------------------------------------------------\r
1287void ArbitraryFromReader(const BYTE *cmd, int parity, int len)\r
1288{\r
1289 int i;\r
1290 int j;\r
1291 int last;\r
1292 BYTE b;\r
1293\r
1294 ToSendReset();\r
1295\r
1296 // Start of Communication (Seq. Z)\r
1297 Sequence(SEC_Z);\r
1298 last = 0;\r
1299\r
1300 for(i = 0; i < len; i++) {\r
1301 // Data bits\r
1302 b = cmd[i];\r
1303 for(j = 0; j < 8; j++) {\r
1304 if(b & 1) {\r
1305 // Sequence X\r
1306 Sequence(SEC_X);\r
1307 last = 1;\r
1308 } else {\r
1309 if(last == 0) {\r
1310 // Sequence Z\r
1311 Sequence(SEC_Z);\r
1312 }\r
1313 else {\r
1314 // Sequence Y\r
1315 Sequence(SEC_Y);\r
1316 last = 0;\r
1317 }\r
1318 }\r
1319 b >>= 1;\r
1320\r
1321 }\r
1322\r
1323 // Predefined parity bit, the flipper flips when needed, because of flips in byte sent\r
1324 if(((parity >> (len - i - 1)) & 1)) {\r
1325 // Sequence X\r
1326 Sequence(SEC_X);\r
1327 last = 1;\r
1328 } else {\r
1329 if(last == 0) {\r
1330 // Sequence Z\r
1331 Sequence(SEC_Z);\r
1332 }\r
1333 else {\r
1334 // Sequence Y\r
1335 Sequence(SEC_Y);\r
1336 last = 0;\r
1337 }\r
1338 }\r
1339 }\r
1340\r
1341 // End of Communication\r
1342 if(last == 0) {\r
1343 // Sequence Z\r
1344 Sequence(SEC_Z);\r
1345 }\r
1346 else {\r
1347 // Sequence Y\r
1348 Sequence(SEC_Y);\r
1349 last = 0;\r
1350 }\r
1351 // Sequence Y\r
1352 Sequence(SEC_Y);\r
1353\r
1354 // Just to be sure!\r
1355 Sequence(SEC_Y);\r
1356 Sequence(SEC_Y);\r
1357 Sequence(SEC_Y);\r
1358\r
1359 // Convert from last character reference to length\r
1360 ToSendMax++;\r
1361}\r
1362\r
1363//-----------------------------------------------------------------------------\r
1364// Code a 7-bit command without parity bit\r
1365// This is especially for 0x26 and 0x52 (REQA and WUPA)\r
1366//-----------------------------------------------------------------------------\r
84c02e97 1367void ShortFrameFromReader(const BYTE bt)\r
6658905f 1368{\r
1369 int j;\r
1370 int last;\r
84c02e97 1371 BYTE b;\r
6658905f 1372\r
1373 ToSendReset();\r
1374\r
1375 // Start of Communication (Seq. Z)\r
1376 Sequence(SEC_Z);\r
1377 last = 0;\r
1378\r
84c02e97 1379 b = bt;\r
6658905f 1380 for(j = 0; j < 7; j++) {\r
1381 if(b & 1) {\r
1382 // Sequence X\r
1383 Sequence(SEC_X);\r
1384 last = 1;\r
1385 } else {\r
1386 if(last == 0) {\r
1387 // Sequence Z\r
1388 Sequence(SEC_Z);\r
1389 }\r
1390 else {\r
1391 // Sequence Y\r
1392 Sequence(SEC_Y);\r
1393 last = 0;\r
1394 }\r
1395 }\r
1396 b >>= 1;\r
1397 }\r
1398\r
1399 // End of Communication\r
1400 if(last == 0) {\r
1401 // Sequence Z\r
1402 Sequence(SEC_Z);\r
1403 }\r
1404 else {\r
1405 // Sequence Y\r
1406 Sequence(SEC_Y);\r
1407 last = 0;\r
1408 }\r
1409 // Sequence Y\r
1410 Sequence(SEC_Y);\r
1411\r
1412 // Just to be sure!\r
1413 Sequence(SEC_Y);\r
1414 Sequence(SEC_Y);\r
1415 Sequence(SEC_Y);\r
1416\r
1417 // Convert from last character reference to length\r
1418 ToSendMax++;\r
1419}\r
1420\r
1421//-----------------------------------------------------------------------------\r
1422// Prepare reader command to send to FPGA\r
84c02e97 1423// \r
6658905f 1424//-----------------------------------------------------------------------------\r
84c02e97 1425void CodeIso14443aAsReaderPar(const BYTE * cmd, int len, DWORD dwParity)\r
6658905f 1426{\r
84c02e97 1427 int i, j;\r
1428 int last;\r
1429 BYTE b;\r
1430 \r
1431 ToSendReset();\r
1432 \r
1433 // Start of Communication (Seq. Z)\r
1434 Sequence(SEC_Z);\r
1435 last = 0;\r
1436 \r
1437 // Generate send structure for the data bits\r
1438 for (i = 0; i < len; i++) {\r
1439 // Get the current byte to send\r
1440 b = cmd[i];\r
1441 \r
1442 for (j = 0; j < 8; j++) {\r
1443 if (b & 1) {\r
1444 // Sequence X\r
1445 Sequence(SEC_X);\r
1446 last = 1;\r
1447 } else {\r
1448 if (last == 0) {\r
1449 // Sequence Z\r
1450 Sequence(SEC_Z);\r
1451 } else {\r
1452 // Sequence Y\r
1453 Sequence(SEC_Y);\r
1454 last = 0;\r
6658905f 1455 }\r
84c02e97 1456 }\r
1457 b >>= 1;\r
6658905f 1458 }\r
84c02e97 1459 \r
1460 // Get the parity bit\r
1461 if ((dwParity >> i) & 0x01) {\r
1462 // Sequence X\r
1463 Sequence(SEC_X);\r
1464 last = 1;\r
1465 } else {\r
1466 if (last == 0) {\r
1467 // Sequence Z\r
1468 Sequence(SEC_Z);\r
1469 } else {\r
1470 // Sequence Y\r
1471 Sequence(SEC_Y);\r
1472 last = 0;\r
1473 }\r
1474 }\r
1475 }\r
1476 \r
1477 // End of Communication\r
1478 if (last == 0) {\r
1479 // Sequence Z\r
1480 Sequence(SEC_Z);\r
1481 } else {\r
1482 // Sequence Y\r
1483 Sequence(SEC_Y);\r
1484 last = 0;\r
1485 }\r
1486 // Sequence Y\r
1487 Sequence(SEC_Y);\r
1488 \r
1489 // Just to be sure!\r
1490 Sequence(SEC_Y);\r
1491 Sequence(SEC_Y);\r
1492 Sequence(SEC_Y);\r
1493 \r
1494 // Convert from last character reference to length\r
1495 ToSendMax++;\r
6658905f 1496}\r
1497\r
6658905f 1498//-----------------------------------------------------------------------------\r
1499// Wait a certain time for tag response\r
1500// If a response is captured return TRUE\r
1501// If it takes to long return FALSE\r
1502//-----------------------------------------------------------------------------\r
1503static BOOL GetIso14443aAnswerFromTag(BYTE *receivedResponse, int maxLen, int *samples, int *elapsed) //BYTE *buffer\r
1504{\r
1505 // buffer needs to be 512 bytes\r
1506 int c;\r
1507\r
0e25ae11 1508 // Set FPGA mode to "reader listen mode", no modulation (listen\r
6658905f 1509 // only, since we are receiving, not transmitting).\r
0e25ae11 1510 // Signal field is on with the appropriate LED\r
1511 LED_D_ON();\r
6658905f 1512 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);\r
1513\r
1514 // Now get the answer from the card\r
1515 Demod.output = receivedResponse;\r
1516 Demod.len = 0;\r
1517 Demod.state = DEMOD_UNSYNCD;\r
1518\r
1519 BYTE b;\r
84c02e97 1520 if (elapsed) *elapsed = 0;\r
6658905f 1521\r
1522 c = 0;\r
1523 for(;;) {\r
1524 WDT_HIT();\r
1525\r
6949aca9 1526 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {\r
1527 AT91C_BASE_SSC->SSC_THR = 0x00; // To make use of exact timing of next command from reader!!\r
84c02e97 1528 if (elapsed) (*elapsed)++;\r
6658905f 1529 }\r
6949aca9 1530 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {\r
6658905f 1531 if(c < 512) { c++; } else { return FALSE; }\r
6949aca9 1532 b = (BYTE)AT91C_BASE_SSC->SSC_RHR;\r
6658905f 1533 if(ManchesterDecoding((b & 0xf0) >> 4)) {\r
1534 *samples = ((c - 1) << 3) + 4;\r
1535 return TRUE;\r
1536 }\r
1537 if(ManchesterDecoding(b & 0x0f)) {\r
1538 *samples = c << 3;\r
1539 return TRUE;\r
1540 }\r
1541 }\r
1542 }\r
1543}\r
1544\r
84c02e97 1545void ReaderTransmitShort(const BYTE* bt)\r
1546{\r
1547 int wait = 0;\r
1548 int samples = 0;\r
1549\r
1550 ShortFrameFromReader(*bt);\r
1551 \r
1552 // Select the card\r
1553 TransmitFor14443a(ToSend, ToSendMax, &samples, &wait); \r
1554 \r
1555 // Store reader command in buffer\r
32cfae43 1556 if (tracing) LogTrace(bt,1,0,GetParity(bt,1),TRUE);\r
84c02e97 1557}\r
d24438f8 1558\r
84c02e97 1559void ReaderTransmitPar(BYTE* frame, int len, DWORD par)\r
1560{\r
1561 int wait = 0;\r
1562 int samples = 0;\r
1563 \r
1564 // This is tied to other size changes\r
1565 // BYTE* frame_addr = ((BYTE*)BigBuf) + 2024; \r
84c02e97 1566 CodeIso14443aAsReaderPar(frame,len,par);\r
1567 \r
1568 // Select the card\r
1569 TransmitFor14443a(ToSend, ToSendMax, &samples, &wait); \r
1570 \r
1571 // Store reader command in buffer\r
32cfae43 1572 if (tracing) LogTrace(frame,len,0,par,TRUE);\r
84c02e97 1573}\r
1574\r
1575\r
1576void ReaderTransmit(BYTE* frame, int len)\r
1577{\r
1578 // Generate parity and redirect\r
1579 ReaderTransmitPar(frame,len,GetParity(frame,len));\r
1580}\r
1581\r
1582BOOL ReaderReceive(BYTE* receivedAnswer)\r
1583{\r
1584 int samples = 0;\r
1585 if (!GetIso14443aAnswerFromTag(receivedAnswer,100,&samples,0)) return FALSE;\r
32cfae43 1586 if (tracing) LogTrace(receivedAnswer,Demod.len,samples,Demod.parityBits,FALSE);\r
84c02e97 1587 return TRUE;\r
1588}\r
d24438f8 1589\r
6658905f 1590//-----------------------------------------------------------------------------\r
1591// Read an ISO 14443a tag. Send out commands and store answers.\r
1592//\r
1593//-----------------------------------------------------------------------------\r
1594void ReaderIso14443a(DWORD parameter)\r
1595{\r
1596 // Anticollision\r
84c02e97 1597 BYTE wupa[] = { 0x52 };\r
1598 BYTE sel_all[] = { 0x93,0x20 };\r
1599 BYTE sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };\r
1600 BYTE sel_all_c2[] = { 0x95,0x20 };\r
1601 BYTE sel_uid_c2[] = { 0x95,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };\r
6658905f 1602\r
093cbaf6 1603 // Mifare AUTH\r
84c02e97 1604 BYTE mf_auth[] = { 0x60,0x00,0xf5,0x7b };\r
1605// BYTE mf_nr_ar[] = { 0x00,0x00,0x00,0x00 };\r
1606 \r
1607 BYTE* receivedAnswer = (((BYTE *)BigBuf) + 3560); // was 3560 - tied to other size changes\r
d24438f8 1608 traceLen = 0;\r
6658905f 1609\r
6658905f 1610 // Setup SSC\r
1611 FpgaSetupSsc();\r
1612\r
1613 // Start from off (no field generated)\r
84c02e97 1614 // Signal field is off with the appropriate LED\r
1615 LED_D_OFF();\r
1616 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1617 SpinDelay(200);\r
6658905f 1618\r
84c02e97 1619 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
1620 FpgaSetupSsc();\r
6658905f 1621\r
1622 // Now give it time to spin up.\r
84c02e97 1623 // Signal field is on with the appropriate LED\r
1624 LED_D_ON();\r
1625 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
6658905f 1626 SpinDelay(200);\r
1627\r
1628 LED_A_ON();\r
1629 LED_B_OFF();\r
1630 LED_C_OFF();\r
6658905f 1631\r
84c02e97 1632 while(traceLen < TRACE_LENGTH)\r
1633 {\r
1634 // Broadcast for a card, WUPA (0x52) will force response from all cards in the field\r
1635 ReaderTransmitShort(wupa);\r
d24438f8 1636 \r
1637 // Test if the action was cancelled\r
1638 if(BUTTON_PRESS()) {\r
1639 break;\r
1640 }\r
1641 \r
84c02e97 1642 // Receive the ATQA\r
1643 if (!ReaderReceive(receivedAnswer)) continue;\r
6658905f 1644\r
84c02e97 1645 // Transmit SELECT_ALL\r
1646 ReaderTransmit(sel_all,sizeof(sel_all));\r
6658905f 1647\r
84c02e97 1648 // Receive the UID\r
1649 if (!ReaderReceive(receivedAnswer)) continue;\r
d24438f8 1650 \r
6658905f 1651 // Construct SELECT UID command\r
1652 // First copy the 5 bytes (Mifare Classic) after the 93 70\r
84c02e97 1653 memcpy(sel_uid+2,receivedAnswer,5);\r
6658905f 1654 // Secondly compute the two CRC bytes at the end\r
84c02e97 1655 AppendCrc14443a(sel_uid,7);\r
6658905f 1656\r
84c02e97 1657 // Transmit SELECT_UID\r
1658 ReaderTransmit(sel_uid,sizeof(sel_uid));\r
1659 \r
1660 // Receive the SAK\r
1661 if (!ReaderReceive(receivedAnswer)) continue;\r
d24438f8 1662\r
1663 // OK we have selected at least at cascade 1, lets see if first byte of UID was 0x88 in\r
1664 // which case we need to make a cascade 2 request and select - this is a long UID\r
84c02e97 1665 // When the UID is not complete, the 3nd bit (from the right) is set in the SAK. \r
1666 if (receivedAnswer[0] &= 0x04)\r
6658905f 1667 {\r
84c02e97 1668 // Transmit SELECT_ALL\r
1669 ReaderTransmit(sel_all_c2,sizeof(sel_all_c2));\r
1670 \r
1671 // Receive the UID\r
1672 if (!ReaderReceive(receivedAnswer)) continue;\r
1673 \r
1674 // Construct SELECT UID command\r
1675 memcpy(sel_uid_c2+2,receivedAnswer,5);\r
d24438f8 1676 // Secondly compute the two CRC bytes at the end\r
84c02e97 1677 AppendCrc14443a(sel_uid_c2,7);\r
d24438f8 1678 \r
84c02e97 1679 // Transmit SELECT_UID\r
1680 ReaderTransmit(sel_uid_c2,sizeof(sel_uid_c2));\r
d24438f8 1681 \r
84c02e97 1682 // Receive the SAK\r
1683 if (!ReaderReceive(receivedAnswer)) continue;\r
0e25ae11 1684 }\r
6658905f 1685\r
84c02e97 1686 // Transmit MIFARE_CLASSIC_AUTH\r
1687 ReaderTransmit(mf_auth,sizeof(mf_auth));\r
d24438f8 1688\r
84c02e97 1689 // Receive the (16 bit) "random" nonce\r
1690 if (!ReaderReceive(receivedAnswer)) continue;\r
6658905f 1691 }\r
1692\r
d24438f8 1693 // Thats it...\r
5435eb0c 1694 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
093cbaf6 1695 LEDsoff();\r
850427c8 1696 Dbprintf("%x %x %x", rsamples, 0xCC, 0xCC);\r
6658905f 1697 DbpString("ready..");\r
1698}\r
32cfae43 1699\r
1700//-----------------------------------------------------------------------------\r
1701// Read an ISO 14443a tag. Send out commands and store answers.\r
1702//\r
1703//-----------------------------------------------------------------------------\r
1704void ReaderMifare(DWORD parameter)\r
1705{\r
1706 \r
1707 // Anticollision\r
1708 BYTE wupa[] = { 0x52 };\r
1709 BYTE sel_all[] = { 0x93,0x20 };\r
1710 BYTE sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };\r
1711 \r
1712 // Mifare AUTH\r
1713 BYTE mf_auth[] = { 0x60,0x00,0xf5,0x7b };\r
1714 BYTE mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };\r
1715 \r
1716 BYTE* receivedAnswer = (((BYTE *)BigBuf) + 3560); // was 3560 - tied to other size changes\r
1717 traceLen = 0;\r
1718 tracing = false;\r
1719 \r
1720 // Setup SSC\r
1721 FpgaSetupSsc();\r
1722 \r
1723 // Start from off (no field generated)\r
1724 // Signal field is off with the appropriate LED\r
1725 LED_D_OFF();\r
1726 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1727 SpinDelay(200);\r
1728 \r
1729 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
1730 FpgaSetupSsc();\r
1731 \r
1732 // Now give it time to spin up.\r
1733 // Signal field is on with the appropriate LED\r
1734 LED_D_ON();\r
1735 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
1736 SpinDelay(200);\r
1737 \r
1738 LED_A_ON();\r
1739 LED_B_OFF();\r
1740 LED_C_OFF();\r
1741 \r
1742 // Broadcast for a card, WUPA (0x52) will force response from all cards in the field\r
1743 ReaderTransmitShort(wupa);\r
1744 // Receive the ATQA\r
1745 ReaderReceive(receivedAnswer);\r
1746 // Transmit SELECT_ALL\r
1747 ReaderTransmit(sel_all,sizeof(sel_all));\r
1748 // Receive the UID\r
1749 ReaderReceive(receivedAnswer);\r
1750 // Construct SELECT UID command\r
1751 // First copy the 5 bytes (Mifare Classic) after the 93 70\r
1752 memcpy(sel_uid+2,receivedAnswer,5);\r
1753 // Secondly compute the two CRC bytes at the end\r
1754 AppendCrc14443a(sel_uid,7);\r
1755 \r
1756 byte_t nt_diff = 0;\r
1757 LED_A_OFF();\r
1758 byte_t par = 0;\r
1759 byte_t par_mask = 0xff;\r
1760 byte_t par_low = 0;\r
1761 BOOL led_on = TRUE;\r
1762 \r
1763 tracing = FALSE;\r
1764 byte_t nt[4];\r
1765 byte_t nt_attacked[4];\r
1766 byte_t par_list[8];\r
1767 byte_t ks_list[8];\r
1768 num_to_bytes(parameter,4,nt_attacked);\r
1769\r
1770 while(TRUE)\r
1771 {\r
1772 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1773 SpinDelay(200);\r
1774 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
1775 \r
1776 // Broadcast for a card, WUPA (0x52) will force response from all cards in the field\r
1777 ReaderTransmitShort(wupa);\r
1778 \r
1779 // Test if the action was cancelled\r
1780 if(BUTTON_PRESS()) {\r
1781 break;\r
1782 }\r
1783 \r
1784 // Receive the ATQA\r
1785 if (!ReaderReceive(receivedAnswer)) continue;\r
1786 \r
1787 // Transmit SELECT_ALL\r
1788 ReaderTransmit(sel_all,sizeof(sel_all));\r
1789 \r
1790 // Receive the UID\r
1791 if (!ReaderReceive(receivedAnswer)) continue;\r
1792 \r
1793 // Transmit SELECT_UID\r
1794 ReaderTransmit(sel_uid,sizeof(sel_uid));\r
1795 \r
1796 // Receive the SAK\r
1797 if (!ReaderReceive(receivedAnswer)) continue;\r
1798 \r
1799 // Transmit MIFARE_CLASSIC_AUTH\r
1800 ReaderTransmit(mf_auth,sizeof(mf_auth));\r
1801 \r
1802 // Receive the (16 bit) "random" nonce\r
1803 if (!ReaderReceive(receivedAnswer)) continue;\r
1804 memcpy(nt,receivedAnswer,4);\r
1805\r
1806 // Transmit reader nonce and reader answer\r
1807 ReaderTransmitPar(mf_nr_ar,sizeof(mf_nr_ar),par);\r
1808 \r
1809 // Receive 4 bit answer\r
1810 if (ReaderReceive(receivedAnswer))\r
1811 {\r
1812 if (nt_diff == 0) \r
1813 {\r
1814 LED_A_ON();\r
1815 memcpy(nt_attacked,nt,4);\r
1816 par_mask = 0xf8;\r
1817 par_low = par & 0x07;\r
1818 }\r
1819\r
1820 if (memcmp(nt,nt_attacked,4) != 0) continue;\r
1821\r
1822 led_on = !led_on;\r
1823 if(led_on) LED_B_ON(); else LED_B_OFF();\r
1824 par_list[nt_diff] = par;\r
1825 ks_list[nt_diff] = receivedAnswer[0]^0x05;\r
1826 \r
1827 // Test if the information is complete\r
1828 if (nt_diff == 0x07) break;\r
1829 \r
1830 nt_diff = (nt_diff+1) & 0x07;\r
1831 mf_nr_ar[3] = nt_diff << 5;\r
1832 par = par_low;\r
1833 } else {\r
1834 if (nt_diff == 0)\r
1835 {\r
1836 par++;\r
1837 } else {\r
1838 par = (((par>>3)+1) << 3) | par_low;\r
1839 }\r
1840 }\r
1841 }\r
1842 \r
1843 LogTraceInfo(sel_uid+2,4);\r
1844 LogTraceInfo(nt,4);\r
1845 LogTraceInfo(par_list,8);\r
1846 LogTraceInfo(ks_list,8);\r
1847 \r
1848 // Thats it...\r
1849 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1850 LEDsoff();\r
1851 tracing = TRUE;\r
1852}\r
Impressum, Datenschutz