Patch by jonor for raw ISO 1444B commands. See http://www.proxmark.org/forum/viewtopic.php?id=1729 for more info

This commit is contained in:
martin.holst@gmail.com 2013-09-01 18:41:05 +00:00
parent a763eb2126
commit 7cf3ef203c
5 changed files with 193 additions and 53 deletions

View file

@ -744,10 +744,10 @@ void UsbPacketReceived(uint8_t *packet, int len)
AcquireRawAdcSamplesIso14443(c->arg[0]); AcquireRawAdcSamplesIso14443(c->arg[0]);
break; break;
case CMD_READ_SRI512_TAG: case CMD_READ_SRI512_TAG:
ReadSRI512Iso14443(c->arg[0]); ReadSTMemoryIso14443(0x0F);
break; break;
case CMD_READ_SRIX4K_TAG: case CMD_READ_SRIX4K_TAG:
ReadSRIX4KIso14443(c->arg[0]); ReadSTMemoryIso14443(0x7F);
break; break;
case CMD_SNOOP_ISO_14443: case CMD_SNOOP_ISO_14443:
SnoopIso14443(); SnoopIso14443();
@ -755,6 +755,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
case CMD_SIMULATE_TAG_ISO_14443: case CMD_SIMULATE_TAG_ISO_14443:
SimulateIso14443Tag(); SimulateIso14443Tag();
break; break;
case CMD_ISO_14443B_COMMAND:
SendRawCommand14443B(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
break;
#endif #endif
#ifdef WITH_ISO14443a #ifdef WITH_ISO14443a

View file

@ -135,10 +135,9 @@ void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode
/// iso14443.h /// iso14443.h
void SimulateIso14443Tag(void); void SimulateIso14443Tag(void);
void AcquireRawAdcSamplesIso14443(uint32_t parameter); void AcquireRawAdcSamplesIso14443(uint32_t parameter);
void ReadSRI512Iso14443(uint32_t parameter); void ReadSTMemoryIso14443(uint32_t);
void ReadSRIX4KIso14443(uint32_t parameter);
void ReadSTMemoryIso14443(uint32_t parameter,uint32_t dwLast);
void RAMFUNC SnoopIso14443(void); void RAMFUNC SnoopIso14443(void);
void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]);
/// iso14443a.h /// iso14443a.h
void RAMFUNC SnoopIso14443a(uint8_t param); void RAMFUNC SnoopIso14443a(uint8_t param);

View file

@ -537,7 +537,7 @@ static RAMFUNC int Handle14443SamplesDemod(int ci, int cq)
if(Demod.posCount < 12) { if(Demod.posCount < 12) {
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_UNSYNCD;
} else { } else {
LED_C_ON(); // Got SOF LED_C_ON(); // Got SOF
Demod.state = DEMOD_AWAITING_START_BIT; Demod.state = DEMOD_AWAITING_START_BIT;
Demod.posCount = 0; Demod.posCount = 0;
Demod.len = 0; Demod.len = 0;
@ -598,8 +598,8 @@ static RAMFUNC int Handle14443SamplesDemod(int ci, int cq)
} else if(s == 0x000) { } else if(s == 0x000) {
// This is EOF // This is EOF
LED_C_OFF(); LED_C_OFF();
return TRUE;
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_UNSYNCD;
return TRUE;
} else { } else {
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_UNSYNCD;
} }
@ -639,7 +639,7 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet)
int samples = 0; int samples = 0;
// Clear out the state of the "UART" that receives from the tag. // 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.output = (uint8_t *)BigBuf;
Demod.len = 0; Demod.len = 0;
Demod.state = DEMOD_UNSYNCD; 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); FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE);
// Signal field is ON with the appropriate LED: // 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 // And put the FPGA in the appropriate mode
FpgaWriteConfWord( FpgaWriteConfWord(
FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | 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[], // Code a layer 2 command (string of octets, including CRC) into ToSend[],
// so that it is ready to transmit to the tag using TransmitFor14443(). // 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; int i, j;
uint8_t b; uint8_t b;
@ -843,32 +843,14 @@ void CodeIso14443bAsReader(const uint8_t *cmd, int len)
// responses. // responses.
// The command name is misleading, it actually decodes the reponse in HEX // The command name is misleading, it actually decodes the reponse in HEX
// into the output buffer (read the result using hexsamples, not hisamples) // into the output buffer (read the result using hexsamples, not hisamples)
//
// obsolete function only for test
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void AcquireRawAdcSamplesIso14443(uint32_t parameter) void AcquireRawAdcSamplesIso14443(uint32_t parameter)
{ {
uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
// Make sure that we start from off, since the tags are stateful; SendRawCommand14443B(sizeof(cmd1),1,1,cmd1);
// 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();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -880,16 +862,7 @@ void AcquireRawAdcSamplesIso14443(uint32_t parameter)
// //
// I tried to be systematic and check every answer of the tag, every CRC, etc... // I tried to be systematic and check every answer of the tag, every CRC, etc...
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void ReadSRI512Iso14443(uint32_t parameter) void ReadSTMemoryIso14443(uint32_t dwLast)
{
ReadSTMemoryIso14443(parameter,0x0F);
}
void ReadSRIX4KIso14443(uint32_t parameter)
{
ReadSTMemoryIso14443(parameter,0x7F);
}
void ReadSTMemoryIso14443(uint32_t parameter,uint32_t dwLast)
{ {
uint8_t i = 0x00; 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[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]); (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 // Now loop to read all 16 blocks, address from 0 to last block
DbpString("Tag memory dump, block 0 to 15"); Dbprintf("Tag memory dump, block 0 to %d",dwLast);
cmd1[0] = 0x08; cmd1[0] = 0x08;
i = 0x00; i = 0x00;
dwLast++; dwLast++;
@ -1072,13 +1045,12 @@ void RAMFUNC SnoopIso14443(void)
Uart.byteCntMax = 100; Uart.byteCntMax = 100;
Uart.state = STATE_UNSYNCD; Uart.state = STATE_UNSYNCD;
// Print some debug information about the buffer sizes // Print some debug information about the buffer sizes
Dbprintf("Snooping buffers initialized:"); Dbprintf("Snooping buffers initialized:");
Dbprintf(" Trace: %i bytes", DEMOD_TRACE_SIZE); Dbprintf(" Trace: %i bytes", DEMOD_TRACE_SIZE);
Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE); Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE);
Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE); Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE);
Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE); Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE);
// And put the FPGA in the appropriate mode // And put the FPGA in the appropriate mode
// Signal field is off with the appropriate LED // Signal field is off with the appropriate LED
@ -1187,7 +1159,7 @@ void RAMFUNC SnoopIso14443(void)
Demod.output = receivedResponse; Demod.output = receivedResponse;
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_UNSYNCD;
} }
WDT_HIT(); WDT_HIT();
if(BUTTON_PRESS()) { if(BUTTON_PRESS()) {
DbpString("cancelled"); DbpString("cancelled");
@ -1207,3 +1179,56 @@ done:
Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax); Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax);
Dbprintf(" Trace length: %i", traceLen); 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();
}
}

View file

@ -21,6 +21,7 @@
#include "ui.h" #include "ui.h"
#include "cmdparser.h" #include "cmdparser.h"
#include "cmdhf14b.h" #include "cmdhf14b.h"
#include "cmdmain.h"
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
@ -267,6 +268,116 @@ int CmdSrix4kRead(const char *Cmd)
return 0; 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[] = static command_t CommandTable[] =
{ {
{"help", CmdHelp, 1, "This help"}, {"help", CmdHelp, 1, "This help"},
@ -276,8 +387,9 @@ static command_t CommandTable[] =
{"sim", CmdHF14Sim, 0, "Fake ISO 14443 tag"}, {"sim", CmdHF14Sim, 0, "Fake ISO 14443 tag"},
{"simlisten", CmdHFSimlisten, 0, "Get HF samples as fake tag"}, {"simlisten", CmdHFSimlisten, 0, "Get HF samples as fake tag"},
{"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443"}, {"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443"},
{"sri512read", CmdSri512Read, 0, "<int> -- Read contents of a SRI512 tag"}, {"sri512read", CmdSri512Read, 0, "Read contents of a SRI512 tag"},
{"srix4kread", CmdSrix4kRead, 0, "<int> -- Read contents of a SRIX4K tag"}, {"srix4kread", CmdSrix4kRead, 0, "Read contents of a SRIX4K tag"},
{"raw", CmdHF14BCmdRaw, 0, "Send raw hex data to tag"},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View file

@ -86,6 +86,7 @@ typedef struct {
#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443 0x0301 #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443 0x0301
#define CMD_READ_SRI512_TAG 0x0303 #define CMD_READ_SRI512_TAG 0x0303
#define CMD_READ_SRIX4K_TAG 0x0304 #define CMD_READ_SRIX4K_TAG 0x0304
#define CMD_ISO_14443B_COMMAND 0x0305
#define CMD_READER_ISO_15693 0x0310 #define CMD_READER_ISO_15693 0x0310
#define CMD_SIMTAG_ISO_15693 0x0311 #define CMD_SIMTAG_ISO_15693 0x0311
#define CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 0x0312 #define CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 0x0312