1
|
/* ISO14443A Miller decoder for OpenPICC, working with differential time samples
|
2
|
*
|
3
|
* Copyright 2007 Milosch Meriac <meriac@bitmanufaktur.de>
|
4
|
* Copyright 2007 Karsten Nohl <honk98@web.de>
|
5
|
* Copyright 2007,2008 Henryk Plötz <henryk@ploetzli.ch>
|
6
|
*
|
7
|
* This program is free software; you can redistribute it and/or modify
|
8
|
* it under the terms of the GNU General Public License as published by
|
9
|
* the Free Software Foundation; either version 2 of the License, or
|
10
|
* (at your option) any later version.
|
11
|
*
|
12
|
* This program is distributed in the hope that it will be useful,
|
13
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
* GNU General Public License for more details.
|
16
|
*
|
17
|
* You should have received a copy of the GNU General Public License
|
18
|
* along with this program; if not, write to the Free Software
|
19
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
20
|
*
|
21
|
*/
|
22
|
|
23
|
#include <openpicc.h>
|
24
|
#include <FreeRTOS.h>
|
25
|
|
26
|
#include <errno.h>
|
27
|
#include <stdlib.h>
|
28
|
#include <string.h>
|
29
|
|
30
|
#include "iso14443.h"
|
31
|
#include "iso14443a_diffmiller.h"
|
32
|
#include "usb_print.h"
|
33
|
|
34
|
#include "performance.h"
|
35
|
|
36
|
#define DEBUGP (void)
|
37
|
#define printf usb_print_string
|
38
|
|
39
|
/*
|
40
|
* Decoding Methodology: We'll only see the edges for the start of modulation pauses and not
|
41
|
* all symbols generate modulation pauses at all. Two phases:
|
42
|
* + Old state and next edge delta to sequence of symbols (might be more than one symbol per edge)
|
43
|
* + Symbols to EOF/SOF marker and bits
|
44
|
*
|
45
|
* These are the possible old-state/delta combinations and the symbols they yield:
|
46
|
*
|
47
|
* old_state delta (in bit_len/4) symbol(s)
|
48
|
* none 3 ZZ
|
49
|
* none 5 ZX
|
50
|
* X 3 X
|
51
|
* X 5 YZ
|
52
|
* X 7 YX
|
53
|
* X >=9 YY
|
54
|
* Y 3 ZZ
|
55
|
* Y 5 ZX
|
56
|
* Z 3 Z
|
57
|
* Z 5 X
|
58
|
* Z >=7 Y
|
59
|
*
|
60
|
* All other combinations are invalid and likely en- or decoding errors. (Note that old_state
|
61
|
* Y is exactly the same as old_state none.)
|
62
|
*
|
63
|
* The mapping from symbol sequences to SOF/EOF/bit is as follows:
|
64
|
* X: 1
|
65
|
* 0, then Y: EOF
|
66
|
* other Y: 0
|
67
|
* first Z: SOF
|
68
|
* other Z: 0
|
69
|
*/
|
70
|
|
71
|
#define BIT_LEN 128
|
72
|
/* The theoretical error margin for the timing measurement is about 7 (note: that is a jitter of 7 in
|
73
|
* total, e.g. +/- 3.5), but we'll round that up to +/- 8. However, the specification allows pause
|
74
|
* times from 2us to 3us, e.g. 1us difference, so we'll add another 13.
|
75
|
*/
|
76
|
#define BIT_LEN_ERROR_MAX (8+13)
|
77
|
#define PAUSE_LEN 20
|
78
|
/* Subtract the mean error margin (about 4, see comment above) from the bit length
|
79
|
* Also subtract the pause length for the case when the clock is not counting during
|
80
|
* a pause. Will subtract this length below for the when the clock *is* counting during
|
81
|
* pauses.
|
82
|
*/
|
83
|
#define BIT_OFFSET (-4 -PAUSE_LEN)
|
84
|
#define BIT_LEN_3 ((BIT_LEN*3)/4 +BIT_OFFSET)
|
85
|
#define BIT_LEN_5 ((BIT_LEN*5)/4 +BIT_OFFSET)
|
86
|
#define BIT_LEN_7 ((BIT_LEN*7)/4 +BIT_OFFSET)
|
87
|
#define BIT_LEN_9 ((BIT_LEN*9)/4 +BIT_OFFSET)
|
88
|
|
89
|
#define ALMOST_EQUAL(a,b) ( abs(a-b) <= BIT_LEN_ERROR_MAX )
|
90
|
#define MUCH_GREATER_THAN(a,b) ( a > (b+BIT_LEN_ERROR_MAX) )
|
91
|
#define ALMOST_GREATER_THAN_OR_EQUAL(a,b) (a >= (b-BIT_LEN_ERROR_MAX))
|
92
|
|
93
|
enum symbol {NO_SYM=0, sym_x, sym_y, sym_z};
|
94
|
enum bit { BIT_ERROR, BIT_SOF, BIT_0, BIT_1, BIT_EOF };
|
95
|
|
96
|
#define PERFORMANCE_COUNTS 10
|
97
|
struct diffmiller_state {
|
98
|
int initialized, pauses_count;
|
99
|
enum symbol old_state;
|
100
|
enum bit last_bit;
|
101
|
iso14443_frame *frame;
|
102
|
u_int32_t counter;
|
103
|
u_int16_t byte,crc;
|
104
|
u_int8_t parity;
|
105
|
u_int8_t last_data_bit;
|
106
|
u_int32_t performance[PERFORMANCE_COUNTS][2];
|
107
|
size_t perf_index;
|
108
|
struct {
|
109
|
u_int8_t in_frame:1;
|
110
|
u_int8_t frame_finished:1;
|
111
|
u_int8_t overflow:1;
|
112
|
u_int8_t error:1;
|
113
|
} flags;
|
114
|
};
|
115
|
|
116
|
struct diffmiller_state _state;
|
117
|
|
118
|
inline void start_frame(struct diffmiller_state * const state)
|
119
|
{
|
120
|
state->byte=0;
|
121
|
state->parity=0;
|
122
|
state->crc=0x6363;
|
123
|
|
124
|
performance_set_checkpoint("start_frame before memset");
|
125
|
memset(&state->flags, 0, sizeof(state->flags));
|
126
|
state->flags.in_frame = 1;
|
127
|
|
128
|
//memset(state->frame, 0, sizeof(*state->frame));
|
129
|
memset(state->frame, 0, (u_int32_t)&(((iso14443_frame*)0)->data) );
|
130
|
performance_set_checkpoint("start_frame after memset");
|
131
|
state->frame->state = FRAME_PENDING;
|
132
|
}
|
133
|
|
134
|
static inline void append_to_frame(struct diffmiller_state *const state,
|
135
|
u_int8_t byte, const u_int8_t parity, const u_int8_t valid_bits) {
|
136
|
|
137
|
iso14443_frame * const f = state->frame;
|
138
|
|
139
|
if(f->numbytes >= sizeof(f->data)/sizeof(f->data[0])-1) { /* -1, because the last byte may be half filled */
|
140
|
state->flags.overflow = 1;
|
141
|
return;
|
142
|
}
|
143
|
|
144
|
if(f->numbits != 0) {
|
145
|
DEBUGP("Appending to a frame with incomplete byte");
|
146
|
}
|
147
|
|
148
|
f->data[f->numbytes] = byte & 0xff;
|
149
|
f->parity[f->numbytes/8] |= ((parity&1)<<(f->numbytes%8));
|
150
|
|
151
|
if(valid_bits == 8) {
|
152
|
f->numbytes++;
|
153
|
byte=(byte ^ state->crc)&0xFF;
|
154
|
byte=(byte ^ byte<<4)&0xFF;
|
155
|
state->crc=((state->crc>>8)^(byte<<8)^(byte<<3)^(byte>>4))&0xFFFF;
|
156
|
} else {
|
157
|
f->numbits += valid_bits;
|
158
|
}
|
159
|
}
|
160
|
|
161
|
|
162
|
static inline void end_frame(struct diffmiller_state * const state, const u_int32_t counter, const int last_data_bit)
|
163
|
{
|
164
|
if(state->frame != NULL) {
|
165
|
if(counter > 0) {
|
166
|
append_to_frame(state, state->byte, 0, counter);
|
167
|
}
|
168
|
|
169
|
state->frame->parameters.a.parity = GIVEN_PARITY;
|
170
|
if(!state->crc)
|
171
|
state->frame->parameters.a.crc = CRC_OK;
|
172
|
else
|
173
|
state->frame->parameters.a.crc = CRC_ERROR;
|
174
|
|
175
|
if(last_data_bit)
|
176
|
state->frame->parameters.a.last_bit = ISO14443A_LAST_BIT_1;
|
177
|
else
|
178
|
state->frame->parameters.a.last_bit = ISO14443A_LAST_BIT_0;
|
179
|
|
180
|
state->flags.frame_finished = 1;
|
181
|
}
|
182
|
}
|
183
|
|
184
|
#define PRINT_BIT(a) if(0){(void)a;}
|
185
|
//#define PRINT_BIT(a) usb_print_string_f(a,0)
|
186
|
|
187
|
#define DO_BIT_0 { \
|
188
|
last_data_bit = 0; \
|
189
|
if(++counter==9) { \
|
190
|
append_to_frame(state, state->byte, 0, 8); \
|
191
|
counter=state->byte=state->parity=0; \
|
192
|
} \
|
193
|
PRINT_BIT(" 0"); \
|
194
|
}
|
195
|
|
196
|
#define DO_BIT_1 { \
|
197
|
last_data_bit = 1; \
|
198
|
if(counter<8) { \
|
199
|
state->byte |= (1<<counter); \
|
200
|
state->parity ^= 1; \
|
201
|
} \
|
202
|
if(++counter==9) { \
|
203
|
append_to_frame(state, state->byte, 1, 8); \
|
204
|
counter=state->byte=state->parity=0; \
|
205
|
} \
|
206
|
PRINT_BIT(" 1"); \
|
207
|
}
|
208
|
|
209
|
#define DO_SYMBOL_X \
|
210
|
PRINT_BIT("(X)"); \
|
211
|
if(!in_frame) { \
|
212
|
if(last_bit == BIT_0) DO_BIT_0; \
|
213
|
error = 1; \
|
214
|
PRINT_BIT(" ERROR\n"); \
|
215
|
last_bit = BIT_ERROR; \
|
216
|
in_frame = 0; \
|
217
|
} else { \
|
218
|
if(last_bit == BIT_0) DO_BIT_0; \
|
219
|
DO_BIT_1; \
|
220
|
last_bit = BIT_1; \
|
221
|
}
|
222
|
|
223
|
#define DO_SYMBOL_Y \
|
224
|
PRINT_BIT("(Y)"); \
|
225
|
if(!in_frame) { \
|
226
|
if(last_bit == BIT_0) DO_BIT_0; \
|
227
|
error = 1; \
|
228
|
PRINT_BIT(" ERROR\n"); \
|
229
|
last_bit = BIT_ERROR; \
|
230
|
in_frame = 0; \
|
231
|
} else { \
|
232
|
if(last_bit == BIT_0) { \
|
233
|
end_frame(state, counter, last_data_bit); \
|
234
|
PRINT_BIT(" EOF\n"); \
|
235
|
last_bit = BIT_EOF; \
|
236
|
in_frame = 0; \
|
237
|
} else { \
|
238
|
last_bit = BIT_0; \
|
239
|
} \
|
240
|
}
|
241
|
|
242
|
#define DO_SYMBOL_Z \
|
243
|
PRINT_BIT("(Z)"); \
|
244
|
if(!in_frame) { \
|
245
|
if(last_bit == BIT_0) DO_BIT_0; \
|
246
|
counter = 0; \
|
247
|
start_frame(state); \
|
248
|
PRINT_BIT("SOF"); \
|
249
|
in_frame = 1; \
|
250
|
last_bit = BIT_ERROR; \
|
251
|
last_bit = BIT_SOF; \
|
252
|
} else { \
|
253
|
if(last_bit == BIT_0) DO_BIT_0; \
|
254
|
last_bit = BIT_0; \
|
255
|
}
|
256
|
|
257
|
|
258
|
int __ramfunc iso14443a_decode_diffmiller(struct diffmiller_state * const state, iso14443_frame * const frame,
|
259
|
const u_int32_t buffer[], unsigned int * const offset, const unsigned int buflen)
|
260
|
{
|
261
|
if(state == NULL || !state->initialized) return -EINVAL;
|
262
|
if(state->frame != NULL && state->frame != frame) return -EINVAL;
|
263
|
state->frame = frame;
|
264
|
|
265
|
enum symbol old_state = state->old_state;
|
266
|
enum bit last_bit = state->last_bit;
|
267
|
int in_frame = state->flags.in_frame;
|
268
|
int error = state->flags.error;
|
269
|
int counter = state->counter;
|
270
|
int last_data_bit = state->last_data_bit;
|
271
|
|
272
|
if(state->perf_index < PERFORMANCE_COUNTS) {
|
273
|
state->performance[state->perf_index][0] = *offset;
|
274
|
state->performance[state->perf_index++][1] = buflen;
|
275
|
}
|
276
|
|
277
|
for(; *offset < buflen; ) {
|
278
|
int delta;
|
279
|
if(state->pauses_count)
|
280
|
delta = buffer[(*offset)++] - PAUSE_LEN;
|
281
|
else
|
282
|
delta = buffer[(*offset)++];
|
283
|
|
284
|
switch(old_state) {
|
285
|
case sym_x:
|
286
|
if( ALMOST_EQUAL(delta, BIT_LEN_3) ) {
|
287
|
DO_SYMBOL_X;
|
288
|
old_state = sym_x;
|
289
|
} else if( ALMOST_EQUAL(delta, BIT_LEN_5) ) {
|
290
|
DO_SYMBOL_Y;
|
291
|
DO_SYMBOL_Z;
|
292
|
old_state = sym_z;
|
293
|
} else if( ALMOST_EQUAL(delta, BIT_LEN_7) ) {
|
294
|
DO_SYMBOL_Y;
|
295
|
DO_SYMBOL_X;
|
296
|
old_state = sym_x;
|
297
|
} else if( ALMOST_GREATER_THAN_OR_EQUAL(delta, BIT_LEN_9)) {
|
298
|
DO_SYMBOL_Y;
|
299
|
DO_SYMBOL_Y;
|
300
|
old_state = sym_y;
|
301
|
}
|
302
|
break;
|
303
|
case NO_SYM: /* Fall-Through */
|
304
|
case sym_y:
|
305
|
if( ALMOST_EQUAL(delta, BIT_LEN_3) ) {
|
306
|
DO_SYMBOL_Z;
|
307
|
DO_SYMBOL_Z;
|
308
|
old_state = sym_z;
|
309
|
} else if( ALMOST_EQUAL(delta, BIT_LEN_5) ) {
|
310
|
DO_SYMBOL_Z;
|
311
|
DO_SYMBOL_X;
|
312
|
old_state = sym_x;
|
313
|
}
|
314
|
break;
|
315
|
case sym_z:
|
316
|
if( ALMOST_EQUAL(delta, BIT_LEN_3) ) {
|
317
|
DO_SYMBOL_Z;
|
318
|
old_state = sym_z;
|
319
|
} else if( ALMOST_EQUAL(delta, BIT_LEN_5) ) {
|
320
|
DO_SYMBOL_X;
|
321
|
old_state = sym_x;
|
322
|
} else if( ALMOST_GREATER_THAN_OR_EQUAL(delta, BIT_LEN_7)) {
|
323
|
DO_SYMBOL_Y;
|
324
|
old_state = sym_y;
|
325
|
}
|
326
|
break;
|
327
|
}
|
328
|
|
329
|
if(state->flags.frame_finished) {
|
330
|
state->flags.frame_finished = 0;
|
331
|
state->old_state = sym_y;
|
332
|
state->last_bit = last_bit;
|
333
|
state->counter = counter;
|
334
|
state->flags.in_frame = in_frame;
|
335
|
state->flags.error = error;
|
336
|
state->frame = NULL;
|
337
|
performance_set_checkpoint("frame finished");
|
338
|
return 0;
|
339
|
}
|
340
|
}
|
341
|
|
342
|
state->old_state = old_state;
|
343
|
state->last_bit = last_bit;
|
344
|
state->counter = counter;
|
345
|
state->last_data_bit = last_data_bit;
|
346
|
state->flags.in_frame = in_frame;
|
347
|
state->flags.error = error;
|
348
|
|
349
|
return -EBUSY;
|
350
|
}
|
351
|
|
352
|
int iso14443a_diffmiller_assert_frame_ended(struct diffmiller_state * const state,
|
353
|
iso14443_frame * const frame)
|
354
|
{
|
355
|
if(state == NULL || !state->initialized) return -EINVAL;
|
356
|
if(!state->flags.in_frame) return -EBUSY;
|
357
|
if(state->frame != NULL && state->frame != frame) return -EINVAL;
|
358
|
state->frame = frame;
|
359
|
|
360
|
end_frame(state, state->counter, state->last_data_bit);
|
361
|
PRINT_BIT(" EOF2\n");
|
362
|
state->flags.in_frame = 0;
|
363
|
|
364
|
if(state->flags.frame_finished) {
|
365
|
state->flags.frame_finished = 0;
|
366
|
state->old_state = sym_y;
|
367
|
state->last_bit = BIT_EOF;
|
368
|
state->counter = 0;
|
369
|
state->frame = NULL;
|
370
|
performance_set_checkpoint("frame finished2");
|
371
|
return 0;
|
372
|
}
|
373
|
|
374
|
return -EBUSY;
|
375
|
}
|
376
|
|
377
|
struct diffmiller_state *iso14443a_init_diffmiller(int pauses_count)
|
378
|
{
|
379
|
if(_state.initialized) return NULL;
|
380
|
struct diffmiller_state *state = &_state;
|
381
|
state->initialized = 1;
|
382
|
state->pauses_count = pauses_count;
|
383
|
state->frame = NULL;
|
384
|
state->old_state = sym_y;
|
385
|
state->flags.frame_finished = 0;
|
386
|
|
387
|
return state;
|
388
|
}
|
389
|
|
390
|
|
391
|
#include "cmd.h"
|
392
|
void iso14443a_diffmiller_print_performance(struct diffmiller_state * const state)
|
393
|
{
|
394
|
DumpStringToUSB("`");
|
395
|
unsigned int i; for(i=0; i<state->perf_index; i++) {
|
396
|
if(i>0)DumpStringToUSB(";");
|
397
|
DumpUIntToUSB(state->performance[i][0]); DumpStringToUSB(":"); DumpUIntToUSB(state->performance[i][1]);
|
398
|
}
|
399
|
DumpStringToUSB("'");
|
400
|
state->perf_index=0;
|
401
|
}
|