summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openpicc/application/iso14443a_pretender.c66
1 files changed, 46 insertions, 20 deletions
diff --git a/openpicc/application/iso14443a_pretender.c b/openpicc/application/iso14443a_pretender.c
index 917ab47..9d5d87f 100644
--- a/openpicc/application/iso14443a_pretender.c
+++ b/openpicc/application/iso14443a_pretender.c
@@ -79,10 +79,19 @@ static u_int8_t UID[] = {0x00, 0x00, 0x00, 0x00};
static u_int8_t nonce[] = {0x00, 0x00, 0x00, 0x00};
#define FRAME_SIZE(bytes) (2* (1+(9*bytes)+1) )
-#define SIZED_BUFFER(bytes) struct { int len; u_int8_t data[FRAME_SIZE(bytes)]; }
#define BYTES_AND_BITS(bytes,bits) (bytes*9+bits)
+#define GET_BASE_SIZE(type) ((size_t) &(((type*)0)->data))
-static ssc_dma_tx_buffer_t ATQA_BUFFER, UID_BUFFER, ATS_BUFFER, NONCE_BUFFER;
+static ssc_dma_tx_buffer_t *ATQA_BUFFER, *UID_BUFFER, *ATS_BUFFER, *NONCE_BUFFER;
+
+static ssc_dma_tx_buffer_t *alloc_buffer_for_frame(const iso14443_frame *frame)
+{
+ int datalen = FRAME_SIZE( BYTES_AND_BITS(frame->numbytes, frame->numbits) );
+ ssc_dma_tx_buffer_t *dst = pvPortMalloc( GET_BASE_SIZE(typeof(*dst)) + datalen );
+ if(dst == NULL) return NULL;
+ dst->len = datalen;
+ return dst;
+}
static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, iso14443_frame *frame, u_int8_t in_irq)
{
@@ -109,18 +118,18 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, iso14443_frame *f
switch(BYTES_AND_BITS(frame->numbytes,frame->numbits)) {
case BYTES_AND_BITS(0, 7): /* REQA or WUPA (7 bits) */
if(frame->data[0] == 0x26 || frame->data[0] == 0x52)
- tx_buffer = &ATQA_BUFFER;
+ tx_buffer = ATQA_BUFFER;
fdt += 9*128;
break;
case BYTES_AND_BITS(2, 0): /* ANTICOL (2 bytes) */
if(frame->data[0] == 0x93 && frame->data[1] == 0x20)
- tx_buffer = &UID_BUFFER;
+ tx_buffer = UID_BUFFER;
fdt += 9*128;
break;
case BYTES_AND_BITS(9, 0): /* SELECT (9 bytes) */
if(frame->data[0] == 0x93 && frame->data[1] == 0x70 && frame->parameters.a.crc &&
( *((u_int32_t*)&frame->data[2]) == *((u_int32_t*)&UID) ) )
- tx_buffer = &ATS_BUFFER;
+ tx_buffer = ATS_BUFFER;
fdt += 9*128;
break;
}
@@ -130,11 +139,16 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, iso14443_frame *f
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;
+ if(NONCE_BUFFER == NULL) {
+ NONCE_BUFFER = alloc_buffer_for_frame(&NONCE_FRAME);
+ }
+ if(NONCE_BUFFER != NULL) {
+ int ret = manchester_encode(NONCE_BUFFER->data, NONCE_BUFFER->len, &NONCE_FRAME);
+ if(ret < 0) {
+ } else {
+ NONCE_BUFFER->len = ret;
+ tx_buffer = NONCE_BUFFER;
+ }
}
/*fdt += ((cv / 128) + 10) * 128;*/
@@ -185,10 +199,10 @@ static void fast_receive_callback(ssc_dma_rx_buffer_t *buffer, iso14443_frame *f
}
if(tx_buffer) usb_print_string_f("\r\n",0);
- if(tx_buffer == &UID_BUFFER) {
+ if(tx_buffer == UID_BUFFER) {
memcpy(&challenge_response.UID, UID_FRAME.data, 5);
usb_print_string_f("uid", 0);
- } else if(tx_buffer == &NONCE_BUFFER) {
+ } else if(tx_buffer == NONCE_BUFFER) {
memcpy(&challenge_response.nonce, NONCE_FRAME.data, 4);
challenge_response.waiting_for_response = 1;
usb_print_string_f("nonce", 0);
@@ -240,10 +254,15 @@ int set_UID(u_int8_t *uid, size_t len)
UID_FRAME.state = FRAME_PREFILLED;
memcpy(UID, uid, len);
- memset(&UID_BUFFER, 0, sizeof(UID_BUFFER));
- int ret = manchester_encode(UID_BUFFER.data, sizeof(UID_BUFFER.data), &UID_FRAME);
+ if(UID_BUFFER == NULL) {
+ UID_BUFFER = alloc_buffer_for_frame(&UID_FRAME);
+ if(UID_BUFFER == NULL) return -ENOMEM;
+ }
+ memset(UID_BUFFER->data, 0, UID_BUFFER->len);
+
+ int ret = manchester_encode(UID_BUFFER->data, UID_BUFFER->len, &UID_FRAME);
if(ret < 0) return ret;
- else UID_BUFFER.len = ret;
+ else UID_BUFFER->len = ret;
return 0;
}
@@ -262,10 +281,15 @@ int set_nonce(u_int8_t *_nonce, size_t len)
NONCE_FRAME.state = FRAME_PREFILLED;
memcpy(nonce, _nonce, len);
- memset(&NONCE_BUFFER, 0, sizeof(NONCE_BUFFER));
- int ret = manchester_encode(NONCE_BUFFER.data, sizeof(NONCE_BUFFER.data), &NONCE_FRAME);
+ if(NONCE_BUFFER == NULL) {
+ NONCE_BUFFER = alloc_buffer_for_frame(&NONCE_FRAME);
+ if(NONCE_BUFFER == NULL) return -ENOMEM;
+ }
+ memset(NONCE_BUFFER->data, 0, NONCE_BUFFER->len);
+
+ int ret = manchester_encode(NONCE_BUFFER->data, NONCE_BUFFER->len, &NONCE_FRAME);
if(ret < 0) return ret;
- else NONCE_BUFFER.len = ret;
+ else NONCE_BUFFER->len = ret;
return 0;
}
@@ -295,8 +319,10 @@ void iso14443a_pretender (void *pvParameters)
}
int ret;
-#define PREFILL_BUFFER(dst, src) ret = manchester_encode(dst.data, sizeof(dst.data), &src); \
- if(ret < 0) goto prefill_failed; else dst.len = ret;
+#define PREFILL_BUFFER(dst, src) dst = alloc_buffer_for_frame(&src); \
+ if(dst == 0) goto prefill_failed; \
+ ret = manchester_encode(dst->data, dst->len, &src); \
+ if(ret < 0) goto prefill_failed; else dst->len = ret;
PREFILL_BUFFER(ATQA_BUFFER, ATQA_FRAME);
//PREFILL_BUFFER(UID_BUFFER, UID_FRAME);
personal git repositories of Harald Welte. Your mileage may vary