Skip to content

Commit 9b59204

Browse files
authored
Merge pull request #3036 from kormax/felica-frame-len-crc-bandaid-fix
Band-aid fix to strip erroneous length byte and CRC from client payload
2 parents c16f3f4 + 8c8bf54 commit 9b59204

File tree

1 file changed

+29
-49
lines changed

1 file changed

+29
-49
lines changed

client/src/cmdhffelica.c

Lines changed: 29 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@
5151
#define FELICA_SERVICE_ATTRIBUTE_PURSE_SUBFIELD (0b000110)
5252

5353

54-
#define AddCrc(data, len) compute_crc(CRC_FELICA, (data), (len), (data)+(len)+1, (data)+(len))
55-
5654
static int CmdHelp(const char *Cmd);
5755
static felica_card_select_t last_known_card;
5856

@@ -468,11 +466,30 @@ static int CmdHFFelicaInfo(const char *Cmd) {
468466
*/
469467
static void clear_and_send_command(uint8_t flags, uint16_t datalen, uint8_t *data, bool verbose) {
470468
uint16_t numbits = 0;
469+
uint16_t payload_len = 0;
470+
uint8_t *payload = data;
471+
472+
// ARMSRC implementation adds FeliCa preamble and length automatically (felica_sendraw:575-576)
473+
// A bunch of code in this module adds length byte at data[0] regardless of that, which is wrong
474+
// This is a workaround to extract the actual payload correctly so that length byte isn't repeated
475+
// It also strips CRC if present, as ARMSRC adds it too
476+
if (data && datalen) {
477+
if (datalen >= data[0] && data[0] > 0) {
478+
payload_len = data[0] - 1;
479+
if (payload_len > datalen - 1) {
480+
payload_len = datalen - 1;
481+
}
482+
payload = data + 1;
483+
} else {
484+
payload_len = datalen;
485+
}
486+
}
487+
471488
clearCommandBuffer();
472489
if (verbose) {
473-
PrintAndLogEx(INFO, "Send raw command - Frame: %s", sprint_hex(data, datalen));
490+
PrintAndLogEx(INFO, "Send raw command - Frame: %s", sprint_hex(payload, payload_len));
474491
}
475-
SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen);
492+
SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (payload_len & 0xFFFF) | (uint32_t)(numbits << 16), 0, payload, payload_len);
476493
}
477494

478495
/**
@@ -785,8 +802,6 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) {
785802
// Add M1c Challenge to frame
786803
memcpy(data + 16, output, sizeof(output));
787804

788-
AddCrc(data, datalen);
789-
datalen += 2;
790805
uint8_t flags = (FELICA_APPEND_CRC | FELICA_RAW);
791806

792807
PrintAndLogEx(INFO, "Client send AUTH1 frame: %s", sprint_hex(data, datalen));
@@ -974,8 +989,6 @@ static int CmdHFFelicaAuthentication2(const char *Cmd) {
974989
// Add M4c Challenge to frame
975990
memcpy(data + 10, m4c, sizeof(m4c));
976991

977-
AddCrc(data, datalen);
978-
datalen += 2;
979992
uint8_t flags = (FELICA_APPEND_CRC | FELICA_RAW);
980993

981994
PrintAndLogEx(INFO, "Client Send AUTH2 Frame: %s", sprint_hex(data, datalen));
@@ -1147,8 +1160,6 @@ static int CmdHFFelicaWritePlain(const char *Cmd) {
11471160
}
11481161

11491162
uint8_t flags = (FELICA_APPEND_CRC | FELICA_RAW);
1150-
AddCrc(data, datalen);
1151-
datalen += 2;
11521163

11531164
felica_status_response_t wr_noCry_resp;
11541165
if (send_wr_plain(flags, datalen, data, 1, &wr_noCry_resp) == PM3_SUCCESS) {
@@ -1300,8 +1311,6 @@ static int CmdHFFelicaReadPlain(const char *Cmd) {
13001311

13011312
for (uint16_t i = 0x00; i < last_blockno; i++) {
13021313
data[15] = i;
1303-
AddCrc(data, datalen);
1304-
datalen += 2;
13051314
felica_read_without_encryption_response_t rd_noCry_resp;
13061315
if ((send_rd_plain(flags, datalen, data, 0, &rd_noCry_resp) == PM3_SUCCESS)) {
13071316
if (rd_noCry_resp.status_flags.status_flag1[0] == 0 && rd_noCry_resp.status_flags.status_flag2[0] == 0) {
@@ -1310,11 +1319,8 @@ static int CmdHFFelicaReadPlain(const char *Cmd) {
13101319
} else {
13111320
break;
13121321
}
1313-
datalen -= 2;
13141322
}
13151323
} else {
1316-
AddCrc(data, datalen);
1317-
datalen += 2;
13181324
felica_read_without_encryption_response_t rd_noCry_resp;
13191325
if (send_rd_plain(flags, datalen, data, 1, &rd_noCry_resp) == PM3_SUCCESS) {
13201326
print_rd_plain_response(&rd_noCry_resp);
@@ -1369,9 +1375,6 @@ static int CmdHFFelicaRequestResponse(const char *Cmd) {
13691375
return PM3_EINVARG;
13701376
}
13711377

1372-
AddCrc(data, datalen);
1373-
datalen += 2;
1374-
13751378
uint8_t flags = (FELICA_APPEND_CRC | FELICA_RAW);
13761379
clear_and_send_command(flags, datalen, data, 0);
13771380

@@ -1472,8 +1475,6 @@ static int CmdHFFelicaRequestSpecificationVersion(const char *Cmd) {
14721475
return PM3_EINVARG;
14731476
}
14741477

1475-
AddCrc(data, datalen);
1476-
datalen += 2;
14771478
uint8_t flags = (FELICA_APPEND_CRC | FELICA_RAW);
14781479

14791480
clear_and_send_command(flags, datalen, data, 0);
@@ -1576,8 +1577,6 @@ static int CmdHFFelicaResetMode(const char *Cmd) {
15761577
return PM3_EINVARG;
15771578
}
15781579

1579-
AddCrc(data, datalen);
1580-
datalen += 2;
15811580
uint8_t flags = (FELICA_APPEND_CRC | FELICA_RAW);
15821581

15831582
clear_and_send_command(flags, datalen, data, 0);
@@ -1647,8 +1646,6 @@ static int CmdHFFelicaRequestSystemCode(const char *Cmd) {
16471646
return PM3_EINVARG;
16481647
}
16491648

1650-
AddCrc(data, datalen);
1651-
datalen += 2;
16521649
uint8_t flags = (FELICA_APPEND_CRC | FELICA_RAW);
16531650

16541651
clear_and_send_command(flags, datalen, data, 0);
@@ -1725,9 +1722,8 @@ static int CmdHFFelicaDump(const char *Cmd) {
17251722

17261723
data_service_dump[10] = cursor & 0xFF;
17271724
data_service_dump[11] = cursor >> 8;
1728-
AddCrc(data_service_dump, service_datalen);
17291725

1730-
if (send_dump_sv_plain(flags, service_datalen + 2, data_service_dump, 0,
1726+
if (send_dump_sv_plain(flags, service_datalen, data_service_dump, 0,
17311727
&resp, false) != PM3_SUCCESS) {
17321728
PrintAndLogEx(FAILED, "No response at cursor 0x%04X", cursor);
17331729
return PM3_ERFTRANS;
@@ -1793,9 +1789,8 @@ static int CmdHFFelicaDump(const char *Cmd) {
17931789
uint16_t last_blockno = 0xFF;
17941790
for (uint16_t i = 0x00; i < last_blockno; i++) {
17951791
data_block_dump[15] = i;
1796-
AddCrc(data_block_dump, block_datalen);
17971792
felica_read_without_encryption_response_t rd_noCry_resp;
1798-
if ((send_rd_plain(flags, block_datalen + 2, data_block_dump, 0, &rd_noCry_resp) == PM3_SUCCESS)) {
1793+
if ((send_rd_plain(flags, block_datalen, data_block_dump, 0, &rd_noCry_resp) == PM3_SUCCESS)) {
17991794
if (rd_noCry_resp.status_flags.status_flag1[0] == 0 && rd_noCry_resp.status_flags.status_flag2[0] == 0) {
18001795
print_rd_plain_response(&rd_noCry_resp);
18011796
} else {
@@ -1919,13 +1914,11 @@ static int CmdHFFelicaRequestService(const char *Cmd) {
19191914
// send 32 calls
19201915
for (uint8_t i = 1; i < 32; i++) {
19211916
data[10] = i;
1922-
AddCrc(data, datalen);
1923-
send_request_service(flags, datalen + 2, data, 1);
1917+
send_request_service(flags, datalen, data, 1);
19241918
}
19251919

19261920
} else {
1927-
AddCrc(data, datalen);
1928-
send_request_service(flags, datalen + 2, data, 1);
1921+
send_request_service(flags, datalen, data, 1);
19291922
}
19301923

19311924
return PM3_SUCCESS;
@@ -1973,9 +1966,8 @@ static int CmdHFFelicaDumpServiceArea(const char *Cmd) {
19731966
/* insert cursor LE */
19741967
data[10] = cursor & 0xFF;
19751968
data[11] = cursor >> 8;
1976-
AddCrc(data, datalen);
19771969

1978-
if (send_dump_sv_plain(flags, datalen + 2, data, 0,
1970+
if (send_dump_sv_plain(flags, datalen, data, 0,
19791971
&resp, false) != PM3_SUCCESS) {
19801972
PrintAndLogEx(FAILED, "No response at cursor 0x%04X", cursor);
19811973
return PM3_ERFTRANS;
@@ -2503,9 +2495,6 @@ static int felica_internal_authentication(
25032495
return PM3_ERFTRANS;
25042496
}
25052497

2506-
AddCrc(data, datalen);
2507-
datalen += 2;
2508-
25092498
uint8_t flags = (FELICA_APPEND_CRC | FELICA_RAW | FELICA_NO_DISCONNECT);
25102499

25112500
felica_status_response_t res;
@@ -2527,9 +2516,6 @@ static int felica_internal_authentication(
25272516
return PM3_ERFTRANS;
25282517
}
25292518

2530-
AddCrc(data, datalen);
2531-
datalen += 2;
2532-
25332519
uint8_t pd[FELICA_BLK_SIZE * sizeof(blk_numbers2)];
25342520
memset(pd, 0, sizeof(pd));
25352521

@@ -2593,9 +2579,6 @@ static int felica_external_authentication(
25932579
return PM3_ERFTRANS;
25942580
}
25952581

2596-
AddCrc(data, datalen);
2597-
datalen += 2;
2598-
25992582
uint8_t wcnt_blk[FELICA_BLK_SIZE];
26002583
ret = send_rd_multiple_plain(flags, datalen, data, wcnt_blk);
26012584
if (ret) {
@@ -2621,9 +2604,6 @@ static int felica_external_authentication(
26212604
return PM3_ERFTRANS;
26222605
}
26232606

2624-
AddCrc(data, datalen);
2625-
datalen += 2;
2626-
26272607
if (keep == false) {
26282608
flags &= ~FELICA_NO_DISCONNECT;
26292609
}
@@ -3097,12 +3077,12 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) {
30973077
CLIGetHexWithReturn(ctx, 7, data, &datalen);
30983078
CLIParserFree(ctx);
30993079

3080+
uint8_t flags = 0;
3081+
31003082
if (crc) {
3101-
AddCrc(data, datalen);
3102-
datalen += 2;
3083+
flags |= FELICA_APPEND_CRC;
31033084
}
31043085

3105-
uint8_t flags = 0;
31063086
if (active || active_select) {
31073087
flags |= FELICA_CONNECT;
31083088
if (active) {

0 commit comments

Comments
 (0)