Fix felica sniffing.

This commit is contained in:
Thomas Sutter 2019-11-01 15:06:48 +01:00
commit dadad1dacf
4 changed files with 41 additions and 244 deletions

View file

@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased]
- Fix hf list felica and hf felica sniff (@7homasSutter)
- Added hf felica wrunencrypted (@7homasSutter)
- Added hf felica rdunencrypted (@7homasSutter)
- Added hf felica rqresponse (@7homasSutter)
- Added hf felica rqservice (@7homasSutter)

View file

@ -410,8 +410,6 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
// clear RXRDY:
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
uint32_t timeout = iso18092_get_timeout();
if (DBGLEVEL >= DBG_DEBUG)
Dbprintf("timeout set: %i", timeout);
for (;;) {
WDT_HIT();
@ -420,8 +418,8 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
Process18092Byte(b);
if (FelicaFrame.state == STATE_FULL) {
felica_nexttransfertime = MAX(felica_nexttransfertime,
(GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME
);
(GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME);
LogTrace(
FelicaFrame.framebytes,
FelicaFrame.len,
@ -453,7 +451,7 @@ static void iso18092_setup(uint8_t fpga_minor_mode) {
BigBuf_Clear_ext(false);
// Initialize Demod and Uart structs
//DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
// DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
FelicaFrameinit(BigBuf_malloc(FELICA_MAX_FRAME_SIZE));
felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER;
@ -574,66 +572,53 @@ void felica_sendraw(PacketCommandNG *c) {
void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) {
int remFrames = (samplesToSkip) ? samplesToSkip : 0;
Dbprintf("Sniff FelicaLiteS: Getting first %d frames, Skipping %d triggers.\n", samplesToSkip, triggersToSkip);
Dbprintf("Sniff Felica: Getting first %d frames, Skipping after %d triggers.\n", samplesToSkip, triggersToSkip);
clear_trace();
set_tracing(true);
iso18092_setup(FPGA_HF_ISO18092_FLAG_NOMOD);
LED_D_ON();
BigBuf_free();
BigBuf_Clear();
//the frame bits are slow enough.
int n = BigBuf_max_traceLen() / sizeof(uint8_t); // take all memory
int numbts = 0;
uint8_t *dest = (uint8_t *)BigBuf_get_addr();
uint8_t *destend = dest + n - 2;
uint32_t endframe = GetCountSspClk();
// Set up the synchronous serial port
FpgaSetupSsc();
//FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SNOOP);
SpinDelay(100);
while (dest <= destend && !BUTTON_PRESS()) {
uint16_t numbts = 0;
int trigger_cnt = 0;
uint32_t timeout = iso18092_get_timeout();
bool isTagFrame = true;
while (!BUTTON_PRESS()) {
WDT_HIT();
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR);
Process18092Byte(dist);
//to be sure we are in frame
if (FelicaFrame.state == STATE_GET_LENGTH) {
//length is after 48 (PRE)+16 (SYNC) - 64 ticks +maybe offset? not 100%
uint16_t distance = GetCountSspClk() - endframe - 64 + (FelicaFrame.byte_offset > 0 ? (8 - FelicaFrame.byte_offset) : 0);
*dest = distance >> 8;
dest++;
*dest = (distance & 0xff);
dest++;
if ((MAX(dist & 0xff, dist >> 8) >= 178) && (++trigger_cnt > triggersToSkip)) {
Dbprintf("triggersToSkip kicked %d", dist);
break;
}
//crc NOT checked
if (FelicaFrame.state == STATE_FULL) {
endframe = GetCountSspClk();
// *dest = FelicaFrame.crc_ok; //kind of wasteful
dest++;
for (int i = 0; i < FelicaFrame.len; i++) {
*dest = FelicaFrame.framebytes[i];
dest++;
if (dest >= destend) break;
}
//Dbprintf("Sniffing - Got Felica Frame! Sample remaining %i", remFrames);
remFrames--;
if (remFrames <= 0) break;
if (dest >= destend) break;
if (remFrames <= 0){
Dbprintf("Stop Sniffing - samplesToSkip reached!");
break;
}
if((FelicaFrame.framebytes[3] % 2) == 0){
isTagFrame = false; // All Reader Frames are even and all Tag frames are odd
} else{
isTagFrame = true;
}
LogTrace(FelicaFrame.framebytes,
FelicaFrame.len,
((GetCountSspClk() & 0xfffffff8) << 4) - DELAY_AIR2ARM_AS_READER - timeout,
((GetCountSspClk() & 0xfffffff8) << 4) - DELAY_AIR2ARM_AS_READER,
NULL,
isTagFrame
);
numbts += FelicaFrame.len;
FelicaFrameReset();
}
}
}
switch_off();
//reset framing
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
set_tracelen(numbts);
set_tracelen(BigBuf_max_traceLen());
Dbprintf("Felica sniffing done, tracelen: %i, use hf list felica for annotations", BigBuf_get_traceLen());
reply_old(CMD_ACK, 1, numbts, 0, 0, 0);

View file

@ -55,7 +55,8 @@ static int usage_hf_felica_sniff(void) {
PrintAndLogEx(NORMAL, " -t triggers to skip (decimal) max 9999");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " hf felica sniff 10 10");
PrintAndLogEx(NORMAL, " hf felica sniff");
PrintAndLogEx(NORMAL, " hf felica sniff -s 10 -t 10");
return PM3_SUCCESS;
}
@ -817,16 +818,17 @@ static int CmdHFFelicaSniff(const char *Cmd) {
}
i++;
}
if(samples2skip == 0){
if(samples2skip <= 0){
samples2skip = 10;
PrintAndLogEx(INFO, "Set default samples2skip: %i", samples2skip);
}
if(triggers2skip == 0){
triggers2skip = 10;
if(triggers2skip <= 0){
triggers2skip = 5000;
PrintAndLogEx(INFO, "Set default triggers2skip: %i", triggers2skip);
}
PrintAndLogEx(INFO, "Start Sniffing now. You can stop sniffing with clicking the PM3 Button");
PrintAndLogEx(INFO, "During sniffing, other pm3 commands may not response.");
clearCommandBuffer();
SendCommandMIX(CMD_HF_FELICA_SNIFF, samples2skip, triggers2skip, 0, NULL, 0);
return PM3_SUCCESS;

View file

@ -427,199 +427,6 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
return tracepos;
}
/*
static void printFelica(uint16_t traceLen, uint8_t *trace) {
PrintAndLogEx(NORMAL, "ISO18092 / FeliCa - Timings are not as accurate");
PrintAndLogEx(NORMAL, " Gap | Src | Data | CRC | Annotation |");
PrintAndLogEx(NORMAL, "--------|-----|-------------------------------------------------------------------------|----------|-------------------|");
uint16_t tracepos = 0;
PrintAndLogEx(NORMAL, "traceLen: %i", traceLen);
PrintAndLogEx(NORMAL, "Raw trace: %s", sprint_hex(trace, traceLen));
while (tracepos < traceLen) {
PrintAndLogEx(NORMAL, "tracepos: %i", tracepos);
PrintAndLogEx(NORMAL, "traceLen: %i", traceLen);
if (tracepos + 3 >= traceLen) break;
uint16_t gap = *((uint16_t *)(trace + tracepos));
uint8_t crc_ok = trace[tracepos + 2];
tracepos += 3;
if (tracepos + 3 >= traceLen) break;
uint16_t len = trace[tracepos + 2];
PrintAndLogEx(NORMAL, "LEN: %i", len);
//I am stripping SYNC
tracepos += 3; //skip SYNC
if (tracepos + len + 1 >= traceLen) break;
uint8_t cmd = trace[tracepos];
uint8_t isResponse = cmd & 1;
char line[32][110] = {{0}};
for (int j = 0; j < len + 1 && j / 8 < 32; j++) {
snprintf(line[j / 8] + ((j % 8) * 4), 110, " %02x ", trace[tracepos + j]);
}
char expbuf[50];
switch (cmd) {
case FELICA_POLL_REQ:
snprintf(expbuf, 49, "Poll Req");
break;
case FELICA_POLL_ACK:
snprintf(expbuf, 49, "Poll Resp");
break;
case FELICA_REQSRV_REQ:
snprintf(expbuf, 49, "Request Srvc Req");
break;
case FELICA_REQSRV_ACK:
snprintf(expbuf, 49, "Request Srv Resp");
break;
case FELICA_RDBLK_REQ:
snprintf(expbuf, 49, "Read block(s) Req");
break;
case FELICA_RDBLK_ACK:
snprintf(expbuf, 49, "Read block(s) Resp");
break;
case FELICA_WRTBLK_REQ:
snprintf(expbuf, 49, "Write block(s) Req");
break;
case FELICA_WRTBLK_ACK:
snprintf(expbuf, 49, "Write block(s) Resp");
break;
case FELICA_SRCHSYSCODE_REQ:
snprintf(expbuf, 49, "Search syscode Req");
break;
case FELICA_SRCHSYSCODE_ACK:
snprintf(expbuf, 49, "Search syscode Resp");
break;
case FELICA_REQSYSCODE_REQ:
snprintf(expbuf, 49, "Request syscode Req");
break;
case FELICA_REQSYSCODE_ACK:
snprintf(expbuf, 49, "Request syscode Resp");
break;
case FELICA_AUTH1_REQ:
snprintf(expbuf, 49, "Auth1 Req");
break;
case FELICA_AUTH1_ACK:
snprintf(expbuf, 49, "Auth1 Resp");
break;
case FELICA_AUTH2_REQ:
snprintf(expbuf, 49, "Auth2 Req");
break;
case FELICA_AUTH2_ACK:
snprintf(expbuf, 49, "Auth2 Resp");
break;
case FELICA_RDSEC_REQ:
snprintf(expbuf, 49, "Secure read Req");
break;
case FELICA_RDSEC_ACK:
snprintf(expbuf, 49, "Secure read Resp");
break;
case FELICA_WRTSEC_REQ:
snprintf(expbuf, 49, "Secure write Req");
break;
case FELICA_WRTSEC_ACK:
snprintf(expbuf, 49, "Secure write Resp");
break;
case FELICA_REQSRV2_REQ:
snprintf(expbuf, 49, "Request Srvc v2 Req");
break;
case FELICA_REQSRV2_ACK:
snprintf(expbuf, 49, "Request Srvc v2 Resp");
break;
case FELICA_GETSTATUS_REQ:
snprintf(expbuf, 49, "Get status Req");
break;
case FELICA_GETSTATUS_ACK:
snprintf(expbuf, 49, "Get status Resp");
break;
case FELICA_OSVER_REQ:
snprintf(expbuf, 49, "Get OS Version Req");
break;
case FELICA_OSVER_ACK:
snprintf(expbuf, 49, "Get OS Version Resp");
break;
case FELICA_RESET_MODE_REQ:
snprintf(expbuf, 49, "Reset mode Req");
break;
case FELICA_RESET_MODE_ACK:
snprintf(expbuf, 49, "Reset mode Resp");
break;
case FELICA_AUTH1V2_REQ:
snprintf(expbuf, 49, "Auth1 v2 Req");
break;
case FELICA_AUTH1V2_ACK:
snprintf(expbuf, 49, "Auth1 v2 Resp");
break;
case FELICA_AUTH2V2_REQ:
snprintf(expbuf, 49, "Auth2 v2 Req");
break;
case FELICA_AUTH2V2_ACK:
snprintf(expbuf, 49, "Auth2 v2 Resp");
break;
case FELICA_RDSECV2_REQ:
snprintf(expbuf, 49, "Secure read v2 Req");
break;
case FELICA_RDSECV2_ACK:
snprintf(expbuf, 49, "Secure read v2 Resp");
break;
case FELICA_WRTSECV2_REQ:
snprintf(expbuf, 49, "Secure write v2 Req");
break;
case FELICA_WRTSECV2_ACK:
snprintf(expbuf, 49, "Secure write v2 Resp");
break;
case FELICA_UPDATE_RNDID_REQ:
snprintf(expbuf, 49, "Update IDr Req");
break;
case FELICA_UPDATE_RNDID_ACK:
snprintf(expbuf, 49, "Update IDr Resp");
break;
default:
snprintf(expbuf, 49, "Unknown");
break;
}
int num_lines = MIN((len) / 16 + 1, 16);
for (int j = 0; j < num_lines ; j++) {
if (j == 0) {
PrintAndLogEx(NORMAL, "%7d | %s |%-32s |%02x %02x %s| %s",
gap,
(isResponse ? "Tag" : "Rdr"),
line[j],
trace[tracepos + len],
trace[tracepos + len + 1],
(crc_ok) ? "OK" : "NG",
expbuf);
} else {
PrintAndLogEx(NORMAL, " | |%-32s | | ", line[j]);
}
}
tracepos += len + 1;
}
PrintAndLogEx(NORMAL, "");
}*/
// sanity check. Don't use proxmark if it is offline and you didn't specify useTraceBuffer
/*
@ -857,6 +664,7 @@ int CmdTraceList(const char *Cmd) {
if (protocol == PROTO_HITAG)
PrintAndLogEx(NORMAL, "Hitag2 / HitagS - Timings in ETU (8us)");
if (protocol == FELICA)
PrintAndLogEx(NORMAL, "ISO18092 / FeliCa - Timings are not as accurate");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, " Start | End | Src | Data (! denotes parity error) | CRC | Annotation");