//
//-----------------------------------------------------------------------------
-#include "proxmark3.h"
+#include "../include/proxmark3.h"
#include "apps.h"
#include "util.h"
#include "string.h"
// Needed for CRC in emulation mode;
// same construction as in ISO 14443;
// different initial value (CRC_ICLASS)
-#include "iso14443crc.h"
-#include "iso15693tools.h"
+#include "../common/iso14443crc.h"
+#include "../common/iso15693tools.h"
+//#include "iso15693tools.h"
+
static int timeout = 4096;
SUB_SECOND_HALF,
SUB_BOTH
} sub;
- uint8_t *output;
+ uint8_t *output;
} Demod;
static RAMFUNC int ManchesterDecoding(int v)
// The command (reader -> tag) that we're receiving.
// The length of a received command will in most cases be no more than 18 bytes.
// So 32 should be enough!
- uint8_t *readerToTagCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
+ #define ICLASS_BUFFER_SIZE 32
+ uint8_t readerToTagCmd[ICLASS_BUFFER_SIZE];
// The response (tag -> reader) that we're receiving.
- uint8_t *tagToReaderResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
+ uint8_t tagToReaderResponse[ICLASS_BUFFER_SIZE];
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
- // reset traceLen to 0
- iso14a_set_tracing(TRUE);
- iso14a_clear_trace();
+ // free all BigBuf memory
+ BigBuf_free();
+ // The DMA buffer, used to stream samples from the FPGA
+ uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
+
+ set_tracing(TRUE);
+ clear_trace();
iso14a_set_trigger(FALSE);
- // The DMA buffer, used to stream samples from the FPGA
- int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET;
int lastRxCounter;
- int8_t *upTo;
+ uint8_t *upTo;
int smpl;
int maxBehindBy = 0;
(DMA_BUFFER_SIZE-1);
if(behindBy > maxBehindBy) {
maxBehindBy = behindBy;
- if(behindBy > 400) {
+ if(behindBy > (9 * DMA_BUFFER_SIZE / 10)) {
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
goto done;
}
if(ManchesterDecoding(smpl & 0x0F)) {
time_stop = (GetCountSspClk()-time_0) << 4;
- rsamples = samples - Demod.samples;
+ rsamples = samples - Demod.samples;
LED_B_ON();
if(tracing) {
DbpString("COMMAND FINISHED");
Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);
- Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
+ Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]);
done:
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);
- Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
+ Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]);
LED_A_OFF();
LED_B_OFF();
LED_C_OFF();
* - A 1-bit input to the FPGA becomes 8 pulses on 423.5kHz (fc/32) (18.88us).
* - A 0-bit inptu to the FPGA becomes an unmodulated time of 18.88us
*
- * In thist mode the SOF can be written as 00011101 = 0x1D
+ * In this mode the SOF can be written as 00011101 = 0x1D
* The EOF can be written as 10111000 = 0xb8
* A logic 1 is 01
* A logic 0 is 10
uint8_t b = cmd[i];
ToSend[++ToSendMax] = encode4Bits(b & 0xF); //Least significant half
ToSend[++ToSendMax] = encode4Bits((b >>4) & 0xF);//Most significant half
- }
+ }
// Send EOF
ToSend[++ToSendMax] = 0xB8;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Enable and clear the trace
- iso14a_set_tracing(TRUE);
- iso14a_clear_trace();
+ set_tracing(TRUE);
+ clear_trace();
uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 };
if(simType == 0) {
else if(simType == 2)
{
- uint8_t mac_responses[64] = { 0 };
+ uint8_t mac_responses[USB_CMD_DATA_SIZE] = { 0 };
Dbprintf("Going into attack mode, %d CSNS sent", numberOfCSNS);
// In this mode, a number of csns are within datain. We'll simulate each one, one at a time
// in order to collect MAC's from the reader. This can later be used in an offlne-attack
int trace_data_size = 0;
//uint8_t sof = 0x0f;
+ // free eventually allocated BigBuf memory
+ BigBuf_free();
// Respond SOF -- takes 1 bytes
- uint8_t *resp1 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);
+ uint8_t *resp1 = BigBuf_malloc(2);
int resp1Len;
// Anticollision CSN (rotated CSN)
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
- uint8_t *resp2 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + 2);
+ uint8_t *resp2 = BigBuf_malloc(28);
int resp2Len;
// CSN
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
- uint8_t *resp3 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + 30);
+ uint8_t *resp3 = BigBuf_malloc(30);
int resp3Len;
// e-Purse
- // 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/byte)
- uint8_t *resp4 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + 60);
+ // 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/bit)
+ uint8_t *resp4 = BigBuf_malloc(20);
int resp4Len;
- // + 1720..
- uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
+ uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
memset(receivedCmd, 0x44, MAX_FRAME_SIZE);
int len;
cmdsRecvd++;
}
/**
- After changes to parity calculation
- Time between reader EOT and pm3 SOF
- delay 21 -> 480uS
- delay 10 -> 220us
- delay 16 -> 388us
- A legit tag has about 380us.
+ A legit tag has about 380us delay between reader EOT and tag SOF.
**/
if(modulated_response_size > 0) {
SendIClassAnswer(modulated_response, modulated_response_size, 1);
//Dbprintf("%x", cmdsRecvd);
LED_A_OFF();
LED_B_OFF();
+ LED_C_OFF();
+
if(buttonPressed)
{
DbpString("Button pressed");
{
if(*wait < 10) *wait = 10;
- for(c = 0; c < *wait;) {
- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
- AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing!
- c++;
- }
- if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
- volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
- (void)r;
- }
- WDT_HIT();
- }
+ for(c = 0; c < *wait;) {
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
+ AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing!
+ c++;
+ }
+ if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
+ volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
+ (void)r;
+ }
+ WDT_HIT();
+ }
}
void ReaderTransmitIClass(uint8_t* frame, int len)
{
- int wait = 0;
- int samples = 0;
+ int wait = 0;
+ int samples = 0;
- // This is tied to other size changes
- CodeIClassCommand(frame,len);
+ // This is tied to other size changes
+ CodeIClassCommand(frame,len);
- // Select the card
- TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait);
- if(trigger)
- LED_A_ON();
+ // Select the card
+ TransmitIClassCommand(ToSend, ToSendMax, &samples, &wait);
+ if(trigger)
+ LED_A_ON();
- // Store reader command in buffer
+ // Store reader command in buffer
if (tracing) {
uint8_t par[MAX_PARITY_SIZE];
GetParity(frame, len, par);
for(;;) {
WDT_HIT();
- if(BUTTON_PRESS()) return FALSE;
+ if(BUTTON_PRESS()) return FALSE;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x00; // To make use of exact timing of next command from reader!!
{
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Reset trace buffer
- iso14a_set_tracing(TRUE);
- iso14a_clear_trace();
+ set_tracing(TRUE);
+ clear_trace();
// Setup SSC
FpgaSetupSsc();
static uint8_t identify[] = { 0x0c };
static uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static uint8_t readcheck_cc[]= { 0x88, 0x02 };
- uint8_t *resp = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
+ uint8_t resp[ICLASS_BUFFER_SIZE];
uint8_t read_status = 0;
int read_status= 0;
bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
bool get_cc = arg0 & FLAG_ICLASS_READER_GET_CC;
-
+ set_tracing(TRUE);
setupIclassReader();
size_t datasize = 0;
while(!BUTTON_PRESS())
{
- if(traceLen > TRACE_SIZE) {
+ if(!tracing) {
DbpString("Trace full");
break;
}
if(read_status == 1) datasize = 8;
if(read_status == 2) datasize = 16;
- LED_B_ON();
- //Send back to client, but don't bother if we already sent this
- if(memcmp(last_csn, card_data, 8) != 0)
+ LED_B_ON();
+ //Send back to client, but don't bother if we already sent this
+ if(memcmp(last_csn, card_data, 8) != 0)
{
if(!get_cc || (get_cc && read_status == 2))
{
- cmd_send(CMD_ACK,read_status,0,0,card_data,datasize);
+ cmd_send(CMD_ACK,read_status,0,0,card_data,datasize);
if(abort_after_read) {
LED_A_OFF();
return;
}
- //Save that we already sent this....
- memcpy(last_csn, card_data, 8);
+ //Save that we already sent this....
+ memcpy(last_csn, card_data, 8);
}
//If 'get_cc' was specified and we didn't get a CC, we'll just keep trying...
}
int keyaccess;
} memory;
- uint8_t* resp = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
+ uint8_t resp[ICLASS_BUFFER_SIZE];
setupIclassReader();
-
+ set_tracing(TRUE);
while(!BUTTON_PRESS()) {
WDT_HIT();
- if(traceLen > TRACE_SIZE) {
+ if(!tracing) {
DbpString("Trace full");
break;
}
uint8_t read_status = handshakeIclassTag(card_data);
if(read_status < 2) continue;
- //for now replay captured auth (as cc not updated)
- memcpy(check+5,MAC,4);
+ //for now replay captured auth (as cc not updated)
+ memcpy(check+5,MAC,4);
if(sendCmdGetResponseWithRetries(check, sizeof(check),resp, 4, 5))
{
- Dbprintf("Error: Authentication Fail!");
+ Dbprintf("Error: Authentication Fail!");
continue;
- }
+ }
//first get configuration block (block 1)
crc = block_crc_LUT[1];
- read[1]=1;
- read[2] = crc >> 8;
- read[3] = crc & 0xff;
+ read[1]=1;
+ read[2] = crc >> 8;
+ read[3] = crc & 0xff;
if(sendCmdGetResponseWithRetries(read, sizeof(read),resp, 10, 10))
{
continue;
}
- mem=resp[5];
- memory.k16= (mem & 0x80);
- memory.book= (mem & 0x20);
- memory.k2= (mem & 0x8);
- memory.lockauth= (mem & 0x2);
- memory.keyaccess= (mem & 0x1);
+ mem=resp[5];
+ memory.k16= (mem & 0x80);
+ memory.book= (mem & 0x20);
+ memory.k2= (mem & 0x8);
+ memory.lockauth= (mem & 0x2);
+ memory.keyaccess= (mem & 0x1);
cardsize = memory.k16 ? 255 : 32;
WDT_HIT();
memset(card_data,0x0,USB_CMD_DATA_SIZE);
uint8_t failedRead =0;
uint8_t stored_data_length =0;
- //then loop around remaining blocks
+ //then loop around remaining blocks
for(int block=0; block < cardsize; block++){
read[1]= block;
crc = block_crc_LUT[block];
- read[2] = crc >> 8;
- read[3] = crc & 0xff;
+ read[2] = crc >> 8;
+ read[3] = crc & 0xff;
if(!sendCmdGetResponseWithRetries(read, sizeof(read), resp, 10, 10))
{
- Dbprintf(" %02x: %02x %02x %02x %02x %02x %02x %02x %02x",
+ Dbprintf(" %02x: %02x %02x %02x %02x %02x %02x %02x %02x",
block, resp[0], resp[1], resp[2],
- resp[3], resp[4], resp[5],
- resp[6], resp[7]);
+ resp[3], resp[4], resp[5],
+ resp[6], resp[7]);
//Fill up the buffer
memcpy(card_data+stored_data_length,resp,8);
uint8_t* resp = (((uint8_t *)BigBuf) + 3560);
// Reset trace buffer
- memset(trace, 0x44, RECV_CMD_OFFSET);
+ memset(trace, 0x44, RECV_CMD_OFFSET);
traceLen = 0;
// Setup SSC