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-
5654static int CmdHelp (const char * Cmd );
5755static felica_card_select_t last_known_card ;
5856
@@ -468,11 +466,30 @@ static int CmdHFFelicaInfo(const char *Cmd) {
468466 */
469467static 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