diff options
author | henryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1> | 2008-03-17 19:43:56 +0000 |
---|---|---|
committer | henryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1> | 2008-03-17 19:43:56 +0000 |
commit | 00488946bbaca6575b5a36afd56d8a3b75b7bb43 (patch) | |
tree | 420f86234048bfea0cffa2e656a6e28ae3d8915e /openpicc/application/iso14443a_pretender.c | |
parent | a18b831b839da7c22eb31d3116038ffc8637e3d5 (diff) |
Add dynamic UID, nonce encoding on the fly
git-svn-id: https://svn.openpcd.org:2342/trunk@462 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
Diffstat (limited to 'openpicc/application/iso14443a_pretender.c')
-rw-r--r-- | openpicc/application/iso14443a_pretender.c | 115 |
1 files changed, 90 insertions, 25 deletions
diff --git a/openpicc/application/iso14443a_pretender.c b/openpicc/application/iso14443a_pretender.c index c6f54cc..f4337fc 100644 --- a/openpicc/application/iso14443a_pretender.c +++ b/openpicc/application/iso14443a_pretender.c @@ -50,15 +50,8 @@ static const iso14443_frame ATQA_FRAME = { {} }; -static const iso14443_frame UID_FRAME = { - TYPE_A, - FRAME_PREFILLED, - {{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}}, - 5, - 0, 0, - {0xF4, 0xAC, 0xF9, 0xD7, 0x76}, - {} -}; +static iso14443_frame UID_FRAME; +static u_int8_t UID[] = {0xF4, 0xAC, 0xF9, 0xD7}; //, 0x76 static const iso14443_frame ATS_FRAME = { TYPE_A, @@ -76,7 +69,7 @@ static const iso14443_frame NONCE_FRAME = { {{STANDARD_FRAME, PARITY, ISO14443A_LAST_BIT_NONE, CRC_UNCALCULATED}}, 4, 0, 0, - {0xFF, 0xCF, 0x80, 0xE3}, + {0, 0, 0, 0}, {} }; @@ -108,20 +101,40 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, iso14443_frame *f break; } - switch(BYTES_AND_BITS(frame->numbytes,frame->numbits)) { - case BYTES_AND_BITS(0, 7): /* REQA (7 bits) */ - tx_buffer = &ATQA_BUFFER; - fdt += 9*128; - break; - case BYTES_AND_BITS(2, 0): /* ANTICOL (2 bytes) */ - tx_buffer = &UID_BUFFER; - fdt += 9*128; - break; - case BYTES_AND_BITS(9, 0): /* SELECT (9 bytes) */ - tx_buffer = &ATS_BUFFER; - fdt += 9*128; - break; - } + + if(cv < 870) /* Anticollision is time-critical, do not even try to send if we're too late anyway */ + switch(BYTES_AND_BITS(frame->numbytes,frame->numbits)) { + case BYTES_AND_BITS(0, 7): /* REQA (7 bits) */ + tx_buffer = &ATQA_BUFFER; + fdt += 9*128; + break; + case BYTES_AND_BITS(2, 0): /* ANTICOL (2 bytes) */ + tx_buffer = &UID_BUFFER; + fdt += 9*128; + break; + case BYTES_AND_BITS(9, 0): /* SELECT (9 bytes) */ + tx_buffer = &ATS_BUFFER; + fdt += 9*128; + break; + } + + if(tx_buffer == NULL) + switch(BYTES_AND_BITS(frame->numbytes, frame->numbits)) { + case BYTES_AND_BITS(4, 0): + if( (frame->data[0] & 0xfe) == 0x60 && frame->parameters.a.crc) { + /* AUTH1A or AUTH1B */ + int ret = manchester_encode(NONCE_BUFFER.data, sizeof(NONCE_BUFFER.data), &NONCE_FRAME); + if(ret < 0) { + } else { + NONCE_BUFFER.len = ret; + tx_buffer = &NONCE_BUFFER; + } + + /*fdt += ((cv / 128) + 10) * 128;*/ + fdt += 50*128; /* 52 ok, 26 not, 39 not, 45 not, 48 not, 50 ok, 49 not */ + } + break; + } /* Add some extra room to the fdt for testing */ //fdt += 3*128; @@ -135,6 +148,8 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, iso14443_frame *f } u_int32_t cv2 = *AT91C_TC2_CV; + usb_print_string_f("\r\n",0); + if(tx_buffer == &NONCE_BUFFER) usb_print_string_f("---> ",0); int old=usb_print_set_default_flush(0); DumpUIntToUSB(cv); DumpStringToUSB(":"); @@ -144,9 +159,57 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, iso14443_frame *f DumpUIntToUSB(buffy); } usb_print_set_default_flush(old); + + switch(BYTES_AND_BITS(frame->numbytes,frame->numbits)) { + case BYTES_AND_BITS(4, 0): + if(frame->parameters.a.crc && frame->data[0] == 0x50 && frame->data[1] == 0x00) { + /* HLTA */ + UID[3]++; + if(UID[3]==0) { + UID[2]++; + if(UID[2]==0) { + UID[1]++; + if(UID[1]==0) { + UID[0]++; + } + } + } + set_UID(UID, sizeof(UID)); + } + break; + } + usb_print_string_f("%", 0); } +int set_UID(u_int8_t *uid, size_t len) +{ + memset(&UID_FRAME, 0, sizeof(UID_FRAME)); + memset(&UID_BUFFER, 0, sizeof(UID_BUFFER)); + + UID_FRAME.type = TYPE_A; + UID_FRAME.parameters.a.format = STANDARD_FRAME; + UID_FRAME.parameters.a.parity = PARITY; + UID_FRAME.parameters.a.last_bit = ISO14443A_LAST_BIT_NONE; + UID_FRAME.parameters.a.crc = CRC_UNCALCULATED; + + UID_FRAME.numbytes = len+1; + + u_int8_t bcc = 0; + unsigned int i; + for(i=0; i<len; i++) { + UID_FRAME.data[i] = uid[i]; + bcc ^= uid[i]; + } + UID_FRAME.data[i] = bcc; + UID_FRAME.state = FRAME_PREFILLED; + + int ret = manchester_encode(UID_BUFFER.data, sizeof(UID_BUFFER.data), &UID_FRAME); + if(ret < 0) return ret; + else UID_BUFFER.len = ret; + return 0; +} + void iso14443a_pretender (void *pvParameters) { (void)pvParameters; @@ -170,10 +233,12 @@ void iso14443a_pretender (void *pvParameters) if(ret < 0) goto prefill_failed; else dst.len = ret; PREFILL_BUFFER(ATQA_BUFFER, ATQA_FRAME); - PREFILL_BUFFER(UID_BUFFER, UID_FRAME); + //PREFILL_BUFFER(UID_BUFFER, UID_FRAME); PREFILL_BUFFER(ATS_BUFFER, ATS_FRAME); PREFILL_BUFFER(NONCE_BUFFER, NONCE_FRAME); + set_UID(UID, sizeof(UID)); + if(0) { prefill_failed: usb_print_string("Buffer prefilling failed\n\r"); |