]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/iso14443a.c
create Dbprintf convenience function
[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
30f2a7d3 8#include "../common/iso14443_crc.c"\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
744 DbpIntegers(maxBehindBy, Uart.state, Uart.byteCnt);\r
745 DbpIntegers(Uart.byteCntMax, traceLen, (int)Uart.output[0]);\r
746\r
747done:\r
6949aca9 748 AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;\r
6658905f 749 DbpIntegers(maxBehindBy, Uart.state, Uart.byteCnt);\r
750 DbpIntegers(Uart.byteCntMax, traceLen, (int)Uart.output[0]);\r
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
1147 DbpString("Read request from reader:");\r
1148 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
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
1159 DbpString("Authenticate request from reader:");\r
1160 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1161\r
1162 } else if(receivedCmd[0] == 0xE0) {\r
1163 // Received a RATS request\r
1164 resp = resp1; respLen = 0;order = 70;\r
1165 DbpString("RATS request from reader:");\r
1166 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1167 } else {\r
1168 // Never seen this command before\r
1169 DbpString("Unknown command received from reader:");\r
1170 DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
1171 DbpIntegers(receivedCmd[3], receivedCmd[4], receivedCmd[5]);\r
1172 DbpIntegers(receivedCmd[6], receivedCmd[7], receivedCmd[8]);\r
1173\r
1174 // Do not respond\r
1175 resp = resp1; respLen = 0; order = 0;\r
1176 }\r
1177\r
1178 // Count number of wakeups received after a halt\r
1179 if(order == 6 && lastorder == 5) { happened++; }\r
1180\r
1181 // Count number of other messages after a halt\r
1182 if(order != 6 && lastorder == 5) { happened2++; }\r
1183\r
1184 // Look at last parity bit to determine timing of answer\r
1185 if((Uart.parityBits & 0x01) || receivedCmd[0] == 0x52) {\r
1186 // 1236, so correction bit needed\r
1187 i = 0;\r
1188 }\r
1189\r
1190 memset(receivedCmd, 0x44, 32);\r
1191\r
1192 if(cmdsRecvd > 999) {\r
1193 DbpString("1000 commands later...");\r
1194 break;\r
1195 }\r
1196 else {\r
1197 cmdsRecvd++;\r
1198 }\r
1199\r
1200 if(respLen <= 0) continue;\r
1201\r
1202 // Modulate Manchester\r
1203 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);\r
6949aca9 1204 AT91C_BASE_SSC->SSC_THR = 0x00;\r
6658905f 1205 FpgaSetupSsc();\r
1206\r
1207 // ### Transmit the response ###\r
1208 u = 0;\r
1209 b = 0x00;\r
1210 fdt_indicator = FALSE;\r
1211 for(;;) {\r
6949aca9 1212 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {\r
1213 volatile BYTE b = (BYTE)AT91C_BASE_SSC->SSC_RHR;\r
6658905f 1214 (void)b;\r
1215 }\r
6949aca9 1216 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {\r
6658905f 1217 if(i > respLen) {\r
1218 b = 0x00;\r
1219 u++;\r
1220 } else {\r
1221 b = resp[i];\r
1222 i++;\r
1223 }\r
6949aca9 1224 AT91C_BASE_SSC->SSC_THR = b;\r
6658905f 1225\r
1226 if(u > 4) {\r
1227 break;\r
1228 }\r
1229 }\r
1230 if(BUTTON_PRESS()) {\r
1231 break;\r
1232 }\r
1233 }\r
1234\r
1235 }\r
1236\r
1237 DbpIntegers(happened, happened2, cmdsRecvd);\r
1238 LED_A_OFF();\r
1239}\r
1240\r
1241//-----------------------------------------------------------------------------\r
1242// Transmit the command (to the tag) that was placed in ToSend[].\r
1243//-----------------------------------------------------------------------------\r
1244static void TransmitFor14443a(const BYTE *cmd, int len, int *samples, int *wait)\r
1245{\r
84c02e97 1246 int c;\r
1247 \r
1248 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
1249 \r
1250 if (wait)\r
1251 if(*wait < 10)\r
1252 *wait = 10;\r
1253 \r
1254 for(c = 0; c < *wait;) {\r
1255 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {\r
1256 AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing!\r
1257 c++;\r
6658905f 1258 }\r
84c02e97 1259 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {\r
1260 volatile DWORD r = AT91C_BASE_SSC->SSC_RHR;\r
1261 (void)r;\r
1262 }\r
1263 WDT_HIT();\r
1264 }\r
1265 \r
1266 c = 0;\r
1267 for(;;) {\r
1268 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {\r
1269 AT91C_BASE_SSC->SSC_THR = cmd[c];\r
1270 c++;\r
1271 if(c >= len) {\r
1272 break;\r
1273 }\r
6658905f 1274 }\r
84c02e97 1275 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {\r
1276 volatile DWORD r = AT91C_BASE_SSC->SSC_RHR;\r
1277 (void)r;\r
1278 }\r
1279 WDT_HIT();\r
1280 }\r
1281 if (samples) *samples = (c + *wait) << 3;\r
6658905f 1282}\r
1283\r
1284//-----------------------------------------------------------------------------\r
1285// To generate an arbitrary stream from reader\r
1286//\r
1287//-----------------------------------------------------------------------------\r
1288void ArbitraryFromReader(const BYTE *cmd, int parity, int len)\r
1289{\r
1290 int i;\r
1291 int j;\r
1292 int last;\r
1293 BYTE b;\r
1294\r
1295 ToSendReset();\r
1296\r
1297 // Start of Communication (Seq. Z)\r
1298 Sequence(SEC_Z);\r
1299 last = 0;\r
1300\r
1301 for(i = 0; i < len; i++) {\r
1302 // Data bits\r
1303 b = cmd[i];\r
1304 for(j = 0; j < 8; j++) {\r
1305 if(b & 1) {\r
1306 // Sequence X\r
1307 Sequence(SEC_X);\r
1308 last = 1;\r
1309 } else {\r
1310 if(last == 0) {\r
1311 // Sequence Z\r
1312 Sequence(SEC_Z);\r
1313 }\r
1314 else {\r
1315 // Sequence Y\r
1316 Sequence(SEC_Y);\r
1317 last = 0;\r
1318 }\r
1319 }\r
1320 b >>= 1;\r
1321\r
1322 }\r
1323\r
1324 // Predefined parity bit, the flipper flips when needed, because of flips in byte sent\r
1325 if(((parity >> (len - i - 1)) & 1)) {\r
1326 // Sequence X\r
1327 Sequence(SEC_X);\r
1328 last = 1;\r
1329 } else {\r
1330 if(last == 0) {\r
1331 // Sequence Z\r
1332 Sequence(SEC_Z);\r
1333 }\r
1334 else {\r
1335 // Sequence Y\r
1336 Sequence(SEC_Y);\r
1337 last = 0;\r
1338 }\r
1339 }\r
1340 }\r
1341\r
1342 // End of Communication\r
1343 if(last == 0) {\r
1344 // Sequence Z\r
1345 Sequence(SEC_Z);\r
1346 }\r
1347 else {\r
1348 // Sequence Y\r
1349 Sequence(SEC_Y);\r
1350 last = 0;\r
1351 }\r
1352 // Sequence Y\r
1353 Sequence(SEC_Y);\r
1354\r
1355 // Just to be sure!\r
1356 Sequence(SEC_Y);\r
1357 Sequence(SEC_Y);\r
1358 Sequence(SEC_Y);\r
1359\r
1360 // Convert from last character reference to length\r
1361 ToSendMax++;\r
1362}\r
1363\r
1364//-----------------------------------------------------------------------------\r
1365// Code a 7-bit command without parity bit\r
1366// This is especially for 0x26 and 0x52 (REQA and WUPA)\r
1367//-----------------------------------------------------------------------------\r
84c02e97 1368void ShortFrameFromReader(const BYTE bt)\r
6658905f 1369{\r
1370 int j;\r
1371 int last;\r
84c02e97 1372 BYTE b;\r
6658905f 1373\r
1374 ToSendReset();\r
1375\r
1376 // Start of Communication (Seq. Z)\r
1377 Sequence(SEC_Z);\r
1378 last = 0;\r
1379\r
84c02e97 1380 b = bt;\r
6658905f 1381 for(j = 0; j < 7; j++) {\r
1382 if(b & 1) {\r
1383 // Sequence X\r
1384 Sequence(SEC_X);\r
1385 last = 1;\r
1386 } else {\r
1387 if(last == 0) {\r
1388 // Sequence Z\r
1389 Sequence(SEC_Z);\r
1390 }\r
1391 else {\r
1392 // Sequence Y\r
1393 Sequence(SEC_Y);\r
1394 last = 0;\r
1395 }\r
1396 }\r
1397 b >>= 1;\r
1398 }\r
1399\r
1400 // End of Communication\r
1401 if(last == 0) {\r
1402 // Sequence Z\r
1403 Sequence(SEC_Z);\r
1404 }\r
1405 else {\r
1406 // Sequence Y\r
1407 Sequence(SEC_Y);\r
1408 last = 0;\r
1409 }\r
1410 // Sequence Y\r
1411 Sequence(SEC_Y);\r
1412\r
1413 // Just to be sure!\r
1414 Sequence(SEC_Y);\r
1415 Sequence(SEC_Y);\r
1416 Sequence(SEC_Y);\r
1417\r
1418 // Convert from last character reference to length\r
1419 ToSendMax++;\r
1420}\r
1421\r
1422//-----------------------------------------------------------------------------\r
1423// Prepare reader command to send to FPGA\r
84c02e97 1424// \r
6658905f 1425//-----------------------------------------------------------------------------\r
84c02e97 1426void CodeIso14443aAsReaderPar(const BYTE * cmd, int len, DWORD dwParity)\r
6658905f 1427{\r
84c02e97 1428 int i, j;\r
1429 int last;\r
1430 BYTE b;\r
1431 \r
1432 ToSendReset();\r
1433 \r
1434 // Start of Communication (Seq. Z)\r
1435 Sequence(SEC_Z);\r
1436 last = 0;\r
1437 \r
1438 // Generate send structure for the data bits\r
1439 for (i = 0; i < len; i++) {\r
1440 // Get the current byte to send\r
1441 b = cmd[i];\r
1442 \r
1443 for (j = 0; j < 8; j++) {\r
1444 if (b & 1) {\r
1445 // Sequence X\r
1446 Sequence(SEC_X);\r
1447 last = 1;\r
1448 } else {\r
1449 if (last == 0) {\r
1450 // Sequence Z\r
1451 Sequence(SEC_Z);\r
1452 } else {\r
1453 // Sequence Y\r
1454 Sequence(SEC_Y);\r
1455 last = 0;\r
6658905f 1456 }\r
84c02e97 1457 }\r
1458 b >>= 1;\r
6658905f 1459 }\r
84c02e97 1460 \r
1461 // Get the parity bit\r
1462 if ((dwParity >> i) & 0x01) {\r
1463 // Sequence X\r
1464 Sequence(SEC_X);\r
1465 last = 1;\r
1466 } else {\r
1467 if (last == 0) {\r
1468 // Sequence Z\r
1469 Sequence(SEC_Z);\r
1470 } else {\r
1471 // Sequence Y\r
1472 Sequence(SEC_Y);\r
1473 last = 0;\r
1474 }\r
1475 }\r
1476 }\r
1477 \r
1478 // End of Communication\r
1479 if (last == 0) {\r
1480 // Sequence Z\r
1481 Sequence(SEC_Z);\r
1482 } else {\r
1483 // Sequence Y\r
1484 Sequence(SEC_Y);\r
1485 last = 0;\r
1486 }\r
1487 // Sequence Y\r
1488 Sequence(SEC_Y);\r
1489 \r
1490 // Just to be sure!\r
1491 Sequence(SEC_Y);\r
1492 Sequence(SEC_Y);\r
1493 Sequence(SEC_Y);\r
1494 \r
1495 // Convert from last character reference to length\r
1496 ToSendMax++;\r
6658905f 1497}\r
1498\r
6658905f 1499//-----------------------------------------------------------------------------\r
1500// Wait a certain time for tag response\r
1501// If a response is captured return TRUE\r
1502// If it takes to long return FALSE\r
1503//-----------------------------------------------------------------------------\r
1504static BOOL GetIso14443aAnswerFromTag(BYTE *receivedResponse, int maxLen, int *samples, int *elapsed) //BYTE *buffer\r
1505{\r
1506 // buffer needs to be 512 bytes\r
1507 int c;\r
1508\r
0e25ae11 1509 // Set FPGA mode to "reader listen mode", no modulation (listen\r
6658905f 1510 // only, since we are receiving, not transmitting).\r
0e25ae11 1511 // Signal field is on with the appropriate LED\r
1512 LED_D_ON();\r
6658905f 1513 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_LISTEN);\r
1514\r
1515 // Now get the answer from the card\r
1516 Demod.output = receivedResponse;\r
1517 Demod.len = 0;\r
1518 Demod.state = DEMOD_UNSYNCD;\r
1519\r
1520 BYTE b;\r
84c02e97 1521 if (elapsed) *elapsed = 0;\r
6658905f 1522\r
1523 c = 0;\r
1524 for(;;) {\r
1525 WDT_HIT();\r
1526\r
6949aca9 1527 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {\r
1528 AT91C_BASE_SSC->SSC_THR = 0x00; // To make use of exact timing of next command from reader!!\r
84c02e97 1529 if (elapsed) (*elapsed)++;\r
6658905f 1530 }\r
6949aca9 1531 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {\r
6658905f 1532 if(c < 512) { c++; } else { return FALSE; }\r
6949aca9 1533 b = (BYTE)AT91C_BASE_SSC->SSC_RHR;\r
6658905f 1534 if(ManchesterDecoding((b & 0xf0) >> 4)) {\r
1535 *samples = ((c - 1) << 3) + 4;\r
1536 return TRUE;\r
1537 }\r
1538 if(ManchesterDecoding(b & 0x0f)) {\r
1539 *samples = c << 3;\r
1540 return TRUE;\r
1541 }\r
1542 }\r
1543 }\r
1544}\r
1545\r
84c02e97 1546void ReaderTransmitShort(const BYTE* bt)\r
1547{\r
1548 int wait = 0;\r
1549 int samples = 0;\r
1550\r
1551 ShortFrameFromReader(*bt);\r
1552 \r
1553 // Select the card\r
1554 TransmitFor14443a(ToSend, ToSendMax, &samples, &wait); \r
1555 \r
1556 // Store reader command in buffer\r
32cfae43 1557 if (tracing) LogTrace(bt,1,0,GetParity(bt,1),TRUE);\r
84c02e97 1558}\r
d24438f8 1559\r
84c02e97 1560void ReaderTransmitPar(BYTE* frame, int len, DWORD par)\r
1561{\r
1562 int wait = 0;\r
1563 int samples = 0;\r
1564 \r
1565 // This is tied to other size changes\r
1566 // BYTE* frame_addr = ((BYTE*)BigBuf) + 2024; \r
84c02e97 1567 CodeIso14443aAsReaderPar(frame,len,par);\r
1568 \r
1569 // Select the card\r
1570 TransmitFor14443a(ToSend, ToSendMax, &samples, &wait); \r
1571 \r
1572 // Store reader command in buffer\r
32cfae43 1573 if (tracing) LogTrace(frame,len,0,par,TRUE);\r
84c02e97 1574}\r
1575\r
1576\r
1577void ReaderTransmit(BYTE* frame, int len)\r
1578{\r
1579 // Generate parity and redirect\r
1580 ReaderTransmitPar(frame,len,GetParity(frame,len));\r
1581}\r
1582\r
1583BOOL ReaderReceive(BYTE* receivedAnswer)\r
1584{\r
1585 int samples = 0;\r
1586 if (!GetIso14443aAnswerFromTag(receivedAnswer,100,&samples,0)) return FALSE;\r
32cfae43 1587 if (tracing) LogTrace(receivedAnswer,Demod.len,samples,Demod.parityBits,FALSE);\r
84c02e97 1588 return TRUE;\r
1589}\r
d24438f8 1590\r
6658905f 1591//-----------------------------------------------------------------------------\r
1592// Read an ISO 14443a tag. Send out commands and store answers.\r
1593//\r
1594//-----------------------------------------------------------------------------\r
1595void ReaderIso14443a(DWORD parameter)\r
1596{\r
1597 // Anticollision\r
84c02e97 1598 BYTE wupa[] = { 0x52 };\r
1599 BYTE sel_all[] = { 0x93,0x20 };\r
1600 BYTE sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };\r
1601 BYTE sel_all_c2[] = { 0x95,0x20 };\r
1602 BYTE sel_uid_c2[] = { 0x95,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };\r
6658905f 1603\r
093cbaf6 1604 // Mifare AUTH\r
84c02e97 1605 BYTE mf_auth[] = { 0x60,0x00,0xf5,0x7b };\r
1606// BYTE mf_nr_ar[] = { 0x00,0x00,0x00,0x00 };\r
1607 \r
1608 BYTE* receivedAnswer = (((BYTE *)BigBuf) + 3560); // was 3560 - tied to other size changes\r
d24438f8 1609 traceLen = 0;\r
6658905f 1610\r
6658905f 1611 // Setup SSC\r
1612 FpgaSetupSsc();\r
1613\r
1614 // Start from off (no field generated)\r
84c02e97 1615 // Signal field is off with the appropriate LED\r
1616 LED_D_OFF();\r
1617 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1618 SpinDelay(200);\r
6658905f 1619\r
84c02e97 1620 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
1621 FpgaSetupSsc();\r
6658905f 1622\r
1623 // Now give it time to spin up.\r
84c02e97 1624 // Signal field is on with the appropriate LED\r
1625 LED_D_ON();\r
1626 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
6658905f 1627 SpinDelay(200);\r
1628\r
1629 LED_A_ON();\r
1630 LED_B_OFF();\r
1631 LED_C_OFF();\r
6658905f 1632\r
84c02e97 1633 while(traceLen < TRACE_LENGTH)\r
1634 {\r
1635 // Broadcast for a card, WUPA (0x52) will force response from all cards in the field\r
1636 ReaderTransmitShort(wupa);\r
d24438f8 1637 \r
1638 // Test if the action was cancelled\r
1639 if(BUTTON_PRESS()) {\r
1640 break;\r
1641 }\r
1642 \r
84c02e97 1643 // Receive the ATQA\r
1644 if (!ReaderReceive(receivedAnswer)) continue;\r
6658905f 1645\r
84c02e97 1646 // Transmit SELECT_ALL\r
1647 ReaderTransmit(sel_all,sizeof(sel_all));\r
6658905f 1648\r
84c02e97 1649 // Receive the UID\r
1650 if (!ReaderReceive(receivedAnswer)) continue;\r
d24438f8 1651 \r
6658905f 1652 // Construct SELECT UID command\r
1653 // First copy the 5 bytes (Mifare Classic) after the 93 70\r
84c02e97 1654 memcpy(sel_uid+2,receivedAnswer,5);\r
6658905f 1655 // Secondly compute the two CRC bytes at the end\r
84c02e97 1656 AppendCrc14443a(sel_uid,7);\r
6658905f 1657\r
84c02e97 1658 // Transmit SELECT_UID\r
1659 ReaderTransmit(sel_uid,sizeof(sel_uid));\r
1660 \r
1661 // Receive the SAK\r
1662 if (!ReaderReceive(receivedAnswer)) continue;\r
d24438f8 1663\r
1664 // OK we have selected at least at cascade 1, lets see if first byte of UID was 0x88 in\r
1665 // which case we need to make a cascade 2 request and select - this is a long UID\r
84c02e97 1666 // When the UID is not complete, the 3nd bit (from the right) is set in the SAK. \r
1667 if (receivedAnswer[0] &= 0x04)\r
6658905f 1668 {\r
84c02e97 1669 // Transmit SELECT_ALL\r
1670 ReaderTransmit(sel_all_c2,sizeof(sel_all_c2));\r
1671 \r
1672 // Receive the UID\r
1673 if (!ReaderReceive(receivedAnswer)) continue;\r
1674 \r
1675 // Construct SELECT UID command\r
1676 memcpy(sel_uid_c2+2,receivedAnswer,5);\r
d24438f8 1677 // Secondly compute the two CRC bytes at the end\r
84c02e97 1678 AppendCrc14443a(sel_uid_c2,7);\r
d24438f8 1679 \r
84c02e97 1680 // Transmit SELECT_UID\r
1681 ReaderTransmit(sel_uid_c2,sizeof(sel_uid_c2));\r
d24438f8 1682 \r
84c02e97 1683 // Receive the SAK\r
1684 if (!ReaderReceive(receivedAnswer)) continue;\r
0e25ae11 1685 }\r
6658905f 1686\r
84c02e97 1687 // Transmit MIFARE_CLASSIC_AUTH\r
1688 ReaderTransmit(mf_auth,sizeof(mf_auth));\r
d24438f8 1689\r
84c02e97 1690 // Receive the (16 bit) "random" nonce\r
1691 if (!ReaderReceive(receivedAnswer)) continue;\r
6658905f 1692 }\r
1693\r
d24438f8 1694 // Thats it...\r
5435eb0c 1695 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
093cbaf6 1696 LEDsoff();\r
6658905f 1697 DbpIntegers(rsamples, 0xCC, 0xCC);\r
1698 DbpString("ready..");\r
1699}\r
32cfae43 1700\r
1701//-----------------------------------------------------------------------------\r
1702// Read an ISO 14443a tag. Send out commands and store answers.\r
1703//\r
1704//-----------------------------------------------------------------------------\r
1705void ReaderMifare(DWORD parameter)\r
1706{\r
1707 \r
1708 // Anticollision\r
1709 BYTE wupa[] = { 0x52 };\r
1710 BYTE sel_all[] = { 0x93,0x20 };\r
1711 BYTE sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };\r
1712 \r
1713 // Mifare AUTH\r
1714 BYTE mf_auth[] = { 0x60,0x00,0xf5,0x7b };\r
1715 BYTE mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };\r
1716 \r
1717 BYTE* receivedAnswer = (((BYTE *)BigBuf) + 3560); // was 3560 - tied to other size changes\r
1718 traceLen = 0;\r
1719 tracing = false;\r
1720 \r
1721 // Setup SSC\r
1722 FpgaSetupSsc();\r
1723 \r
1724 // Start from off (no field generated)\r
1725 // Signal field is off with the appropriate LED\r
1726 LED_D_OFF();\r
1727 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1728 SpinDelay(200);\r
1729 \r
1730 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
1731 FpgaSetupSsc();\r
1732 \r
1733 // Now give it time to spin up.\r
1734 // Signal field is on with the appropriate LED\r
1735 LED_D_ON();\r
1736 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
1737 SpinDelay(200);\r
1738 \r
1739 LED_A_ON();\r
1740 LED_B_OFF();\r
1741 LED_C_OFF();\r
1742 \r
1743 // Broadcast for a card, WUPA (0x52) will force response from all cards in the field\r
1744 ReaderTransmitShort(wupa);\r
1745 // Receive the ATQA\r
1746 ReaderReceive(receivedAnswer);\r
1747 // Transmit SELECT_ALL\r
1748 ReaderTransmit(sel_all,sizeof(sel_all));\r
1749 // Receive the UID\r
1750 ReaderReceive(receivedAnswer);\r
1751 // Construct SELECT UID command\r
1752 // First copy the 5 bytes (Mifare Classic) after the 93 70\r
1753 memcpy(sel_uid+2,receivedAnswer,5);\r
1754 // Secondly compute the two CRC bytes at the end\r
1755 AppendCrc14443a(sel_uid,7);\r
1756 \r
1757 byte_t nt_diff = 0;\r
1758 LED_A_OFF();\r
1759 byte_t par = 0;\r
1760 byte_t par_mask = 0xff;\r
1761 byte_t par_low = 0;\r
1762 BOOL led_on = TRUE;\r
1763 \r
1764 tracing = FALSE;\r
1765 byte_t nt[4];\r
1766 byte_t nt_attacked[4];\r
1767 byte_t par_list[8];\r
1768 byte_t ks_list[8];\r
1769 num_to_bytes(parameter,4,nt_attacked);\r
1770\r
1771 while(TRUE)\r
1772 {\r
1773 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1774 SpinDelay(200);\r
1775 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
1776 \r
1777 // Broadcast for a card, WUPA (0x52) will force response from all cards in the field\r
1778 ReaderTransmitShort(wupa);\r
1779 \r
1780 // Test if the action was cancelled\r
1781 if(BUTTON_PRESS()) {\r
1782 break;\r
1783 }\r
1784 \r
1785 // Receive the ATQA\r
1786 if (!ReaderReceive(receivedAnswer)) continue;\r
1787 \r
1788 // Transmit SELECT_ALL\r
1789 ReaderTransmit(sel_all,sizeof(sel_all));\r
1790 \r
1791 // Receive the UID\r
1792 if (!ReaderReceive(receivedAnswer)) continue;\r
1793 \r
1794 // Transmit SELECT_UID\r
1795 ReaderTransmit(sel_uid,sizeof(sel_uid));\r
1796 \r
1797 // Receive the SAK\r
1798 if (!ReaderReceive(receivedAnswer)) continue;\r
1799 \r
1800 // Transmit MIFARE_CLASSIC_AUTH\r
1801 ReaderTransmit(mf_auth,sizeof(mf_auth));\r
1802 \r
1803 // Receive the (16 bit) "random" nonce\r
1804 if (!ReaderReceive(receivedAnswer)) continue;\r
1805 memcpy(nt,receivedAnswer,4);\r
1806\r
1807 // Transmit reader nonce and reader answer\r
1808 ReaderTransmitPar(mf_nr_ar,sizeof(mf_nr_ar),par);\r
1809 \r
1810 // Receive 4 bit answer\r
1811 if (ReaderReceive(receivedAnswer))\r
1812 {\r
1813 if (nt_diff == 0) \r
1814 {\r
1815 LED_A_ON();\r
1816 memcpy(nt_attacked,nt,4);\r
1817 par_mask = 0xf8;\r
1818 par_low = par & 0x07;\r
1819 }\r
1820\r
1821 if (memcmp(nt,nt_attacked,4) != 0) continue;\r
1822\r
1823 led_on = !led_on;\r
1824 if(led_on) LED_B_ON(); else LED_B_OFF();\r
1825 par_list[nt_diff] = par;\r
1826 ks_list[nt_diff] = receivedAnswer[0]^0x05;\r
1827 \r
1828 // Test if the information is complete\r
1829 if (nt_diff == 0x07) break;\r
1830 \r
1831 nt_diff = (nt_diff+1) & 0x07;\r
1832 mf_nr_ar[3] = nt_diff << 5;\r
1833 par = par_low;\r
1834 } else {\r
1835 if (nt_diff == 0)\r
1836 {\r
1837 par++;\r
1838 } else {\r
1839 par = (((par>>3)+1) << 3) | par_low;\r
1840 }\r
1841 }\r
1842 }\r
1843 \r
1844 LogTraceInfo(sel_uid+2,4);\r
1845 LogTraceInfo(nt,4);\r
1846 LogTraceInfo(par_list,8);\r
1847 LogTraceInfo(ks_list,8);\r
1848 \r
1849 // Thats it...\r
1850 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
1851 LEDsoff();\r
1852 tracing = TRUE;\r
1853}\r
Impressum, Datenschutz