mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-08 06:00:53 -07:00
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:
parent
a763eb2126
commit
7cf3ef203c
5 changed files with 193 additions and 53 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
@ -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++;
|
||||
|
@ -1079,7 +1052,6 @@ void RAMFUNC SnoopIso14443(void)
|
|||
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
|
||||
LED_D_OFF();
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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, "<int> -- Read contents of a SRI512 tag"},
|
||||
{"srix4kread", CmdSrix4kRead, 0, "<int> -- 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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue