Project

General

Profile

Download (11.8 KB) Statistics
| Branch: | Tag: | Revision:
1
/***************************************************************
2
 *
3
 * OpenPICC - ISO 14443 Layer 3 response pretender, 
4
 * proof of concept
5
 *
6
 * Copyright 2008 Henryk Plötz <henryk@ploetzli.ch>
7
 *
8
 ***************************************************************
9

    
10
    This program is free software; you can redistribute it and/or modify
11
    it under the terms of the GNU General Public License as published by
12
    the Free Software Foundation; version 2.
13

    
14
    This program is distributed in the hope that it will be useful,
15
    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
    GNU General Public License for more details.
18

    
19
    You should have received a copy of the GNU General Public License along
20
    with this program; if not, write to the Free Software Foundation, Inc.,
21
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22

    
23
*/
24

    
25
#include <FreeRTOS.h>
26
#include <board.h>
27
#include <task.h>
28
#include <errno.h>
29
#include <string.h>
30
#include <stdlib.h>
31

    
32
#include "openpicc.h"
33
#include "ssc_buffer.h"
34
#include "iso14443.h"
35
#include "iso14443_layer2a.h"
36
#include "iso14443a_pretender.h"
37
#include "iso14443a_manchester.h"
38
#include "usb_print.h"
39
#include "cmd.h"
40
extern volatile int fdt_offset;
41
#include "led.h"
42

    
43
struct challenge_response {
44
	u_int8_t UID[5];
45
	u_int8_t nonce[4];
46
	u_int8_t waiting_for_response; 
47
	struct {
48
		u_int8_t data[8];
49
		u_int8_t parity[2];
50
		size_t len;
51
	} response;
52
};
53

    
54
struct challenge_response challenge_response;
55

    
56
static const iso14443_frame ATQA_FRAME = {
57
	TYPE_A,
58
	FRAME_PREFILLED,
59
	{{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}},
60
	2,
61
	0, 0,
62
	{4, 0},
63
	{}
64
};
65

    
66
static const iso14443_frame ATS_FRAME = {
67
	TYPE_A,
68
	FRAME_PREFILLED,
69
	{{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}},
70
	3,
71
	0, 0,
72
	{0x08, 0xB6, 0xDD},
73
	{}
74
};
75

    
76
static iso14443_frame UID_FRAME, NONCE_FRAME;
77
//static u_int8_t UID[]   = {0xF4, 0xAC, 0xF9, 0xD7}; // bcc = 0x76
78
static u_int8_t UID[]   = {0x00, 0x00, 0x00, 0x00}; 
79
static u_int8_t nonce[] = {0x00, 0x00, 0x00, 0x00};
80

    
81
#define FRAME_SIZE(bytes) (2* (1+(9*bytes)+1) )
82
#define BYTES_AND_BITS(bytes,bits) (bytes*9+bits)
83
#define GET_BASE_SIZE(type) ((size_t) &(((type*)0)->data))
84

    
85
static ssc_dma_tx_buffer_t *ATQA_BUFFER, *UID_BUFFER, *ATS_BUFFER, *NONCE_BUFFER;
86

    
87
static ssc_dma_tx_buffer_t *alloc_buffer_for_frame(const iso14443_frame *frame)
88
{
89
	int datalen = FRAME_SIZE( BYTES_AND_BITS(frame->numbytes, frame->numbits) );
90
	ssc_dma_tx_buffer_t *dst = pvPortMalloc( GET_BASE_SIZE(typeof(*dst)) + datalen );
91
	if(dst == NULL) return NULL;
92
	dst->len = datalen;
93
	return dst;
94
}
95

    
96
static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, iso14443_frame *frame, u_int8_t in_irq)
97
{
98
	(void)buffer; (void)in_irq;
99
	u_int32_t cv = *AT91C_TC2_CV;
100
	
101
	ssc_dma_tx_buffer_t *tx_buffer=NULL;
102
	int fdt = 0;
103
	
104
	switch(frame->parameters.a.last_bit) {
105
	case ISO14443A_LAST_BIT_0:
106
		fdt = 20;
107
		break;
108
	case ISO14443A_LAST_BIT_1:
109
		fdt = 84;
110
		break;
111
	case ISO14443A_LAST_BIT_NONE:
112
		fdt = 0;
113
		break;
114
	}
115
	
116
	
117
	if(cv < 870) /* Anticollision is time-critical, do not even try to send if we're too late anyway */
118
		switch(BYTES_AND_BITS(frame->numbytes,frame->numbits)) {
119
		case BYTES_AND_BITS(0, 7): /* REQA or WUPA (7 bits) */
120
			if(frame->data[0] == 0x26 || frame->data[0] == 0x52)
121
				tx_buffer = ATQA_BUFFER;
122
			fdt += 9*128;
123
			break;
124
		case BYTES_AND_BITS(2, 0): /* ANTICOL (2 bytes) */
125
			if(frame->data[0] == 0x93 && frame->data[1] == 0x20)
126
				tx_buffer = UID_BUFFER;
127
			fdt += 9*128;
128
			break;
129
		case BYTES_AND_BITS(9, 0): /* SELECT (9 bytes) */
130
			if(frame->data[0] == 0x93 && frame->data[1] == 0x70 && frame->parameters.a.crc &&
131
					( *((u_int32_t*)&frame->data[2]) ==  *((u_int32_t*)&UID) ) )
132
				tx_buffer = ATS_BUFFER;
133
			fdt += 9*128;
134
			break;
135
		}
136
	
137
	if(tx_buffer == NULL) 
138
		switch(BYTES_AND_BITS(frame->numbytes, frame->numbits)) {
139
		case BYTES_AND_BITS(4, 0):
140
			if( (frame->data[0] & 0xfe) == 0x60 && frame->parameters.a.crc) {
141
				/* AUTH1A or AUTH1B */
142
				if(NONCE_BUFFER == NULL) {
143
					NONCE_BUFFER = alloc_buffer_for_frame(&NONCE_FRAME);
144
				}
145
				if(NONCE_BUFFER != NULL) {
146
					int ret = manchester_encode(NONCE_BUFFER->data,  NONCE_BUFFER->len,  &NONCE_FRAME);
147
					if(ret < 0) {
148
					} else {
149
						NONCE_BUFFER->len = ret;
150
						tx_buffer = NONCE_BUFFER;
151
					}
152
				}
153
				
154
				/*fdt += ((cv / 128) + 10) * 128;*/
155
				fdt += 50*128;  /* 52 ok, 26 not, 39 not, 45 not, 48 not, 50 ok, 49 not */
156
			}
157
			break;
158
		}
159
	
160
	/* Add some extra room to the fdt for testing */
161
	//fdt += 3*128;
162
	fdt += fdt_offset;
163
	
164
	if(tx_buffer != NULL) {
165
		tx_buffer->state = SSC_FULL;
166
		if(	iso14443_transmit(tx_buffer, fdt, 1, 0) < 0) {
167
			usb_print_string_f("Tx failed ", 0);
168
		}
169
	}
170
	
171
#if 0
172
	u_int32_t cv2 = *AT91C_TC2_CV;
173
	usb_print_string_f("\r\n",0);
174
	if(tx_buffer == &NONCE_BUFFER) usb_print_string_f("---> ",0);
175
	int old=usb_print_set_default_flush(0);
176
	DumpUIntToUSB(cv);
177
	DumpStringToUSB(":");
178
	DumpUIntToUSB(cv2);
179
	usb_print_set_default_flush(old);
180
#endif
181
	
182
	switch(BYTES_AND_BITS(frame->numbytes,frame->numbits)) {
183
	case BYTES_AND_BITS(4, 0):
184
		if(frame->parameters.a.crc && frame->data[0] == 0x50 && frame->data[1] == 0x00) {
185
			/* HLTA */
186
			UID[3]++;
187
			if(UID[3]==0) {
188
				UID[2]++;
189
				if(UID[2]==0) {
190
					UID[1]++;
191
					if(UID[1]==0) {
192
						UID[0]++;
193
					}
194
				}
195
			}
196
			set_UID(UID, sizeof(UID));
197
		}
198
	break;
199
	}
200
	
201
	if(tx_buffer) usb_print_string_f("\r\n",0);
202
	if(tx_buffer == UID_BUFFER) {
203
		memcpy(&challenge_response.UID, UID_FRAME.data, 5);
204
		usb_print_string_f("uid", 0);
205
	} else if(tx_buffer == NONCE_BUFFER) {
206
		memcpy(&challenge_response.nonce, NONCE_FRAME.data, 4);
207
		challenge_response.waiting_for_response = 1;
208
		usb_print_string_f("nonce", 0);
209
	} else if(challenge_response.waiting_for_response) {
210
		challenge_response.waiting_for_response = 0;
211
		if(frame->numbytes != 8) {
212
			usb_print_string_f("tilt ",0);
213
		}
214
		challenge_response.response.len = frame->numbytes + (frame->numbits+7)/8;
215
		memcpy(&challenge_response.response.data, frame->data, challenge_response.response.len);
216
		memcpy(&challenge_response.response.parity, frame->parity, 1);
217

    
218
		int old=usb_print_set_default_flush(0);
219
		DumpStringToUSB("[[");
220
		DumpBufferToUSB((char*)challenge_response.UID, 5);
221
		DumpStringToUSB(" ");
222
		DumpBufferToUSB((char*)challenge_response.nonce, 4);
223
		DumpStringToUSB(" ");
224
		DumpBufferToUSB((char*)challenge_response.response.data, challenge_response.response.len);
225
		DumpStringToUSB("]]");
226
		usb_print_set_default_flush(old);
227
	}
228
	//usb_print_string_f("%", 0);
229
}
230

    
231
static void prepare_frame(iso14443_frame *frame, int len)
232
{
233
	memset(frame, 0, sizeof(*frame));
234
	frame->type = TYPE_A;
235
	frame->parameters.a.format = STANDARD_FRAME;
236
	frame->parameters.a.parity = PARITY;
237
	frame->parameters.a.last_bit = ISO14443A_LAST_BIT_NONE;
238
	frame->parameters.a.crc = CRC_UNCALCULATED;
239
	
240
	frame->numbytes = len;
241
}
242

    
243
int set_UID(u_int8_t *uid, size_t len)
244
{
245
	prepare_frame(&UID_FRAME, len+1);
246
	
247
	u_int8_t bcc = 0;
248
	unsigned int i;
249
	for(i=0; i<len; i++) {
250
		UID_FRAME.data[i] = uid[i];
251
		bcc ^= uid[i];
252
	}
253
	UID_FRAME.data[i] = bcc;
254
	UID_FRAME.state = FRAME_PREFILLED;
255
	memcpy(UID, uid, len);
256
	
257
	if(UID_BUFFER == NULL) {
258
		UID_BUFFER = alloc_buffer_for_frame(&UID_FRAME);
259
		if(UID_BUFFER == NULL) return -ENOMEM;
260
	}
261
	memset(UID_BUFFER->data, 0, UID_BUFFER->len);
262
	
263
	int ret = manchester_encode(UID_BUFFER->data,  UID_BUFFER->len,  &UID_FRAME);
264
	if(ret < 0) return ret;
265
	else UID_BUFFER->len = ret;
266
	return 0;
267
}
268

    
269
int get_UID(u_int8_t *uid, size_t len)
270
{
271
	if(len < 4 || len > 4) return -1;
272
	memcpy(uid, UID, len);
273
	return 0;
274
}
275

    
276
int set_nonce(u_int8_t *_nonce, size_t len)
277
{
278
	prepare_frame(&NONCE_FRAME, len);
279
	
280
	memcpy(&NONCE_FRAME.data, _nonce, len);
281
	NONCE_FRAME.state = FRAME_PREFILLED;
282
	memcpy(nonce, _nonce, len);
283
	
284
	if(NONCE_BUFFER == NULL) {
285
		NONCE_BUFFER = alloc_buffer_for_frame(&NONCE_FRAME);
286
		if(NONCE_BUFFER == NULL) return -ENOMEM;
287
	}
288
	memset(NONCE_BUFFER->data, 0, NONCE_BUFFER->len);
289
	
290
	int ret = manchester_encode(NONCE_BUFFER->data,  NONCE_BUFFER->len,  &NONCE_FRAME);
291
	if(ret < 0) return ret;
292
	else NONCE_BUFFER->len = ret;
293
	return 0;
294
}
295

    
296
int get_nonce(u_int8_t *_nonce, size_t len)
297
{
298
	if(len < 4 || len > 4) return -1;
299
	memcpy(_nonce, nonce, len);
300
	return 0;
301
}
302

    
303
void iso14443a_pretender (void *pvParameters)
304
{
305
	(void)pvParameters;
306
	int res;
307
	
308
	/* Delay until USB print etc. are ready */
309
	int i;
310
	for(i=0; i<=1000; i++) {
311
		vLedSetBrightness(LED_RED, i);
312
		vLedSetBrightness(LED_GREEN, i);
313
		vTaskDelay(1*portTICK_RATE_MS);
314
	}
315
	
316
	for(i=0; i<=1000; i+=4) {
317
		vLedSetBrightness(LED_GREEN, 1000-i);
318
		vTaskDelay(1*portTICK_RATE_MS);
319
	}
320
	
321
	int ret;
322
#define PREFILL_BUFFER(dst, src) dst = alloc_buffer_for_frame(&src); \
323
	if(dst == 0) goto prefill_failed; \
324
	ret = manchester_encode(dst->data,  dst->len,  &src); \
325
	if(ret < 0) goto prefill_failed; else dst->len = ret;
326
	
327
	PREFILL_BUFFER(ATQA_BUFFER,  ATQA_FRAME);
328
	//PREFILL_BUFFER(UID_BUFFER,   UID_FRAME);
329
	PREFILL_BUFFER(ATS_BUFFER,   ATS_FRAME);
330
	//PREFILL_BUFFER(NONCE_BUFFER, NONCE_FRAME);
331
	
332
	set_UID(UID, sizeof(UID));
333
	set_nonce(nonce, sizeof(nonce));
334
	
335
	if(0) {
336
prefill_failed:
337
		usb_print_string("Buffer prefilling failed\n\r");
338
		while(1) {
339
			for(i=1000; i<=3000; i++) {
340
				vLedSetBrightness(LED_GREEN, abs(1000-(i%2000)));
341
				vTaskDelay(1*portTICK_RATE_MS);
342
			}
343
		}
344
	}
345
	
346
	do {
347
		res = iso14443_layer2a_init(1);
348
		if(res < 0) {
349
			usb_print_string("Pretender: Initialization failed: -");
350
			DumpUIntToUSB(-res);
351
			usb_print_string("\n\r");
352
			for(i=0; i<=10000; i++) {
353
				vLedSetBrightness(LED_RED, abs(1000-(i%2000)));
354
				vTaskDelay(1*portTICK_RATE_MS);
355
			}
356
		}
357
	} while(res < 0);
358
	
359
	
360
	usb_print_string("Waiting for carrier. ");
361
	while(iso14443_wait_for_carrier(1000 * portTICK_RATE_MS) != 0) {
362
	}
363
	usb_print_string("Carrier detected.\n\r");
364
	
365
	for(i=0; i<=1000; i+=4) {
366
		vLedSetBrightness(LED_RED, 1000-i);
367
		vTaskDelay(1*portTICK_RATE_MS);
368
	}
369
	
370
	vTaskDelay(250*portTICK_RATE_MS);
371
	vLedSetGreen(0);
372
	vLedSetRed(0);
373
	
374
	int current_detected = 0, last_detected = 0;
375
	portTickType last_switched = 0;
376
#define DETECTED_14443A_3 1
377
#define DETECTED_14443A_4 2
378
#define DETECTED_MIFARE 4
379
	
380
	while(true) {
381
		iso14443_frame *frame = 0;
382
		res = iso14443_receive(fast_receive_callback, &frame, 1000 * portTICK_RATE_MS);
383
		if(res >= 0) {
384
			switch(BYTES_AND_BITS(frame->numbytes, frame->numbits) ) {
385
			case BYTES_AND_BITS(0, 7): /* REQA (7 bits) */
386
				current_detected |= DETECTED_14443A_3;
387
				break;
388
			case BYTES_AND_BITS(2, 0): /* ANTICOL (2 bytes) */
389
			case BYTES_AND_BITS(9, 0): /* SELECT (9 bytes) */
390
				current_detected |= DETECTED_14443A_3;
391
				break;
392
			case BYTES_AND_BITS(4, 0): /* AUTH1A (or any other four byte frame) */
393
			case BYTES_AND_BITS(8, 0): /* AUTH2 (8 bytes) */
394
				current_detected |= DETECTED_MIFARE;
395
				break;
396
			}
397
			
398
			portENTER_CRITICAL();
399
			frame->state = FRAME_FREE;
400
			portEXIT_CRITICAL();
401
		} else {
402
			if(res != -ETIMEDOUT) {
403
				usb_print_string("Receive error: ");
404
				switch(res) {
405
					case -ENETDOWN:   usb_print_string("PLL is not locked or PLL lock lost\n\r"); break;
406
					case -EBUSY:      usb_print_string("A Tx is currently running or pending, can't receive\n\r"); break;
407
					case -EALREADY:   usb_print_string("There's already an iso14443_receive() invocation running\n\r"); break;
408
				}
409
				vTaskDelay(1000 * portTICK_RATE_MS); // FIXME Proper error handling, e.g. wait for Tx end in case of EBUSY
410
			} else if(0) {
411
				DumpStringToUSB("\n\r");
412
				DumpTimeToUSB(xTaskGetTickCount());
413
				usb_print_string(": -- Mark --");
414
			}
415
		}
416
		
417
		if( last_switched < xTaskGetTickCount()-(1000*portTICK_RATE_MS) ) {
418
			last_detected = current_detected;
419
			current_detected = 0;
420
			last_switched = xTaskGetTickCount();
421
		}
422

    
423
#if 0
424
		if(last_detected & (DETECTED_14443A_3 | DETECTED_14443A_4 | DETECTED_MIFARE)) {
425
			if(last_detected & DETECTED_MIFARE) {
426
				vLedSetGreen(0);
427
				vLedSetRed(1);
428
			} else if(last_detected & DETECTED_14443A_4) {
429
				vLedSetGreen(1);
430
				vLedSetRed(0);
431
			} else {
432
				vLedSetGreen(1);
433
				vLedSetRed(1);
434
			}
435
		} else {
436
			vLedSetGreen(0);
437
			vLedSetRed(0);
438
		}
439
#endif
440
	}
441
}
(31-31/59)
Add picture from clipboard (Maximum size: 48.8 MB)