mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-11-10 17:49:32 +08:00
hf felica litesim - now uses cliparser
This commit is contained in:
parent
db3719792b
commit
91b47eeb1f
4 changed files with 145 additions and 76 deletions
|
@ -1311,7 +1311,11 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
break;
|
||||
}
|
||||
case CMD_HF_FELICALITE_SIMULATE: {
|
||||
felica_sim_lite(packet->oldarg[0]);
|
||||
struct p {
|
||||
uint8_t uid[8];
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *) packet->data.asBytes;
|
||||
felica_sim_lite(payload->uid);
|
||||
break;
|
||||
}
|
||||
case CMD_HF_FELICA_SNIFF: {
|
||||
|
|
|
@ -630,51 +630,74 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) {
|
|||
#define R_READBLK_LEN 0x21
|
||||
//simulate NFC Tag3 card - for now only poll response works
|
||||
// second half (4 bytes) of NDEF2 goes into nfcid2_0, first into nfcid2_1
|
||||
void felica_sim_lite(uint64_t uid) {
|
||||
void felica_sim_lite(uint8_t *uid) {
|
||||
|
||||
int i, curlen = 0;
|
||||
uint8_t *curresp = 0;
|
||||
|
||||
uint8_t ndef[8];
|
||||
num_to_bytes(uid, 8, ndef);
|
||||
|
||||
//prepare our 3 responses...
|
||||
// prepare our 3 responses...
|
||||
uint8_t resp_poll0[R_POLL0_LEN] = { 0xb2, 0x4d, 0x12, FELICA_POLL_ACK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x01, 0x43, 0x00, 0xb3, 0x7f};
|
||||
uint8_t resp_poll1[R_POLL1_LEN] = { 0xb2, 0x4d, 0x14, FELICA_POLL_ACK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x01, 0x43, 0x00, 0x88, 0xb4, 0xb3, 0x7f};
|
||||
uint8_t resp_readblk[R_READBLK_LEN] = { 0xb2, 0x4d, 0x1d, FELICA_RDBLK_ACK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x04, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x23, 0xcb, 0x6e};
|
||||
|
||||
//NFC tag 3/ ISo technically. Many overlapping standards
|
||||
DbpString("Felica Lite-S sim start");
|
||||
// NFC tag 3/ ISo technically. Many overlapping standards
|
||||
DbpString("Felica Lite-S simulation start");
|
||||
Dbprintf("NDEF2 UID: %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
ndef[0], ndef[1], ndef[2], ndef[3], ndef[4], ndef[5], ndef[6], ndef[7]
|
||||
uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7]
|
||||
);
|
||||
|
||||
//fill in blanks
|
||||
for (i = 0; i < 8; i++) {
|
||||
resp_poll0[i + 4] = ndef[i];
|
||||
resp_poll1[i + 4] = ndef[i];
|
||||
resp_readblk[i + 4] = ndef[i];
|
||||
// fill in blanks
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
resp_poll0[i + 4] = uid[i];
|
||||
resp_poll1[i + 4] = uid[i];
|
||||
resp_readblk[i + 4] = uid[i];
|
||||
}
|
||||
|
||||
//calculate and set CRC
|
||||
// calculate and set CRC
|
||||
AddCrc(resp_poll0, resp_poll0[2]);
|
||||
AddCrc(resp_poll1, resp_poll1[2]);
|
||||
AddCrc(resp_readblk, resp_readblk[2]);
|
||||
|
||||
iso18092_setup(FPGA_HF_ISO18092_FLAG_NOMOD);
|
||||
|
||||
int retval = PM3_SUCCESS;
|
||||
int curlen = 0;
|
||||
uint8_t *curresp = NULL;
|
||||
bool listenmode = true;
|
||||
//uint32_t frtm = GetCountSspClk();
|
||||
// uint32_t frtm = GetCountSspClk();
|
||||
|
||||
uint8_t flip = 0;
|
||||
uint16_t checker = 0;
|
||||
for (;;) {
|
||||
if (BUTTON_PRESS()) break;
|
||||
|
||||
WDT_HIT();
|
||||
|
||||
// since simulation is a tight time critical loop,
|
||||
// we only check for user request to end at iteration 3000, 9000.
|
||||
if (flip == 3) {
|
||||
if (data_available()) {
|
||||
retval = PM3_EOPABORTED;
|
||||
break;
|
||||
}
|
||||
flip = 0;
|
||||
}
|
||||
|
||||
if (checker >= 3000) {
|
||||
|
||||
if (BUTTON_PRESS()) {
|
||||
retval = PM3_EOPABORTED;
|
||||
break;
|
||||
}
|
||||
flip++;
|
||||
checker = 0;
|
||||
}
|
||||
++checker;
|
||||
|
||||
WDT_HIT();
|
||||
|
||||
if (listenmode) {
|
||||
//waiting for request...
|
||||
// waiting for request...
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
|
||||
uint8_t dist = (uint8_t)(AT91C_BASE_SSC->SSC_RHR);
|
||||
//frtm = GetCountSspClk();
|
||||
// frtm = GetCountSspClk();
|
||||
Process18092Byte(dist);
|
||||
|
||||
if (FelicaFrame.state == STATE_FULL) {
|
||||
|
@ -683,7 +706,7 @@ void felica_sim_lite(uint64_t uid) {
|
|||
|
||||
if (FelicaFrame.framebytes[2] == 6 && FelicaFrame.framebytes[3] == 0) {
|
||||
|
||||
//polling... there are two types of polling we answer to
|
||||
// polling... there are two types of polling we answer to
|
||||
if (FelicaFrame.framebytes[6] == 0) {
|
||||
curresp = resp_poll0;
|
||||
curlen = R_POLL0_LEN;
|
||||
|
@ -697,28 +720,30 @@ void felica_sim_lite(uint64_t uid) {
|
|||
}
|
||||
|
||||
if (FelicaFrame.framebytes[2] > 5 && FelicaFrame.framebytes[3] == 0x06) {
|
||||
//we should rebuild it depending on page size, but...
|
||||
//Let's see first
|
||||
// we should rebuild it depending on page size, but...
|
||||
// Let's see first
|
||||
curresp = resp_readblk;
|
||||
curlen = R_READBLK_LEN;
|
||||
listenmode = false;
|
||||
}
|
||||
//clear frame
|
||||
// clear frame
|
||||
FelicaFrameReset();
|
||||
} else {
|
||||
//frame invalid, clear it out to allow for the next one
|
||||
// frame invalid, clear it out to allow for the next one
|
||||
FelicaFrameReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!listenmode) {
|
||||
//trying to answer... here to start answering immediately.
|
||||
//this one is a bit finicky. Seems that being a bit late is better than earlier
|
||||
//TransmitFor18092_AsReader(curresp, curlen, frtm+512, 0, 0);
|
||||
|
||||
|
||||
if (listenmode == false) {
|
||||
// trying to answer... here to start answering immediately.
|
||||
// this one is a bit finicky. Seems that being a bit late is better than earlier
|
||||
// TransmitFor18092_AsReader(curresp, curlen, frtm+512, 0, 0);
|
||||
TransmitFor18092_AsReader(curresp, curlen, NULL, 0, 0);
|
||||
|
||||
//switch back
|
||||
// switch back
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO18092 | FPGA_HF_ISO18092_FLAG_NOMOD);
|
||||
|
||||
FelicaFrameReset();
|
||||
|
@ -730,10 +755,11 @@ void felica_sim_lite(uint64_t uid) {
|
|||
|
||||
switch_off();
|
||||
|
||||
//reset framing
|
||||
// reset framing
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
|
||||
|
||||
DbpString("Felica Lite-S sim end");
|
||||
Dbprintf("FeliCa Lite-S emulator stopped. Trace length: %d ", BigBuf_get_traceLen());
|
||||
reply_ng(CMD_HF_FELICALITE_SIMULATE, retval, NULL, 0);
|
||||
}
|
||||
|
||||
#define RES_SVC_LEN 11 + 3
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Definitions internal to the app source.
|
||||
// Definitions internal to the FeliCa functionality
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef __FELICA_H
|
||||
#define __FELICA_H
|
||||
|
@ -16,7 +16,7 @@
|
|||
|
||||
void felica_sendraw(PacketCommandNG *c);
|
||||
void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip);
|
||||
void felica_sim_lite(uint64_t uid);
|
||||
void felica_sim_lite(uint8_t *uid);
|
||||
void felica_dump_lite_s(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,22 +8,21 @@
|
|||
// High frequency ISO18092 / FeliCa commands
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "cmdhffelica.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "comms.h"
|
||||
#include "cmdtrace.h"
|
||||
#include "crc16.h"
|
||||
#include "util.h"
|
||||
#include "ui.h"
|
||||
#include "iso18.h" // felica_card_select_t struct
|
||||
#include "iso18.h" // felica_card_select_t struct
|
||||
#include "des.h"
|
||||
#include "cliparser.h" // cliparser
|
||||
#include "cliparser.h" // cliparser
|
||||
#include "util_posix.h" // msleep
|
||||
|
||||
#define AddCrc(data, len) compute_crc(CRC_FELICA, (data), (len), (data)+(len)+1, (data)+(len))
|
||||
|
||||
|
@ -136,28 +135,6 @@ static int usage_hf_felica_sniff(void) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_hf_felica_simlite(void) {
|
||||
PrintAndLogEx(NORMAL, "\n Emulating ISO/18092 FeliCa Lite tag \n");
|
||||
PrintAndLogEx(NORMAL, "Usage: hf felica litesim [h] u <uid>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " uid : UID in hexsymbol");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf felica litesim 11223344556677");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_hf_felica_dumplite(void) {
|
||||
PrintAndLogEx(NORMAL, "\n Dump ISO/18092 FeliCa Lite tag \n");
|
||||
PrintAndLogEx(NORMAL, "press button to abort run, otherwise it will loop for 200sec.");
|
||||
PrintAndLogEx(NORMAL, "Usage: hf felica litedump [h]");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf felica litedump");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_hf_felica_request_service(void) {
|
||||
PrintAndLogEx(NORMAL, "\nInfo: Use this command to verify the existence of Area and Service, and to acquire Key Version:");
|
||||
PrintAndLogEx(NORMAL, " - When the specified Area or Service exists, the card returns Key Version.");
|
||||
|
@ -1455,13 +1432,48 @@ static int CmdHFFelicaSniff(const char *Cmd) {
|
|||
|
||||
// uid hex
|
||||
static int CmdHFFelicaSimLite(const char *Cmd) {
|
||||
uint64_t uid = param_get64ex(Cmd, 0, 0, 16);
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf felica litesim",
|
||||
"Emulating ISO/18092 FeliCa Lite tag",
|
||||
"hf felica litesim -u 1122334455667788"
|
||||
);
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str1("u", "uid", "<hex>", "UID/NDEF2 8 hex bytes"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
int uid_len = 0;
|
||||
struct p {
|
||||
uint8_t uid[8];
|
||||
} PACKED payload;
|
||||
CLIGetHexWithReturn(ctx, 1, payload.uid, &uid_len);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (!uid)
|
||||
return usage_hf_felica_simlite();
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " or pm3-button to abort simulation");
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_FELICALITE_SIMULATE, uid, 0, 0, NULL, 0);
|
||||
SendCommandNG(CMD_HF_FELICALITE_SIMULATE, payload.uid, sizeof(payload));
|
||||
PacketResponseNG resp;
|
||||
|
||||
for (;;) {
|
||||
if (kbd_enter_pressed()) {
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
PrintAndLogEx(DEBUG, "User aborted");
|
||||
msleep(300);
|
||||
break;
|
||||
}
|
||||
|
||||
if (WaitForResponseTimeout(CMD_HF_FELICALITE_SIMULATE, &resp, 1000)) {
|
||||
if (resp.status == PM3_EOPABORTED) {
|
||||
PrintAndLogEx(DEBUG, "Button pressed, user aborted");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "Done");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1618,19 +1630,46 @@ static uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t trac
|
|||
|
||||
static int CmdHFFelicaDumpLite(const char *Cmd) {
|
||||
|
||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if (ctmp == 'h') return usage_hf_felica_dumplite();
|
||||
/*
|
||||
iceman 2021,
|
||||
Why does this command say it dumps a FeliCa lite card
|
||||
and then tries to print a trace?!?
|
||||
Is this a trace list or a feclia dump cmd?
|
||||
*/
|
||||
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf felica litedump",
|
||||
"Dump ISO/18092 FeliCa Lite tag. It will timeout after 200sec",
|
||||
"hf felica litedump"
|
||||
);
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
PrintAndLogEx(SUCCESS, "FeliCa lite - dump started");
|
||||
PrintAndLogEx(SUCCESS, "press pm3-button to cancel");
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_FELICALITE_DUMP, NULL, 0);
|
||||
PacketResponseNG resp;
|
||||
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " or pm3-button to abort dumping");
|
||||
|
||||
uint8_t timeout = 0;
|
||||
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
while (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) {
|
||||
|
||||
if (kbd_enter_pressed()) {
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
PrintAndLogEx(DEBUG, "User aborted");
|
||||
return PM3_EOPABORTED;
|
||||
}
|
||||
|
||||
timeout++;
|
||||
PrintAndLogEx(NORMAL, "." NOLF);
|
||||
PrintAndLogEx(INPLACE, "% 3i", timeout);
|
||||
|
||||
fflush(stdout);
|
||||
if (kbd_enter_pressed()) {
|
||||
PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
|
||||
|
@ -1659,7 +1698,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) {
|
|||
|
||||
uint8_t *trace = calloc(tracelen, sizeof(uint8_t));
|
||||
if (trace == NULL) {
|
||||
PrintAndLogEx(WARNING, "Cannot allocate memory for trace");
|
||||
PrintAndLogEx(WARNING, "failed to allocate memory ");
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
|
||||
|
@ -1669,8 +1708,8 @@ static int CmdHFFelicaDumpLite(const char *Cmd) {
|
|||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu32" bytes)", tracelen);
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu32" bytes)", tracelen);
|
||||
print_hex_break(trace, tracelen, 32);
|
||||
printSep();
|
||||
|
||||
|
@ -1791,7 +1830,7 @@ int readFelicaUid(bool verbose) {
|
|||
}
|
||||
case 0: {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(SUCCESS, "FeliCa tag info");
|
||||
PrintAndLogEx(SUCCESS, "-------- " _CYAN_("FeliCa tag info") " -------------------");
|
||||
|
||||
PrintAndLogEx(SUCCESS, "IDm %s", sprint_hex(card.IDm, sizeof(card.IDm)));
|
||||
PrintAndLogEx(SUCCESS, " - CODE %s", sprint_hex(card.code, sizeof(card.code)));
|
||||
|
@ -1839,7 +1878,7 @@ static command_t CommandTable[] = {
|
|||
//{"writev2", CmdHFFelicaNotImplementedYet, IfPm3Felica, "write Block Data to authentication-required Service."},
|
||||
//{"uprandomid", CmdHFFelicaNotImplementedYet, IfPm3Felica, "update Random ID (IDr)."},
|
||||
{"-----------", CmdHelp, AlwaysAvailable, "----------------------- " _CYAN_("FeliCa Light") " -----------------------"},
|
||||
{"litesim", CmdHFFelicaSimLite, IfPm3Felica, "<NDEF2> - only reply to poll request"},
|
||||
{"litesim", CmdHFFelicaSimLite, IfPm3Felica, "Emulating ISO/18092 FeliCa Lite tag"},
|
||||
{"litedump", CmdHFFelicaDumpLite, IfPm3Felica, "Wait for and try dumping FelicaLite"},
|
||||
// {"sim", CmdHFFelicaSim, IfPm3Felica, "<UID> -- Simulate ISO 18092/FeliCa tag"}
|
||||
{NULL, NULL, NULL, NULL}
|
||||
|
|
Loading…
Reference in a new issue