cppcheck duplicatecondition

This commit is contained in:
Philippe Teuwen 2025-03-24 21:59:52 +01:00
commit 4fff85d6ed

View file

@ -1186,38 +1186,36 @@ static int CmdEM4x70AutoRecover(const char *Cmd) {
// 1. Verify passed parameters authenticate with the tag (safety check)
// lf em 4x70 auth --rnd <rnd_1> --frn <frn_1>
if (PM3_SUCCESS == result) {
PrintAndLogEx(INFO, "Step 1. Verifying passed parameters authenticate with the tag (safety check)");
PrintAndLogEx(HINT, "Hint: " _YELLOW_("lf em 4x70 auth --rnd %s --frn %s"), rnd_string, frn_string);
PrintAndLogEx(INFO, "Step 1. Verifying passed parameters authenticate with the tag (safety check)");
PrintAndLogEx(HINT, "Hint: " _YELLOW_("lf em 4x70 auth --rnd %s --frn %s"), rnd_string, frn_string);
em4x70_cmd_input_auth_t opts_auth = {
.use_parity = opts.parity,
.rn = opts.nonce,
.frn = opts.frn,
};
em4x70_cmd_input_auth_t opts_auth = {
.use_parity = opts.parity,
.rn = opts.nonce,
.frn = opts.frn,
};
em4x70_cmd_output_auth_t tag_grn;
em4x70_cmd_output_auth_t tag_grn;
result = auth_em4x70(&opts_auth, &tag_grn);
result = auth_em4x70(&opts_auth, &tag_grn);
if (PM3_ETIMEOUT == result) {
PrintAndLogEx(WARNING, "timeout while waiting for reply");
return result;
} else if (PM3_SUCCESS != result) {
PrintAndLogEx(FAILED, "Authenticating with provided values ( " _RED_("fail") " )");
return result;
} else if (memcmp(&opts.grn, &tag_grn, sizeof(ID48LIB_GRN)) != 0) {
PrintAndLogEx(FAILED, "Authenticating with new key returned %02x %02x %02x"
, tag_grn.grn.grn[0]
, tag_grn.grn.grn[1]
, tag_grn.grn.grn[2]
);
PrintAndLogEx(FAILED, "Expected %s [maybe 5 lsb of key wrong?] ( " _RED_("fail") " )", grn_string);
result = PM3_EWRONGANSWER;
return result;
}
last_successful_step = 1;
if (PM3_ETIMEOUT == result) {
PrintAndLogEx(WARNING, "timeout while waiting for reply");
return result;
} else if (PM3_SUCCESS != result) {
PrintAndLogEx(FAILED, "Authenticating with provided values ( " _RED_("fail") " )");
return result;
} else if (memcmp(&opts.grn, &tag_grn, sizeof(ID48LIB_GRN)) != 0) {
PrintAndLogEx(FAILED, "Authenticating with new key returned %02x %02x %02x"
, tag_grn.grn.grn[0]
, tag_grn.grn.grn[1]
, tag_grn.grn.grn[2]
);
PrintAndLogEx(FAILED, "Expected %s [maybe 5 lsb of key wrong?] ( " _RED_("fail") " )", grn_string);
result = PM3_EWRONGANSWER;
return result;
}
last_successful_step = 1;
// 2/3/4. Brute force the key bits in block 7,8,9
// lf em 4x70 write -b N -d 0000
@ -1232,98 +1230,88 @@ static int CmdEM4x70AutoRecover(const char *Cmd) {
em4x70_cmd_output_brute_t brute = {0};
// lf em 4x70 write -b N -d 0000
if (PM3_SUCCESS == result) {
PrintAndLogEx(INFO, "Step %d. Brute force the key bits in block %d", step, block);
PrintAndLogEx(HINT, "Hint: " _YELLOW_("lf em 4x70 write -b %d -d 0000"), block);
PrintAndLogEx(INFO, "Step %d. Brute force the key bits in block %d", step, block);
PrintAndLogEx(HINT, "Hint: " _YELLOW_("lf em 4x70 write -b %d -d 0000"), block);
em4x70_cmd_input_writeblock_t opt_write_zeros = {
.use_parity = opts.parity,
.block = block,
.value = {0x00, 0x00},
};
em4x70_cmd_input_writeblock_t opt_write_zeros = {
.use_parity = opts.parity,
.block = block,
.value = {0x00, 0x00},
};
result = writeblock_em4x70(&opt_write_zeros, &tag_info);
result = writeblock_em4x70(&opt_write_zeros, &tag_info);
if (PM3_ETIMEOUT == result) {
PrintAndLogEx(FAILED, "timeout while waiting for reply");
PrintAndLogEx(HINT, "Hint: Block %d data may have been overwritten. Manually restart at step %d", block, step);
return result;
} else if (PM3_SUCCESS != result) {
PrintAndLogEx(FAILED, "Writing block %d ( " _RED_("fail") " )", block);
PrintAndLogEx(HINT, "Hint: Block %d data was overwritten. Manually restart at step %d", block, step);
return result;
}
if (PM3_ETIMEOUT == result) {
PrintAndLogEx(FAILED, "timeout while waiting for reply");
PrintAndLogEx(HINT, "Hint: Block %d data may have been overwritten. Manually restart at step %d", block, step);
return result;
} else if (PM3_SUCCESS != result) {
PrintAndLogEx(FAILED, "Writing block %d ( " _RED_("fail") " )", block);
PrintAndLogEx(HINT, "Hint: Block %d data was overwritten. Manually restart at step %d", block, step);
return result;
}
// lf em 4x70 brute -b N --rnd <rnd_1> --frn <frn_1>
if (PM3_SUCCESS == result) {
PrintAndLogEx(HINT, "Hint: " _YELLOW_("lf em 4x70 brute -b %d --rnd %s --frn %s"), block, rnd_string, frn_string);
PrintAndLogEx(HINT, "Hint: " _YELLOW_("lf em 4x70 brute -b %d --rnd %s --frn %s"), block, rnd_string, frn_string);
em4x70_cmd_input_brute_t opts_brute = {
.use_parity = opts.parity,
.block = block,
.rn = opts.nonce,
.frn = opts.frn,
.partial_key_start = {0},
};
em4x70_cmd_input_brute_t opts_brute = {
.use_parity = opts.parity,
.block = block,
.rn = opts.nonce,
.frn = opts.frn,
.partial_key_start = {0},
};
result = brute_em4x70(&opts_brute, &brute);
result = brute_em4x70(&opts_brute, &brute);
if (PM3_ETIMEOUT == result) {
PrintAndLogEx(FAILED, "timeout while waiting for reply");
PrintAndLogEx(HINT, "Hint: Block %d data was overwritten. Manually restart at step %d", block, step);
return result;
} else if (PM3_SUCCESS != result) {
PrintAndLogEx(FAILED, "Writing block %d ( " _RED_("fail") " )", block);
PrintAndLogEx(HINT, "Hint: Block %d data was overwritten. Manually restart at step %d", block, step);
return result;
} else {
PrintAndLogEx(INFO, " Found: Partial key in block %d is " _GREEN_("%02X%02X")
, block
, brute.partial_key[0]
, brute.partial_key[1]
);
// Save the partial key...
if (block == 9) {
opts.key.k[0] = brute.partial_key[0];
opts.key.k[1] = brute.partial_key[1];
} else if (block == 8) {
opts.key.k[2] = brute.partial_key[0];
opts.key.k[3] = brute.partial_key[1];
} else if (block == 7) {
opts.key.k[4] = brute.partial_key[0];
opts.key.k[5] = brute.partial_key[1];
}
if (PM3_ETIMEOUT == result) {
PrintAndLogEx(FAILED, "timeout while waiting for reply");
PrintAndLogEx(HINT, "Hint: Block %d data was overwritten. Manually restart at step %d", block, step);
return result;
} else if (PM3_SUCCESS != result) {
PrintAndLogEx(FAILED, "Writing block %d ( " _RED_("fail") " )", block);
PrintAndLogEx(HINT, "Hint: Block %d data was overwritten. Manually restart at step %d", block, step);
return result;
} else {
PrintAndLogEx(INFO, " Found: Partial key in block %d is " _GREEN_("%02X%02X")
, block
, brute.partial_key[0]
, brute.partial_key[1]
);
// Save the partial key...
if (block == 9) {
opts.key.k[0] = brute.partial_key[0];
opts.key.k[1] = brute.partial_key[1];
} else if (block == 8) {
opts.key.k[2] = brute.partial_key[0];
opts.key.k[3] = brute.partial_key[1];
} else if (block == 7) {
opts.key.k[4] = brute.partial_key[0];
opts.key.k[5] = brute.partial_key[1];
}
}
// lf em 4x70 write -b N -d <key_block_N>
if (PM3_SUCCESS == result) {
PrintAndLogEx(HINT, "Hint: " _YELLOW_("lf em 4x70 write -b %d -d %02X%02X"), block, brute.partial_key[0], brute.partial_key[1]);
PrintAndLogEx(HINT, "Hint: " _YELLOW_("lf em 4x70 write -b %d -d %02X%02X"), block, brute.partial_key[0], brute.partial_key[1]);
em4x70_cmd_input_writeblock_t opt_write_zeros = {
.use_parity = opts.parity,
.block = block,
.value = {brute.partial_key[0], brute.partial_key[1]},
};
em4x70_cmd_input_writeblock_t opt_write_zeros2 = {
.use_parity = opts.parity,
.block = block,
.value = {brute.partial_key[0], brute.partial_key[1]},
};
result = writeblock_em4x70(&opt_write_zeros, &tag_info);
result = writeblock_em4x70(&opt_write_zeros2, &tag_info);
if (PM3_ETIMEOUT == result) {
PrintAndLogEx(FAILED, "timeout while waiting for reply");
PrintAndLogEx(HINT, "Hint: Block %d data (" _GREEN_("%02X%02X") ") may need to be rewritten", block, brute.partial_key[0], brute.partial_key[1]);
return result;
} else if (PM3_SUCCESS != result) {
PrintAndLogEx(FAILED, "Writing block %d ( " _RED_("fail") " )", block);
PrintAndLogEx(HINT, "Hint: Block %d data (" _GREEN_("%02X%02X") ") may need to be rewritten", block, brute.partial_key[0], brute.partial_key[1]);
return result;
}
if (PM3_ETIMEOUT == result) {
PrintAndLogEx(FAILED, "timeout while waiting for reply");
PrintAndLogEx(HINT, "Hint: Block %d data (" _GREEN_("%02X%02X") ") may need to be rewritten", block, brute.partial_key[0], brute.partial_key[1]);
return result;
} else if (PM3_SUCCESS != result) {
PrintAndLogEx(FAILED, "Writing block %d ( " _RED_("fail") " )", block);
PrintAndLogEx(HINT, "Hint: Block %d data (" _GREEN_("%02X%02X") ") may need to be rewritten", block, brute.partial_key[0], brute.partial_key[1]);
return result;
}
if (PM3_SUCCESS == result) {
last_successful_step = step;
} else {
break;
}
last_successful_step = step;
}
// The good news is that, if the above succeeded, then from this point forward, the tag remains in a known-good state.
@ -1332,108 +1320,102 @@ static int CmdEM4x70AutoRecover(const char *Cmd) {
// 5. Recover potential values of the lower 48 bits of the key
// lf em 4x70 recover --key <key_block_9><key_block_8><key_block_7> --rnd <rnd_1> --frn <frn_1>
if (PM3_SUCCESS == result) {
PrintAndLogEx(INFO, "Step 5. Recover potential values of the lower 48 bits of the key");
PrintAndLogEx(HINT, "Hint: " _YELLOW_("lf em 4x70 recover --key %s --rnd %s --frn %s --grn %s"), key_string, rnd_string, frn_string, grn_string);
PrintAndLogEx(INFO, "Step 5. Recover potential values of the lower 48 bits of the key");
PrintAndLogEx(HINT, "Hint: " _YELLOW_("lf em 4x70 recover --key %s --rnd %s --frn %s --grn %s"), key_string, rnd_string, frn_string, grn_string);
result = recover_em4x70(&opts, &data);
result = recover_em4x70(&opts, &data);
if (PM3_EOVFLOW == result) {
PrintAndLogEx(ERR, "Found more than %d potential keys. This is unexpected and likely a code failure.", MAXIMUM_ID48_RECOVERED_KEY_COUNT);
return result;
} else if (PM3_SUCCESS != result) {
PrintAndLogEx(ERR, "No potential keys recovered. This is unexpected and likely a code failure.");
return result;
} else {
PrintAndLogEx(INFO, " Found " _GREEN_("%d") " potential keys", data.potential_key_count);
for (uint8_t idx = 0; idx < data.potential_key_count; ++idx) {
ID48LIB_KEY q = data.potential_keys[idx];
PrintAndLogEx(DEBUG, " Potential Key %d: %s %02X%02X%02X%02X%02X%02X"
, idx
, key_string
, q.k[ 6]
, q.k[ 7]
, q.k[ 8]
, q.k[ 9]
, q.k[10]
, q.k[11]
);
}
last_successful_step = 5;
if (PM3_EOVFLOW == result) {
PrintAndLogEx(ERR, "Found more than %d potential keys. This is unexpected and likely a code failure.", MAXIMUM_ID48_RECOVERED_KEY_COUNT);
return result;
} else if (PM3_SUCCESS != result) {
PrintAndLogEx(ERR, "No potential keys recovered. This is unexpected and likely a code failure.");
return result;
} else {
PrintAndLogEx(INFO, " Found " _GREEN_("%d") " potential keys", data.potential_key_count);
for (uint8_t idx = 0; idx < data.potential_key_count; ++idx) {
ID48LIB_KEY q = data.potential_keys[idx];
PrintAndLogEx(DEBUG, " Potential Key %d: %s %02X%02X%02X%02X%02X%02X"
, idx
, key_string
, q.k[ 6]
, q.k[ 7]
, q.k[ 8]
, q.k[ 9]
, q.k[10]
, q.k[11]
);
}
last_successful_step = 5;
}
// 6. Verify which potential key is actually on the tag (using a different rnd/frn combination)
// lf em 4x70 auth --rnd <rnd_2> --frn <frn_N>
if (PM3_SUCCESS == result) {
PrintAndLogEx(INFO, "Step 6. Verify which potential key is actually on the tag");
PrintAndLogEx(INFO, "Step 6. Verify which potential key is actually on the tag");
em4x70_cmd_input_verify_auth_t opts_v = {
.use_parity = opts.parity,
//.rn = {{0}},
//.frn = {{0}},
//.grn = {{0}},
};
em4x70_cmd_input_verify_auth_t opts_v = {
.use_parity = opts.parity,
//.rn = {{0}},
//.frn = {{0}},
//.grn = {{0}},
};
// TODO: retry a few time, if >1 key validated with the new nonce
bool continue_loop = true;
bool found_one_key = false;
bool found_more_than_one_key = false;
uint8_t first_validated_key_idx = 0xFF;
// TODO: retry a few time, if >1 key validated with the new nonce
bool continue_loop = true;
bool found_one_key = false;
bool found_more_than_one_key = false;
uint8_t first_validated_key_idx = 0xFF;
for (uint8_t attempt = 0; continue_loop && (attempt < 10); ++attempt) {
continue_loop = false;
found_one_key = false;
found_more_than_one_key = false;
first_validated_key_idx = 0xFF;
fill_buffer_prng_bytes(&opts_v.rn, sizeof(ID48LIB_NONCE));
for (uint8_t attempt = 0; continue_loop && (attempt < 10); ++attempt) {
continue_loop = false;
found_one_key = false;
found_more_than_one_key = false;
first_validated_key_idx = 0xFF;
fill_buffer_prng_bytes(&opts_v.rn, sizeof(ID48LIB_NONCE));
for (uint8_t i = 0; i < data.potential_key_count; ++i) {
// generate the alternate frn/grn for this key + nonce combo
id48lib_generator(&data.potential_keys[i], &opts_v.rn, &opts_v.frn, &opts_v.grn);
for (uint8_t i = 0; i < data.potential_key_count; ++i) {
// generate the alternate frn/grn for this key + nonce combo
id48lib_generator(&data.potential_keys[i], &opts_v.rn, &opts_v.frn, &opts_v.grn);
int tmpResult = verify_auth_em4x70(&opts_v);
if (PM3_SUCCESS == tmpResult) {
if (!found_one_key) {
first_validated_key_idx = i;
found_one_key = true;
} else {
found_more_than_one_key = true;
}
int tmpResult = verify_auth_em4x70(&opts_v);
if (PM3_SUCCESS == tmpResult) {
if (!found_one_key) {
first_validated_key_idx = i;
found_one_key = true;
} else {
found_more_than_one_key = true;
}
}
if (found_one_key == false) {
PrintAndLogEx(WARNING, "No potential keys validated. Will try again with different nonce");
continue_loop = true;
msleep(2000); // delay 2 seconds ... in case tag was bumped, etc.
} else if (found_more_than_one_key) {
PrintAndLogEx(WARNING, "Multiple potential keys validated. Will try different nonce");
continue_loop = true;
msleep(2000); // delay 2 seconds ... in case tag was bumped, etc.
} else {
last_successful_step = 6;
}
}
if ((found_one_key == false) || found_more_than_one_key) {
PrintAndLogEx(FAILED, "Unable to recover any of the multiple potential keys");
PrintAndLogEx(FAILED, "Check tag for good coupling / position!");
return PM3_EFAILED;
if (found_one_key == false) {
PrintAndLogEx(WARNING, "No potential keys validated. Will try again with different nonce");
continue_loop = true;
msleep(2000); // delay 2 seconds ... in case tag was bumped, etc.
} else if (found_more_than_one_key) {
PrintAndLogEx(WARNING, "Multiple potential keys validated. Will try different nonce");
continue_loop = true;
msleep(2000); // delay 2 seconds ... in case tag was bumped, etc.
} else {
// print the validated key to the string buffer (for step 7)
ID48LIB_KEY q = data.potential_keys[first_validated_key_idx];
snprintf(key_string, 25, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
q.k[ 0], q.k[ 1], q.k[ 2], q.k[ 3], q.k[ 4], q.k[ 5],
q.k[ 6], q.k[ 7], q.k[ 8], q.k[ 9], q.k[10], q.k[11]
);
last_successful_step = 6;
}
}
if ((found_one_key == false) || found_more_than_one_key) {
PrintAndLogEx(FAILED, "Unable to recover any of the multiple potential keys");
PrintAndLogEx(FAILED, "Check tag for good coupling / position!");
return PM3_EFAILED;
} else {
// print the validated key to the string buffer (for step 7)
ID48LIB_KEY q = data.potential_keys[first_validated_key_idx];
snprintf(key_string, 25, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
q.k[ 0], q.k[ 1], q.k[ 2], q.k[ 3], q.k[ 4], q.k[ 5],
q.k[ 6], q.k[ 7], q.k[ 8], q.k[ 9], q.k[10], q.k[11]
);
}
// 7. Print the validated key
if (PM3_SUCCESS == result) {
PrintAndLogEx(SUCCESS, "Recovered key... " _GREEN_("%s"), key_string);
last_successful_step = 7;
}
PrintAndLogEx(SUCCESS, "Recovered key... " _GREEN_("%s"), key_string);
last_successful_step = 7;
// For posterity, step 7 used to do the following:
// 7. Print the validated key --OR-- Print that the tag is still OK --OR-- Print instructions on what to retry to recover tag to a good state