Merge pull request #1772 from markus-oehme-pg40/iso15693-improvements

Iso15693 improvements
This commit is contained in:
Iceman 2022-09-06 16:44:51 +02:00 committed by GitHub
commit 1a6c127f0d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 184 additions and 34 deletions

View file

@ -3,6 +3,10 @@ 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]
- Added `hf 15 eview` and `hf 15 esave` - Retrieve emulator image for ISO15693 simulation (@markus-oehme-pg40)
- Changed `hf 15 sim` - now supports reader writes (@markus-oehme-pg40)
- Added `hf 15 eload` - specify memory image for ISO15693 simulation (@markus-oehme-pg40)
- Added `hf 15 sim --blocksize` - configure block size for simulation (@markus-oehme-pg40)
- Fixed buffer overflow in mfu ndef decode (@mwalker)
- Changed spiffs write/append to send in 8192 chunks to ensure its eraised (@mwalker)
- Fixed spiffs dump to ensure to fails correctly if no big_buff was allocated (@mwalker)
@ -90,8 +94,6 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
- Added new standalone mode `lf_em4100rsww` (@zabszk)
- Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz)
- Added `script run hf_mf_hid_sim.lua` (@micsen)
- Added `hf 15 sim --blocksize` - configure block size for simulation (@markus-oehme-pg40)
- Added `hf 15 eload` - specify memory image for ISO15693 simulation (@markus-oehme-pg40)
## [Frostbit.4.14831][2022-01-11]

View file

@ -2111,6 +2111,11 @@ void EmlSetMemIso15693(uint8_t count, uint8_t *data, uint32_t offset) {
memcpy(emCARD + offset, data, count);
}
void EmlGetMemIso15693(uint8_t count, uint8_t *output, uint32_t offset) {
uint8_t *emCARD = BigBuf_get_EM_addr();
memcpy(output, emCARD + offset, count);
}
// Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands
// all demodulation performed in arm rather than host. - greg
void SimTagIso15693(uint8_t *uid, uint8_t block_size) {
@ -2235,29 +2240,19 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) {
// READ_BLOCK and READ_MULTI_BLOCK
if ((cmd[1] == ISO15693_READBLOCK) || (cmd[1] == ISO15693_READ_MULTI_BLOCK)) {
bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH);
bool addressed = cmd[0] & ISO15_REQ_ADDRESS;
bool option = cmd[0] & ISO15_REQ_OPTION;
uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM;
uint8_t block_idx = 0;
uint8_t address_offset = 0;
if (addressed) {
address_offset = 8;
}
uint8_t block_idx = cmd[2 + address_offset];
uint8_t block_count = 1;
if (cmd[1] == ISO15693_READBLOCK) {
if (cmd_len == 13) {
// addressed mode
block_idx= cmd[10];
} else if (cmd_len == 5) {
// non-addressed mode
block_idx = cmd[2];
}
} else if (cmd[1] == ISO15693_READ_MULTI_BLOCK) {
if (cmd_len == 14) {
// addressed mode
block_idx= cmd[10];
block_count= cmd[11] + 1;
} else if (cmd_len == 6) {
// non-addressed mode
block_idx = cmd[2];
block_count = cmd[3] + 1;
}
if (cmd[1] == ISO15693_READ_MULTI_BLOCK) {
block_count = cmd[3 + address_offset] + 1;
}
// Build READ_(MULTI_)BLOCK response
@ -2268,11 +2263,8 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) {
security_offset = 1;
}
uint8_t resp_readblock[response_length];
for (int i = 0; i < response_length; i++) {
resp_readblock[i] = 0;
}
memset(resp_readblock, 0, response_length);
uint8_t *emCARD = BigBuf_get_EM_addr();
resp_readblock[0] = 0; // Response flags
for (int j = 0; j < block_count; j++) {
// where to put the data of the current block
@ -2280,13 +2272,12 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) {
if (option) {
resp_readblock[work_offset] = 0; // Security status
}
for (int i = 0; i < block_size; i++) {
// Block data
if (block_size * (block_idx + j + 1) <= CARD_MEMORY_SIZE) {
resp_readblock[work_offset + security_offset + i] = emCARD[block_size * (block_idx + j) + i];
} else {
resp_readblock[work_offset + security_offset + i] = 0;
}
// Block data
if (block_size * (block_idx + j + 1) <= CARD_MEMORY_SIZE) {
EmlGetMemIso15693(block_size, resp_readblock + (work_offset + security_offset),
block_size * (block_idx + j));
} else {
memset(resp_readblock + work_offset + security_offset, 0, block_size);
}
}
@ -2299,6 +2290,45 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) {
TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow);
LogTrace_ISO15693(resp_readblock, response_length, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false);
}
// WRITE_BLOCK and WRITE_MULTI_BLOCK
if ((cmd[1] == ISO15693_WRITEBLOCK) || (cmd[1] == ISO15693_WRITE_MULTI_BLOCK)) {
bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH);
bool addressed = cmd[0] & ISO15_REQ_ADDRESS;
uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM;
uint8_t address_offset = 0;
if (addressed) {
address_offset = 8;
}
uint8_t block_idx = cmd[2 + address_offset];
uint8_t block_count = 1;
uint8_t multi_offset = 0;
if (cmd[1] == ISO15693_WRITE_MULTI_BLOCK) {
block_count = cmd[3 + address_offset] + 1;
multi_offset = 1;
}
uint8_t *data = cmd + 3 + address_offset + multi_offset;
// write data
EmlSetMemIso15693(block_count * block_size, data, block_idx * block_size);
// Build WRITE_(MULTI_)BLOCK response
int response_length = 3;
uint8_t resp_writeblock[response_length];
memset(resp_writeblock, 0, response_length);
resp_writeblock[0] = 0; // Response flags
// CRC
AddCrc15(resp_writeblock, response_length - 2);
CodeIso15693AsTag(resp_writeblock, response_length);
tosend_t *ts = get_tosend();
TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow);
LogTrace_ISO15693(resp_writeblock, response_length, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false);
}
}
switch_off();

View file

@ -48,6 +48,7 @@ void AcquireRawAdcSamplesIso15693(void);
void ReaderIso15693(iso15_card_select_t *p_card); // ISO15693 reader
void EmlClearIso15693(void);
void EmlSetMemIso15693(uint8_t count, uint8_t *data, uint32_t offset);
void EmlGetMemIso15693(uint8_t count, uint8_t *output, uint32_t offset);
void SimTagIso15693(uint8_t *uid, uint8_t block_size); // simulate an ISO15693 tag
void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag
void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t *data); // send arbitrary commands from CLI

View file

@ -1043,7 +1043,7 @@ static int CmdHF15ELoad(const char *Cmd) {
uint8_t *data = NULL;
size_t bytes_read = 0;
int res = loadFile_safe(filename, ".bin", (void **)&data, &bytes_read);
int res = pm3_load_dump(filename, (void **)&data, &bytes_read, CARD_MEMORY_SIZE);
if (res != PM3_SUCCESS) {
return res;
}
@ -1098,6 +1098,121 @@ static int CmdHF15ELoad(const char *Cmd) {
return PM3_SUCCESS;
}
static int CmdHF15ESave(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 15 esave",
"Save emulator memory into three files (BIN/EML/JSON) ",
"hf 15 esave -f hf-15-01020304"
"hf 15 esave -b 8 -c 42 -f hf-15-01020304"
);
void *argtable[] = {
arg_param_begin,
arg_str1("f", "file", "<fn>", "filename of dump"),
arg_int0("b", "blocksize", "<dec>", "block size, defaults to 4"),
arg_int0("c", "count", "<dec>", "number of blocks to export, defaults to all"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
int fnlen = 0;
char filename[FILE_PATH_SIZE];
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
int blocksize = arg_get_int_def(ctx, 2, 4);
int count = arg_get_int_def(ctx, 3, -1);
CLIParserFree(ctx);
int bytes = CARD_MEMORY_SIZE;
if (count > 0 && count * blocksize <= bytes) {
bytes = count * blocksize;
}
// reserve memory
uint8_t *dump = calloc(bytes, sizeof(uint8_t));
if (dump == NULL) {
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
return PM3_EMALLOC;
}
PrintAndLogEx(INFO, "Downloading %u bytes from emulator memory", bytes);
if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0, NULL, 0, NULL, 2500, false)) {
PrintAndLogEx(WARNING, "Fail, transfer from device time-out");
free(dump);
return PM3_ETIMEOUT;
}
pm3_save_dump(filename, dump, bytes, jsf15, blocksize);
free(dump);
return PM3_SUCCESS;
}
static void print_hrule(int blocksize) {
char dashes[] = "------------------------------------------------------------";
PrintAndLogEx(INFO, "-----+%.*s-+-%.*s-", 3*blocksize, dashes, blocksize, dashes);
}
static void print_blocks_15693(uint8_t *data, uint16_t bytes, int blocksize) {
int blocks = bytes / blocksize;
PrintAndLogEx(NORMAL, "");
print_hrule(blocksize);
char spaces[] = " ";
PrintAndLogEx(INFO, " blk | data %.*s| ascii", MAX(0, 3*blocksize - 5), spaces);
print_hrule(blocksize);
for (int i = 0; i < blocks; i++) {
PrintAndLogEx(INFO, "%4d | %s ", i, sprint_hex_ascii(data + (i * blocksize), blocksize));
}
if (bytes % blocksize != 0) {
// If there is something left over print it too
// This will have a broken layout, but should not happen anyway
PrintAndLogEx(INFO, "%4d | %s ", blocks, sprint_hex_ascii(data + (blocks * blocksize),
bytes % blocksize));
}
print_hrule(blocksize);
PrintAndLogEx(NORMAL, "");
}
static int CmdHF15EView(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 15 eview",
"It displays emulator memory",
"hf 15 eview\n"
"hf 15 eview -b 8 -c 60\n"
);
void *argtable[] = {
arg_param_begin,
arg_int0("b", "blocksize", "<dec>", "block size, defaults to 4"),
arg_int0("c", "count", "<dec>", "number of blocks to display, defaults to all"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
int blocksize = arg_get_int_def(ctx, 1, 4);
int count = arg_get_int_def(ctx, 2, -1);
CLIParserFree(ctx);
int bytes = CARD_MEMORY_SIZE;
if (count > 0 && count * blocksize <= bytes) {
bytes = count * blocksize;
}
uint8_t *dump = calloc(bytes, sizeof(uint8_t));
if (dump == NULL) {
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
return PM3_EMALLOC;
}
PrintAndLogEx(INFO, "Downloading %u bytes from emulator memory", bytes);
if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0, NULL, 0, NULL, 2500, false)) {
PrintAndLogEx(WARNING, "Fail, transfer from device time-out");
free(dump);
return PM3_ETIMEOUT;
}
print_blocks_15693(dump, bytes, blocksize);
free(dump);
return PM3_SUCCESS;
}
// Simulation is still not working very good
// helptext
static int CmdHF15Sim(const char *Cmd) {
@ -2289,7 +2404,9 @@ static command_t CommandTable[] = {
{"reader", CmdHF15Reader, IfPm3Iso15693, "Act like an ISO-15693 reader"},
{"restore", CmdHF15Restore, IfPm3Iso15693, "Restore from file to all memory pages of an ISO-15693 tag"},
{"samples", CmdHF15Samples, IfPm3Iso15693, "Acquire samples as reader (enables carrier, sends inquiry)"},
{"eload", CmdHF15ELoad, IfPm3Iso15693, "Load image file to be used by 'sim' command"},
{"eload", CmdHF15ELoad, IfPm3Iso15693, "Load image file into emulator to be used by 'sim' command"},
{"esave", CmdHF15ESave, IfPm3Iso15693, "Save emulator memory into image file"},
{"eview", CmdHF15EView, IfPm3Iso15693, "View emulator memory"},
{"sim", CmdHF15Sim, IfPm3Iso15693, "Fake an ISO-15693 tag"},
{"slixdisable", CmdHF15SlixDisable, IfPm3Iso15693, "Disable privacy mode on SLIX ISO-15693 tag"},
{"wrbl", CmdHF15Write, IfPm3Iso15693, "Write a block"},