From 7cf3ef203cceb0d5caab8c01b87324080f0d8fd9 Mon Sep 17 00:00:00 2001 From: "martin.holst@gmail.com" Date: Sun, 1 Sep 2013 18:41:05 +0000 Subject: [PATCH] Patch by jonor for raw ISO 1444B commands. See http://www.proxmark.org/forum/viewtopic.php?id=1729 for more info --- armsrc/appmain.c | 7 ++- armsrc/apps.h | 5 +- armsrc/iso14443.c | 117 ++++++++++++++++++++++++++++------------------ client/cmdhf14b.c | 116 ++++++++++++++++++++++++++++++++++++++++++++- include/usb_cmd.h | 1 + 5 files changed, 193 insertions(+), 53 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index c1d4940d..4477a120 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -744,10 +744,10 @@ void UsbPacketReceived(uint8_t *packet, int len) AcquireRawAdcSamplesIso14443(c->arg[0]); break; case CMD_READ_SRI512_TAG: - ReadSRI512Iso14443(c->arg[0]); + ReadSTMemoryIso14443(0x0F); break; case CMD_READ_SRIX4K_TAG: - ReadSRIX4KIso14443(c->arg[0]); + ReadSTMemoryIso14443(0x7F); break; case CMD_SNOOP_ISO_14443: SnoopIso14443(); @@ -755,6 +755,9 @@ void UsbPacketReceived(uint8_t *packet, int len) case CMD_SIMULATE_TAG_ISO_14443: SimulateIso14443Tag(); break; + case CMD_ISO_14443B_COMMAND: + SendRawCommand14443B(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes); + break; #endif #ifdef WITH_ISO14443a diff --git a/armsrc/apps.h b/armsrc/apps.h index 394b0192..9574a937 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -135,10 +135,9 @@ void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode /// iso14443.h void SimulateIso14443Tag(void); void AcquireRawAdcSamplesIso14443(uint32_t parameter); -void ReadSRI512Iso14443(uint32_t parameter); -void ReadSRIX4KIso14443(uint32_t parameter); -void ReadSTMemoryIso14443(uint32_t parameter,uint32_t dwLast); +void ReadSTMemoryIso14443(uint32_t); void RAMFUNC SnoopIso14443(void); +void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]); /// iso14443a.h void RAMFUNC SnoopIso14443a(uint8_t param); diff --git a/armsrc/iso14443.c b/armsrc/iso14443.c index 9452ae83..ca06fc81 100644 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@ -537,7 +537,7 @@ static RAMFUNC int Handle14443SamplesDemod(int ci, int cq) if(Demod.posCount < 12) { Demod.state = DEMOD_UNSYNCD; } else { - LED_C_ON(); // Got SOF + LED_C_ON(); // Got SOF Demod.state = DEMOD_AWAITING_START_BIT; Demod.posCount = 0; Demod.len = 0; @@ -598,8 +598,8 @@ static RAMFUNC int Handle14443SamplesDemod(int ci, int cq) } else if(s == 0x000) { // This is EOF LED_C_OFF(); - return TRUE; Demod.state = DEMOD_UNSYNCD; + return TRUE; } else { Demod.state = DEMOD_UNSYNCD; } @@ -639,7 +639,7 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) int samples = 0; // Clear out the state of the "UART" that receives from the tag. - memset(BigBuf, 0x44, 400); + memset(BigBuf, 0x00, 400); Demod.output = (uint8_t *)BigBuf; Demod.len = 0; Demod.state = DEMOD_UNSYNCD; @@ -656,7 +656,7 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE); // Signal field is ON with the appropriate LED: - if (weTx) LED_D_ON(); else LED_D_OFF(); + if (weTx) LED_D_ON(); else LED_D_OFF(); // And put the FPGA in the appropriate mode FpgaWriteConfWord( FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | @@ -786,7 +786,7 @@ static void TransmitFor14443(void) // Code a layer 2 command (string of octets, including CRC) into ToSend[], // so that it is ready to transmit to the tag using TransmitFor14443(). //----------------------------------------------------------------------------- -void CodeIso14443bAsReader(const uint8_t *cmd, int len) +static void CodeIso14443bAsReader(const uint8_t *cmd, int len) { int i, j; uint8_t b; @@ -843,32 +843,14 @@ void CodeIso14443bAsReader(const uint8_t *cmd, int len) // responses. // The command name is misleading, it actually decodes the reponse in HEX // into the output buffer (read the result using hexsamples, not hisamples) +// +// obsolete function only for test //----------------------------------------------------------------------------- void AcquireRawAdcSamplesIso14443(uint32_t parameter) { uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; - // Make sure that we start from off, since the tags are stateful; - // confusing things will happen if we don't reset them between reads. - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_D_OFF(); - SpinDelay(200); - - SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - FpgaSetupSsc(); - - // Now give it time to spin up. - // Signal field is on with the appropriate LED - LED_D_ON(); - FpgaWriteConfWord( - FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); - SpinDelay(200); - - CodeIso14443bAsReader(cmd1, sizeof(cmd1)); - TransmitFor14443(); -// LED_A_ON(); - GetSamplesFor14443Demod(TRUE, 2000, FALSE); -// LED_A_OFF(); + SendRawCommand14443B(sizeof(cmd1),1,1,cmd1); } //----------------------------------------------------------------------------- @@ -880,16 +862,7 @@ void AcquireRawAdcSamplesIso14443(uint32_t parameter) // // I tried to be systematic and check every answer of the tag, every CRC, etc... //----------------------------------------------------------------------------- -void ReadSRI512Iso14443(uint32_t parameter) -{ - ReadSTMemoryIso14443(parameter,0x0F); -} -void ReadSRIX4KIso14443(uint32_t parameter) -{ - ReadSTMemoryIso14443(parameter,0x7F); -} - -void ReadSTMemoryIso14443(uint32_t parameter,uint32_t dwLast) +void ReadSTMemoryIso14443(uint32_t dwLast) { uint8_t i = 0x00; @@ -973,8 +946,8 @@ void ReadSTMemoryIso14443(uint32_t parameter,uint32_t dwLast) (Demod.output[7]<<24) + (Demod.output[6]<<16) + (Demod.output[5]<<8) + Demod.output[4], (Demod.output[3]<<24) + (Demod.output[2]<<16) + (Demod.output[1]<<8) + Demod.output[0]); - // Now loop to read all 16 blocks, address from 0 to 15 - DbpString("Tag memory dump, block 0 to 15"); + // Now loop to read all 16 blocks, address from 0 to last block + Dbprintf("Tag memory dump, block 0 to %d",dwLast); cmd1[0] = 0x08; i = 0x00; dwLast++; @@ -1072,13 +1045,12 @@ void RAMFUNC SnoopIso14443(void) Uart.byteCntMax = 100; Uart.state = STATE_UNSYNCD; - // Print some debug information about the buffer sizes - Dbprintf("Snooping buffers initialized:"); - Dbprintf(" Trace: %i bytes", DEMOD_TRACE_SIZE); - Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE); - Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE); - Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE); - + // Print some debug information about the buffer sizes + Dbprintf("Snooping buffers initialized:"); + Dbprintf(" Trace: %i bytes", DEMOD_TRACE_SIZE); + Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE); + Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE); + Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE); // And put the FPGA in the appropriate mode // Signal field is off with the appropriate LED @@ -1187,7 +1159,7 @@ void RAMFUNC SnoopIso14443(void) Demod.output = receivedResponse; Demod.state = DEMOD_UNSYNCD; } - WDT_HIT(); + WDT_HIT(); if(BUTTON_PRESS()) { DbpString("cancelled"); @@ -1207,3 +1179,56 @@ done: Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax); Dbprintf(" Trace length: %i", traceLen); } + +/* + * Send raw command to tag ISO14443B + * @Input + * datalen len of buffer data + * recv bool when true wait for data from tag and send to client + * powerfield bool leave the field on when true + * data buffer with byte to send + * + * @Output + * none + * + */ + +void SendRawCommand14443B(uint32_t datalen, uint32_t recv,uint8_t powerfield, uint8_t data[]) +{ + if(!powerfield) + { + // Make sure that we start from off, since the tags are stateful; + // confusing things will happen if we don't reset them between reads. + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + SpinDelay(200); + } + + if(!GETBIT(GPIO_LED_D)) + { + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); + FpgaSetupSsc(); + + // Now give it time to spin up. + // Signal field is on with the appropriate LED + LED_D_ON(); + FpgaWriteConfWord( + FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ); + SpinDelay(200); + } + + CodeIso14443bAsReader(data, datalen); + TransmitFor14443(); + if(recv) + { + uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE); + GetSamplesFor14443Demod(TRUE, 2000, TRUE); + cmd_send(CMD_ACK,iLen,0,0,Demod.output,iLen); + } + if(!powerfield) + { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + } +} + diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index f1238d22..83d6633c 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -21,6 +21,7 @@ #include "ui.h" #include "cmdparser.h" #include "cmdhf14b.h" +#include "cmdmain.h" static int CmdHelp(const char *Cmd); @@ -267,6 +268,116 @@ int CmdSrix4kRead(const char *Cmd) return 0; } +int CmdHF14BCmdRaw (const char *cmd) { + UsbCommand resp; + uint8_t *recv; + UsbCommand c = {CMD_ISO_14443B_COMMAND, {0, 0, 0}}; // len,recv? + uint8_t reply=1; + uint8_t crc=0; + uint8_t power=0; + char buf[5]=""; + int i=0; + uint8_t data[100]; + unsigned int datalen=0, temp; + char *hexout; + + if (strlen(cmd)<3) { + PrintAndLog("Usage: hf 14b raw [-r] [-c] [-p] <0A 0B 0C ... hex>"); + PrintAndLog(" -r do not read response"); + PrintAndLog(" -c calculate and append CRC"); + PrintAndLog(" -p leave the field on after receive"); + return 0; + } + + // strip + while (*cmd==' ' || *cmd=='\t') cmd++; + + while (cmd[i]!='\0') { + if (cmd[i]==' ' || cmd[i]=='\t') { i++; continue; } + if (cmd[i]=='-') { + switch (cmd[i+1]) { + case 'r': + case 'R': + reply=0; + break; + case 'c': + case 'C': + crc=1; + break; + case 'p': + case 'P': + power=1; + break; + default: + PrintAndLog("Invalid option"); + return 0; + } + i+=2; + continue; + } + if ((cmd[i]>='0' && cmd[i]<='9') || + (cmd[i]>='a' && cmd[i]<='f') || + (cmd[i]>='A' && cmd[i]<='F') ) { + buf[strlen(buf)+1]=0; + buf[strlen(buf)]=cmd[i]; + i++; + + if (strlen(buf)>=2) { + sscanf(buf,"%x",&temp); + data[datalen]=(uint8_t)(temp & 0xff); + datalen++; + *buf=0; + } + continue; + } + PrintAndLog("Invalid char on input"); + return 0; + } + if(crc) + { + uint8_t first, second; + ComputeCrc14443(CRC_14443_B, data, datalen, &first, &second); + data[datalen++] = first; + data[datalen++] = second; + } + + c.arg[0] = datalen; + c.arg[1] = reply; + c.arg[2] = power; + memcpy(c.d.asBytes,data,datalen); + + SendCommand(&c); + + if (reply) { + if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) { + recv = resp.d.asBytes; + PrintAndLog("received %i octets",resp.arg[0]); + if(!resp.arg[0]) + return 0; + hexout = (char *)malloc(resp.arg[0] * 3 + 1); + if (hexout != NULL) { + uint8_t first, second; + for (int i = 0; i < resp.arg[0]; i++) { // data in hex + sprintf(&hexout[i * 3], "%02hX ", recv[i]); + } + PrintAndLog("%s", hexout); + free(hexout); + ComputeCrc14443(CRC_14443_B, recv, resp.arg[0]-2, &first, &second); + if(recv[resp.arg[0]-2]==first && recv[resp.arg[0]-1]==second) { + PrintAndLog("CRC OK"); + } else { + PrintAndLog("CRC failed"); + } + } else { + PrintAndLog("malloc failed your client has low memory?"); + } + } else { + PrintAndLog("timeout while waiting for reply."); + } + } // if reply + return 0; +} + static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, @@ -276,8 +387,9 @@ static command_t CommandTable[] = {"sim", CmdHF14Sim, 0, "Fake ISO 14443 tag"}, {"simlisten", CmdHFSimlisten, 0, "Get HF samples as fake tag"}, {"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443"}, - {"sri512read", CmdSri512Read, 0, " -- Read contents of a SRI512 tag"}, - {"srix4kread", CmdSrix4kRead, 0, " -- Read contents of a SRIX4K tag"}, + {"sri512read", CmdSri512Read, 0, "Read contents of a SRI512 tag"}, + {"srix4kread", CmdSrix4kRead, 0, "Read contents of a SRIX4K tag"}, + {"raw", CmdHF14BCmdRaw, 0, "Send raw hex data to tag"}, {NULL, NULL, 0, NULL} }; diff --git a/include/usb_cmd.h b/include/usb_cmd.h index eec849b8..8726ec67 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -86,6 +86,7 @@ typedef struct { #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443 0x0301 #define CMD_READ_SRI512_TAG 0x0303 #define CMD_READ_SRIX4K_TAG 0x0304 +#define CMD_ISO_14443B_COMMAND 0x0305 #define CMD_READER_ISO_15693 0x0310 #define CMD_SIMTAG_ISO_15693 0x0311 #define CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 0x0312 -- 2.39.5