summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhenryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2008-03-17 19:43:56 +0000
committerhenryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2008-03-17 19:43:56 +0000
commit00488946bbaca6575b5a36afd56d8a3b75b7bb43 (patch)
tree420f86234048bfea0cffa2e656a6e28ae3d8915e
parenta18b831b839da7c22eb31d3116038ffc8637e3d5 (diff)
Add dynamic UID, nonce encoding on the fly
git-svn-id: https://svn.openpcd.org:2342/trunk@462 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
-rw-r--r--openpicc/application/iso14443a_pretender.c115
-rw-r--r--openpicc/application/iso14443a_pretender.h3
2 files changed, 92 insertions, 26 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");
diff --git a/openpicc/application/iso14443a_pretender.h b/openpicc/application/iso14443a_pretender.h
index 675a2e6..0d7042b 100644
--- a/openpicc/application/iso14443a_pretender.h
+++ b/openpicc/application/iso14443a_pretender.h
@@ -1,6 +1,7 @@
#ifndef ISO14443A_PRETENDER_H_
#define ISO14443A_PRETENDER_H_
-void iso14443a_pretender (void *pvParameters);
+extern void iso14443a_pretender (void *pvParameters);
+extern int set_UID(u_int8_t *uid, size_t len);
#endif /*ISO14443A_PRETENDER_H_*/
personal git repositories of Harald Welte. Your mileage may vary