style
Some checks failed
CodeQL / Analyze (push) Has been cancelled
MacOS Build and Test / macos-make (push) Has been cancelled
MacOS Build and Test / macos-make-btaddon (push) Has been cancelled
MacOS Build and Test / macos-cmake (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make (push) Has been cancelled
Ubuntu Build and Test / ubuntu-make-btaddon (push) Has been cancelled
Ubuntu Build and Test / ubuntu-cmake (push) Has been cancelled
Windows Build and Test / proxspace (push) Has been cancelled
Windows Build and Test / wsl (push) Has been cancelled

This commit is contained in:
iceman1001 2025-08-04 19:53:08 +02:00
commit a0df90af18
4 changed files with 115 additions and 81 deletions

View file

@ -1737,74 +1737,74 @@ static int CmdHFFelicaDump(const char *Cmd) {
if (node_code == 0xFFFF) break;
char attrib_str[64] = "";
switch (len) {
case 0x0E:
break;
case 0x0C: {
uint8_t attribute = node_code & 0x3F;
bool is_public = (attribute & FELICA_SERVICE_ATTRIBUTE_UNAUTH_READ) != 0;
strcat(attrib_str, is_public ? "| Public " : "| Private ");
case 0x0E:
break;
case 0x0C: {
uint8_t attribute = node_code & 0x3F;
bool is_public = (attribute & FELICA_SERVICE_ATTRIBUTE_UNAUTH_READ) != 0;
strcat(attrib_str, is_public ? "| Public " : "| Private ");
bool is_purse = (attribute & FELICA_SERVICE_ATTRIBUTE_PURSE) != 0;
// Subfield bitwise attributes are applicable depending on is PURSE or not
bool is_purse = (attribute & FELICA_SERVICE_ATTRIBUTE_PURSE) != 0;
// Subfield bitwise attributes are applicable depending on is PURSE or not
if(is_purse) {
strcat(attrib_str, "| Purse |");
switch((attribute & FELICA_SERVICE_ATTRIBUTE_PURSE_SUBFIELD) >> 1) {
case 0:
strcat(attrib_str, " Direct |");
break;
case 1:
strcat(attrib_str, " Cashback |");
break;
case 2:
strcat(attrib_str, " Decrement |");
break;
case 3:
strcat(attrib_str, " Read Only |");
break;
default:
strcat(attrib_str, " Unknown |");
break;
if (is_purse) {
strcat(attrib_str, "| Purse |");
switch ((attribute & FELICA_SERVICE_ATTRIBUTE_PURSE_SUBFIELD) >> 1) {
case 0:
strcat(attrib_str, " Direct |");
break;
case 1:
strcat(attrib_str, " Cashback |");
break;
case 2:
strcat(attrib_str, " Decrement |");
break;
case 3:
strcat(attrib_str, " Read Only |");
break;
default:
strcat(attrib_str, " Unknown |");
break;
}
} else {
bool is_random = (attribute & FELICA_SERVICE_ATTRIBUTE_RANDOM_ACCESS) != 0;
strcat(attrib_str, is_random ? "| Random |" : "| Cyclic |");
bool is_readonly = (attribute & FELICA_SERVICE_ATTRIBUTE_READ_ONLY) != 0;
strcat(attrib_str, is_readonly ? " Read Only |" : " Read/Write |");
}
} else {
bool is_random = (attribute & FELICA_SERVICE_ATTRIBUTE_RANDOM_ACCESS) != 0;
strcat(attrib_str, is_random ? "| Random |" : "| Cyclic |");
bool is_readonly = (attribute & FELICA_SERVICE_ATTRIBUTE_READ_ONLY) != 0;
strcat(attrib_str, is_readonly ? " Read Only |" : " Read/Write |");
}
PrintAndLogEx(INFO, "Service %04X %s", node_code, attrib_str);
PrintAndLogEx(INFO, "Service %04X %s", node_code, attrib_str);
if (is_public) {
// dump blocks here
PrintAndLogEx(INFO, " block | data ");
PrintAndLogEx(INFO, "-------+----------------------------------------");
if (is_public) {
// dump blocks here
PrintAndLogEx(INFO, " block | data ");
PrintAndLogEx(INFO, "-------+----------------------------------------");
data_block_dump[11] = resp.payload[0]; // convert service code to little endian
data_block_dump[12] = resp.payload[1];
data_block_dump[11] = resp.payload[0]; // convert service code to little endian
data_block_dump[12] = resp.payload[1];
uint16_t last_blockno = 0xFF;
for (uint16_t i = 0x00; i < last_blockno; i++) {
data_block_dump[15] = i;
AddCrc(data_block_dump, block_datalen);
felica_read_without_encryption_response_t rd_noCry_resp;
if ((send_rd_plain(flags, block_datalen + 2, data_block_dump, 0, &rd_noCry_resp) == PM3_SUCCESS)) {
if (rd_noCry_resp.status_flags.status_flag1[0] == 0 && rd_noCry_resp.status_flags.status_flag2[0] == 0) {
print_rd_plain_response(&rd_noCry_resp);
uint16_t last_blockno = 0xFF;
for (uint16_t i = 0x00; i < last_blockno; i++) {
data_block_dump[15] = i;
AddCrc(data_block_dump, block_datalen);
felica_read_without_encryption_response_t rd_noCry_resp;
if ((send_rd_plain(flags, block_datalen + 2, data_block_dump, 0, &rd_noCry_resp) == PM3_SUCCESS)) {
if (rd_noCry_resp.status_flags.status_flag1[0] == 0 && rd_noCry_resp.status_flags.status_flag2[0] == 0) {
print_rd_plain_response(&rd_noCry_resp);
} else {
break; // no more blocks to read
}
} else {
break; // no more blocks to read
break;
}
} else {
break;
}
}
break;
}
break;
}
default:
PrintAndLogEx(FAILED, "Unexpected length 0x%02X @ 0x%04X",
len, cursor);
return PM3_ERFTRANS;
default:
PrintAndLogEx(FAILED, "Unexpected length 0x%02X @ 0x%04X",
len, cursor);
return PM3_ERFTRANS;
}
cursor++;
if (cursor == 0) break;
@ -2448,7 +2448,7 @@ static int read_without_encryption(
uint16_t size = hdr_size + sizeof(svc) + 1;
*n = size;
memcpy(out, &(uint8_t){ size }, sizeof(uint8_t));
memcpy(out, &(uint8_t) { size }, sizeof(uint8_t));
memcpy(out + 1, &request, hdr_size);
memcpy(out + hdr_size + 1, &svc, sizeof(svc));
@ -2507,7 +2507,7 @@ static int write_without_encryption(
uint8_t size = hdr_size + sizeof(blk) + dl + 1;
*n = size;
memcpy(out, &(uint8_t){ size }, sizeof(uint8_t));
memcpy(out, &(uint8_t) { size }, sizeof(uint8_t));
memcpy(out + 1, &hdr, hdr_size);
memcpy(out + hdr_size + 1, &blk, sizeof(blk));
memcpy(out + offset, data, dl);
@ -2551,10 +2551,10 @@ static int parse_multiple_block_data(const uint8_t *data, const size_t datalen,
}
static int felica_auth_context_init(
mbedtls_des3_context* ctx,
const uint8_t* rc,
mbedtls_des3_context *ctx,
const uint8_t *rc,
const size_t rclen,
const uint8_t* key,
const uint8_t *key,
const size_t keylen,
felica_auth_context_t *auth_ctx) {
@ -2599,12 +2599,12 @@ cleanup:
}
static int felica_generate_mac(
mbedtls_des3_context* ctx,
mbedtls_des3_context *ctx,
const felica_auth_context_t *auth_ctx,
const uint8_t* initialize_block,
const uint8_t* block_data,
const uint8_t *initialize_block,
const uint8_t *block_data,
const size_t length,
uint8_t* mac) {
uint8_t *mac) {
int ret = PM3_SUCCESS;

View file

@ -242,6 +242,7 @@ const static vocabulary_t vocabulary[] = {
{ 0, "hf felica reader" },
{ 0, "hf felica sniff" },
{ 0, "hf felica wrbl" },
{ 0, "hf felica dump" },
{ 0, "hf felica rqservice" },
{ 0, "hf felica rqresponse" },
{ 0, "hf felica scsvcode" },
@ -252,6 +253,7 @@ const static vocabulary_t vocabulary[] = {
{ 0, "hf felica resetmode" },
{ 0, "hf felica litesim" },
{ 0, "hf felica litedump" },
{ 0, "hf felica liteauth" },
{ 1, "hf fido help" },
{ 1, "hf fido list" },
{ 0, "hf fido info" },

View file

@ -2659,6 +2659,19 @@
],
"usage": "hf felica auth2 [-hv] [-i <hex>] [-c <hex>] [-k <hex>]"
},
"hf felica dump": {
"command": "hf felica dump",
"description": "Dump all existing Area Code and Service Code. Only works on services that do not require authentication yet.",
"notes": [
"hf felica dump"
],
"offline": false,
"options": [
"-h, --help This help",
"--no-auth read public services"
],
"usage": "hf felica dump [-h] [--no-auth]"
},
"hf felica help": {
"command": "hf felica help",
"description": "----------- ----------------------- General ----------------------- help This help list List ISO 18092/FeliCa history ----------- ----------------------- Operations ----------------------- ----------- ----------------------- FeliCa Standard ----------------------- ----------- ----------------------- FeliCa Light ----------------------- --------------------------------------------------------------------------------------- hf felica list available offline: yes Alias of `trace list -t felica` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol",
@ -2692,6 +2705,23 @@
],
"usage": "hf felica info [-h]"
},
"hf felica liteauth": {
"command": "hf felica liteauth",
"description": "Authenticate",
"notes": [
"hf felica liteauth -i 11100910C11BC407",
"hf felica liteauth -k 46656c69436130313233343536616263",
"hf felica liteauth -c 701185c59f8d30afeab8e4b3a61f5cc4 -k 46656c69436130313233343536616263"
],
"offline": false,
"options": [
"-h, --help This help",
"-k, --key <hex> set card key, 16 bytes",
"-c, <hex> set random challenge, 16 bytes",
"-i, <hex> set custom IDm"
],
"usage": "hf felica liteauth [-h] [-k <hex>] [-c <hex>] [-i <hex>]"
},
"hf felica litedump": {
"command": "hf felica litedump",
"description": "Dump ISO/18092 FeliCa Lite tag. It will timeout after 200sec",
@ -13453,8 +13483,8 @@
}
},
"metadata": {
"commands_extracted": 773,
"commands_extracted": 775,
"extracted_by": "PM3Help2JSON v1.00",
"extracted_on": "2025-07-28T13:42:15"
"extracted_on": "2025-08-04T17:50:35"
}
}

View file

@ -333,6 +333,7 @@ Check column "offline" for their availability.
|`hf felica reader `|N |`Act like an ISO18092/FeliCa reader`
|`hf felica sniff `|N |`Sniff ISO 18092/FeliCa traffic`
|`hf felica wrbl `|N |`write block data to an authentication-not-required Service.`
|`hf felica dump `|N |`Wait for and try dumping FeliCa`
|`hf felica rqservice `|N |`verify the existence of Area and Service, and to acquire Key Version.`
|`hf felica rqresponse `|N |`verify the existence of a card and its Mode.`
|`hf felica scsvcode `|N |`acquire Area Code and Service Code.`
@ -343,6 +344,7 @@ Check column "offline" for their availability.
|`hf felica resetmode `|N |`reset Mode to Mode 0.`
|`hf felica litesim `|N |`Emulating ISO/18092 FeliCa Lite tag`
|`hf felica litedump `|N |`Wait for and try dumping FelicaLite`
|`hf felica liteauth `|N |`authenticate a card.`
### hf fido