From 569d57719d7642db9577a7cb28000fbc09a69949 Mon Sep 17 00:00:00 2001 From: Henry Gabryjelski Date: Sun, 5 May 2024 15:54:00 -0700 Subject: [PATCH] Fix firmware return value for em4x70 to always be of type `PM3_*` --- armsrc/em4x70.c | 58 +++++++++++++++++++--------------------- client/src/cmdlfem4x70.c | 58 +++++++++------------------------------- 2 files changed, 40 insertions(+), 76 deletions(-) diff --git a/armsrc/em4x70.c b/armsrc/em4x70.c index 2732c1405..05f08d6bc 100644 --- a/armsrc/em4x70.c +++ b/armsrc/em4x70.c @@ -581,11 +581,6 @@ static bool send_command_and_read(uint8_t command, uint8_t *bytes, size_t length Dbprintf("Invalid data received length: %d, expected %d", len, out_length_bits); return false; } - // TODO: Figure out why getting an extra bit (quite often) here - // e.g., write block and info commands both reach here and output: - // [#] Should have a multiple of 8 bits, was sent 33 - // [#] Should have a multiple of 8 bits, was sent 65 - // Extra bits are currently just dropped, with no ill effect noticed. bits2bytes(bits, len, bytes); return true; } @@ -617,7 +612,6 @@ static bool em4x70_read_um1(void) { } - /** * em4x70_read_um2 * @@ -725,7 +719,7 @@ static int em4x70_receive(uint8_t *bits, size_t length) { void em4x70_info(const em4x70_data_t *etd, bool ledcontrol) { - uint8_t status = 0; + bool success = false; // Support tags with and without command parity bits command_parity = etd->parity; @@ -736,17 +730,17 @@ void em4x70_info(const em4x70_data_t *etd, bool ledcontrol) { // Find the Tag if (get_signalproperties() && find_em4x70_tag()) { // Read ID, UM1 and UM2 - status = em4x70_read_id() && em4x70_read_um1() && em4x70_read_um2(); + success = em4x70_read_id() && em4x70_read_um1() && em4x70_read_um2(); } StopTicks(); lf_finalize(ledcontrol); + int status = success ? PM3_SUCCESS : PM3_ESOFT; reply_ng(CMD_LF_EM4X70_INFO, status, tag.data, sizeof(tag.data)); } void em4x70_write(const em4x70_data_t *etd, bool ledcontrol) { - - uint8_t status = 0; + int status = PM3_ESOFT; command_parity = etd->parity; @@ -757,16 +751,15 @@ void em4x70_write(const em4x70_data_t *etd, bool ledcontrol) { if (get_signalproperties() && find_em4x70_tag()) { // Write - status = write(etd->word, etd->address) == PM3_SUCCESS; + status = write(etd->word, etd->address); - if (status) { + if (status == PM3_SUCCESS) { // Read Tag after writing if (em4x70_read_id()) { em4x70_read_um1(); em4x70_read_um2(); } } - } StopTicks(); @@ -776,7 +769,7 @@ void em4x70_write(const em4x70_data_t *etd, bool ledcontrol) { void em4x70_unlock(const em4x70_data_t *etd, bool ledcontrol) { - uint8_t status = 0; + int status = PM3_ESOFT; command_parity = etd->parity; @@ -790,10 +783,10 @@ void em4x70_unlock(const em4x70_data_t *etd, bool ledcontrol) { if (em4x70_read_id()) { // Send PIN - status = send_pin(etd->pin) == PM3_SUCCESS; + status = send_pin(etd->pin); // If the write succeeded, read the rest of the tag - if (status) { + if (status == PM3_SUCCESS) { // Read Tag // ID doesn't change em4x70_read_um1(); @@ -809,7 +802,8 @@ void em4x70_unlock(const em4x70_data_t *etd, bool ledcontrol) { void em4x70_auth(const em4x70_data_t *etd, bool ledcontrol) { - uint8_t status = 0; + int status = PM3_ESOFT; + uint8_t response[3] = {0}; command_parity = etd->parity; @@ -821,7 +815,7 @@ void em4x70_auth(const em4x70_data_t *etd, bool ledcontrol) { if (get_signalproperties() && find_em4x70_tag()) { // Authenticate and get tag response - status = authenticate(etd->rnd, etd->frnd, response) == PM3_SUCCESS; + status = authenticate(etd->rnd, etd->frnd, response); } StopTicks(); @@ -830,7 +824,7 @@ void em4x70_auth(const em4x70_data_t *etd, bool ledcontrol) { } void em4x70_brute(const em4x70_data_t *etd, bool ledcontrol) { - uint8_t status = 0; + int status = PM3_ESOFT; uint8_t response[2] = {0}; command_parity = etd->parity; @@ -842,7 +836,7 @@ void em4x70_brute(const em4x70_data_t *etd, bool ledcontrol) { if (get_signalproperties() && find_em4x70_tag()) { // Bruteforce partial key - status = bruteforce(etd->address, etd->rnd, etd->frnd, etd->start_key, response) == PM3_SUCCESS; + status = bruteforce(etd->address, etd->rnd, etd->frnd, etd->start_key, response); } StopTicks(); @@ -852,7 +846,7 @@ void em4x70_brute(const em4x70_data_t *etd, bool ledcontrol) { void em4x70_write_pin(const em4x70_data_t *etd, bool ledcontrol) { - uint8_t status = 0; + int status = PM3_ESOFT; command_parity = etd->parity; @@ -865,17 +859,19 @@ void em4x70_write_pin(const em4x70_data_t *etd, bool ledcontrol) { // Read ID (required for send_pin command) if (em4x70_read_id()) { - // Write new PIN - if ((write((etd->pin) & 0xFFFF, EM4X70_PIN_WORD_UPPER) == PM3_SUCCESS) && - (write((etd->pin >> 16) & 0xFFFF, EM4X70_PIN_WORD_LOWER) == PM3_SUCCESS)) { - + // Write the pin + status = write((etd->pin) & 0xFFFF, EM4X70_PIN_WORD_UPPER); + if (status == PM3_SUCCESS) { + status = write((etd->pin >> 16) & 0xFFFF, EM4X70_PIN_WORD_LOWER); + } + if (status == PM3_SUCCESS) { // Now Try to authenticate using the new PIN // Send PIN - status = send_pin(etd->pin) == PM3_SUCCESS; + status = send_pin(etd->pin); // If the write succeeded, read the rest of the tag - if (status) { + if (status == PM3_SUCCESS) { // Read Tag // ID doesn't change em4x70_read_um1(); @@ -892,7 +888,7 @@ void em4x70_write_pin(const em4x70_data_t *etd, bool ledcontrol) { void em4x70_write_key(const em4x70_data_t *etd, bool ledcontrol) { - uint8_t status = 0; + int status = PM3_ESOFT; command_parity = etd->parity; @@ -904,15 +900,15 @@ void em4x70_write_key(const em4x70_data_t *etd, bool ledcontrol) { // Read ID to ensure we can write to card if (em4x70_read_id()) { - status = 1; + status = PM3_SUCCESS; // Write each crypto block for (int i = 0; i < 6; i++) { uint16_t key_word = (etd->crypt_key[(i * 2) + 1] << 8) + etd->crypt_key[i * 2]; // Write each word, abort if any failure occurs - if (write(key_word, 9 - i) != PM3_SUCCESS) { - status = 0; + status = write(key_word, 9 - i); + if (status != PM3_SUCCESS) { break; } } diff --git a/client/src/cmdlfem4x70.c b/client/src/cmdlfem4x70.c index 72e75f904..da9b985f1 100644 --- a/client/src/cmdlfem4x70.c +++ b/client/src/cmdlfem4x70.c @@ -225,14 +225,10 @@ static int get_em4x70_info(const em4x70_cmd_input_info_t *opts, em4x70_tag_info_ if (WaitForResponseTimeout(CMD_LF_EM4X70_INFO, &resp, TIMEOUT) == false) { return PM3_ETIMEOUT; } - - //iceman: prefer to have specific return code check. - // like resp.status != PM3_SUCCESS if looking for failure - if (resp.status) { + if (resp.status == PM3_SUCCESS) { memcpy(data_out, resp.data.asBytes, sizeof(em4x70_tag_info_t)); - return PM3_SUCCESS; } - return PM3_ESOFT; + return resp.status; } static int writeblock_em4x70(const em4x70_cmd_input_writeblock_t *opts, em4x70_tag_info_t *data_out) { @@ -251,14 +247,10 @@ static int writeblock_em4x70(const em4x70_cmd_input_writeblock_t *opts, em4x70_t if (WaitForResponseTimeout(CMD_LF_EM4X70_WRITE, &resp, TIMEOUT) == false) { return PM3_ETIMEOUT; } - - //iceman: prefer to have specific return code check. - // like resp.status != PM3_SUCCESS if looking for failure - if (resp.status) { + if (resp.status == PM3_SUCCESS) { memcpy(data_out, resp.data.asBytes, sizeof(em4x70_tag_info_t)); - return PM3_SUCCESS; } - return PM3_ESOFT; + return resp.status; } static int auth_em4x70(const em4x70_cmd_input_auth_t *opts, em4x70_cmd_output_auth_t *data_out) { @@ -276,20 +268,15 @@ static int auth_em4x70(const em4x70_cmd_input_auth_t *opts, em4x70_cmd_output_au if (WaitForResponseTimeout(CMD_LF_EM4X70_AUTH, &resp, TIMEOUT) == false) { return PM3_ETIMEOUT; } - - //iceman: prefer to have specific return code check. - // like resp.status != PM3_SUCCESS if looking for failure - if (resp.status) { + if (resp.status == PM3_SUCCESS) { // Response is 20-bit from tag - // HACKHACK -- It appears the byte order differs from what is expected? data_out->grn.grn[0] = resp.data.asBytes[2]; data_out->grn.grn[1] = resp.data.asBytes[1]; data_out->grn.grn[2] = resp.data.asBytes[0]; //memcpy(data_out, &resp.data.asBytes[0], sizeof(ID48LIB_GRN)); - return PM3_SUCCESS; } - return PM3_ESOFT; + return resp.status; } static int setkey_em4x70(const em4x70_cmd_input_setkey_t *opts) { @@ -305,13 +292,7 @@ static int setkey_em4x70(const em4x70_cmd_input_setkey_t *opts) { if (WaitForResponseTimeout(CMD_LF_EM4X70_SETKEY, &resp, TIMEOUT) == false) { return PM3_ETIMEOUT; } - - //iceman: prefer to have specific return code check. - // like resp.status != PM3_SUCCESS if looking for failure - if (resp.status) { - return PM3_SUCCESS; - } - return PM3_ESOFT; + return resp.status; } static int brute_em4x70(const em4x70_cmd_input_brute_t *opts, em4x70_cmd_output_brute_t *data_out) { @@ -346,14 +327,10 @@ static int brute_em4x70(const em4x70_cmd_input_brute_t *opts, em4x70_cmd_output_ } if (WaitForResponseTimeout(CMD_LF_EM4X70_BRUTE, &resp, TIMEOUT)) { - - //iceman: prefer to have specific return code check. - // like resp.status != PM3_SUCCESS if looking for failure - if (resp.status) { + if (resp.status == PM3_SUCCESS) { memcpy(data_out, resp.data.asBytes, sizeof(em4x70_cmd_output_brute_t)); - return PM3_SUCCESS; } - return PM3_ESOFT; + return resp.status; } // NOTE: It takes about 11 seconds per 0x0100 authentication attempts. @@ -383,15 +360,10 @@ static int unlock_em4x70(const em4x70_cmd_input_unlock_t *opts, em4x70_tag_info_ if (WaitForResponseTimeout(CMD_LF_EM4X70_UNLOCK, &resp, TIMEOUT) == false) { return PM3_ETIMEOUT; } - - //iceman: prefer to have specific return code check. - // like resp.status != PM3_SUCCESS if looking for failure - if (resp.status) { + if (resp.status == PM3_SUCCESS) { memcpy(data_out, resp.data.asBytes, sizeof(em4x70_tag_info_t)); - return PM3_SUCCESS; } - return PM3_ESOFT; - + return resp.status; } static int setpin_em4x70(const em4x70_cmd_input_setpin_t *opts, em4x70_tag_info_t *data_out) { @@ -408,14 +380,10 @@ static int setpin_em4x70(const em4x70_cmd_input_setpin_t *opts, em4x70_tag_info_ if (WaitForResponseTimeout(CMD_LF_EM4X70_SETPIN, &resp, TIMEOUT) == false) { return PM3_ETIMEOUT; } - - //iceman: prefer to have specific return code check. - // like resp.status != PM3_SUCCESS if looking for failure - if (resp.status) { + if (resp.status == PM3_SUCCESS) { memcpy(data_out, resp.data.asBytes, sizeof(em4x70_tag_info_t)); - return PM3_SUCCESS; } - return PM3_ESOFT; + return resp.status; } static int recover_em4x70(const em4x70_cmd_input_recover_t *opts, em4x70_cmd_output_recover_t *data_out) {