mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-03-22 05:00:29 +08:00
whitespace
This commit is contained in:
parent
f805e5c7c7
commit
57788d5751
4 changed files with 230 additions and 321 deletions
|
@ -1401,7 +1401,6 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
|
||||||
// hitagS settings
|
// hitagS settings
|
||||||
t_wait_1 = 204;
|
t_wait_1 = 204;
|
||||||
t_wait_2 = 128;
|
t_wait_2 = 128;
|
||||||
/*tag_size = 256;*/
|
|
||||||
flipped_bit = 0;
|
flipped_bit = 0;
|
||||||
tag_size = 8;
|
tag_size = 8;
|
||||||
DBG DbpString("Configured for hitagS reader");
|
DBG DbpString("Configured for hitagS reader");
|
||||||
|
|
|
@ -40,8 +40,7 @@ bool hitag2_crack(uint8_t *response, uint8_t *nrarhex) {
|
||||||
uint8_t *spaceptr = NULL;
|
uint8_t *spaceptr = NULL;
|
||||||
|
|
||||||
// get uid as hexstring
|
// get uid as hexstring
|
||||||
if(!hitag2_get_uid(uidhex))
|
if (!hitag2_get_uid(uidhex)) {
|
||||||
{
|
|
||||||
UserMessage("Cannot get UID\r\n");
|
UserMessage("Cannot get UID\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -51,35 +50,30 @@ bool hitag2_crack(uint8_t *response, uint8_t *nrarhex) {
|
||||||
|
|
||||||
// convert nR and aR hexstrings to binarray
|
// convert nR and aR hexstrings to binarray
|
||||||
spaceptr = strchr(nrarhex, ' ');
|
spaceptr = strchr(nrarhex, ' ');
|
||||||
if (!spaceptr)
|
if (!spaceptr) {
|
||||||
{
|
|
||||||
UserMessage("Please supply a valid nR aR pair\r\n");
|
UserMessage("Please supply a valid nR aR pair\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*spaceptr = 0x00;
|
*spaceptr = 0x00;
|
||||||
|
|
||||||
if (hextobinarray(nrar, nrarhex) != 32)
|
if (hextobinarray(nrar, nrarhex) != 32) {
|
||||||
{
|
|
||||||
UserMessage("nR is not 32 bits long\r\n");
|
UserMessage("nR is not 32 bits long\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hextobinarray(nrar + 32, spaceptr + 1) != 32)
|
if (hextobinarray(nrar + 32, spaceptr + 1) != 32) {
|
||||||
{
|
|
||||||
UserMessage("aR is not 32 bits long\r\n");
|
UserMessage("aR is not 32 bits long\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find a valid encrypted command
|
// find a valid encrypted command
|
||||||
if (!hitag2crack_find_valid_e_cmd(e_firstcmd, nrar))
|
if (!hitag2crack_find_valid_e_cmd(e_firstcmd, nrar)) {
|
||||||
{
|
|
||||||
UserMessage("Cannot find a valid encrypted command\r\n");
|
UserMessage("Cannot find a valid encrypted command\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the 'read page 0' command and recover key stream
|
// find the 'read page 0' command and recover key stream
|
||||||
if (!hitag2crack_find_e_page0_cmd(keybits, e_firstcmd, nrar, uid))
|
if (!hitag2crack_find_e_page0_cmd(keybits, e_firstcmd, nrar, uid)) {
|
||||||
{
|
|
||||||
UserMessage("Cannot find encrypted 'read page0' command\r\n");
|
UserMessage("Cannot find encrypted 'read page0' command\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -88,14 +82,10 @@ bool hitag2_crack(uint8_t *response, uint8_t *nrarhex) {
|
||||||
response[0] = 0x00;
|
response[0] = 0x00;
|
||||||
|
|
||||||
// read all pages using key stream
|
// read all pages using key stream
|
||||||
for (i=0; i<8; i++)
|
for (i = 0; i < 8; i++) {
|
||||||
{
|
if (hitag2crack_read_page(pagehex, i, nrar, keybits)) {
|
||||||
if (hitag2crack_read_page(pagehex, i, nrar, keybits))
|
|
||||||
{
|
|
||||||
sprintf(temp, "%1d: %s\r\n", i, pagehex);
|
sprintf(temp, "%1d: %s\r\n", i, pagehex);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
sprintf(temp, "%1d:\r\n", i);
|
sprintf(temp, "%1d:\r\n", i);
|
||||||
}
|
}
|
||||||
// add page string to response
|
// add page string to response
|
||||||
|
@ -175,64 +165,49 @@ bool hitag2crack_find_e_page0_cmd(uint8_t keybits[], uint8_t e_firstcmd[], uint8
|
||||||
|
|
||||||
UserMessage("Finding 'read page 0' command:");
|
UserMessage("Finding 'read page 0' command:");
|
||||||
// we're going to brute the missing 4 bits of the valid encrypted command
|
// we're going to brute the missing 4 bits of the valid encrypted command
|
||||||
for (a=0; a<2; a++)
|
for (a = 0; a < 2; a++) {
|
||||||
{
|
for (b = 0; b < 2; b++) {
|
||||||
for (b=0; b<2; b++)
|
for (c = 0; c < 2; c++) {
|
||||||
{
|
for (d = 0; d < 2; d++) {
|
||||||
for (c=0; c<2; c++)
|
|
||||||
{
|
|
||||||
for (d=0; d<2; d++)
|
|
||||||
{
|
|
||||||
// create our guess by bit flipping the pattern of bits
|
// create our guess by bit flipping the pattern of bits
|
||||||
// representing the inverted bit and the 3 page bits
|
// representing the inverted bit and the 3 page bits
|
||||||
// in both the non-inverted and inverted parts of the
|
// in both the non-inverted and inverted parts of the
|
||||||
// encrypted command.
|
// encrypted command.
|
||||||
memcpy(guess, e_firstcmd, 10);
|
memcpy(guess, e_firstcmd, 10);
|
||||||
if (a)
|
if (a) {
|
||||||
{
|
|
||||||
guess[5] = !guess[5];
|
guess[5] = !guess[5];
|
||||||
guess[0] = !guess[0];
|
guess[0] = !guess[0];
|
||||||
}
|
}
|
||||||
if (b)
|
if (b) {
|
||||||
{
|
|
||||||
guess[7] = !guess[7];
|
guess[7] = !guess[7];
|
||||||
guess[2] = !guess[2];
|
guess[2] = !guess[2];
|
||||||
}
|
}
|
||||||
if (c)
|
if (c) {
|
||||||
{
|
|
||||||
guess[8] = !guess[8];
|
guess[8] = !guess[8];
|
||||||
guess[3] = !guess[3];
|
guess[3] = !guess[3];
|
||||||
}
|
}
|
||||||
if (d)
|
if (d) {
|
||||||
{
|
|
||||||
guess[9] = !guess[9];
|
guess[9] = !guess[9];
|
||||||
guess[4] = !guess[4];
|
guess[4] = !guess[4];
|
||||||
}
|
}
|
||||||
|
|
||||||
// try the guess
|
// try the guess
|
||||||
if (hitag2crack_send_e_cmd(responsestr, nrar, guess, 10))
|
if (hitag2crack_send_e_cmd(responsestr, nrar, guess, 10)) {
|
||||||
{
|
|
||||||
// check if it was valid
|
// check if it was valid
|
||||||
if (strcmp(responsestr, ERROR_RESPONSE) != 0)
|
if (strcmp(responsestr, ERROR_RESPONSE) != 0) {
|
||||||
{
|
|
||||||
// convert response to binarray
|
// convert response to binarray
|
||||||
hextobinarray(e_uid, responsestr);
|
hextobinarray(e_uid, responsestr);
|
||||||
// test if the guess was 'read page 0' command
|
// test if the guess was 'read page 0' command
|
||||||
if (hitag2crack_test_e_p0cmd(keybits, nrar, guess, uid, e_uid))
|
if (hitag2crack_test_e_p0cmd(keybits, nrar, guess, uid, e_uid)) {
|
||||||
{
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef RFIDLER_DEBUG
|
#ifdef RFIDLER_DEBUG
|
||||||
UserMessage("hitag2crack_find_e_page0_cmd:\r\n hitag2crack_send_e_cmd returned ERROR_RESPONSE\r\n");
|
UserMessage("hitag2crack_find_e_page0_cmd:\r\n hitag2crack_send_e_cmd returned ERROR_RESPONSE\r\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef RFIDLER_DEBUG
|
#ifdef RFIDLER_DEBUG
|
||||||
UserMessage("hitag2crack_find_e_page0_cmd:\r\n hitag2crack_send_e_cmd failed\r\n");
|
UserMessage("hitag2crack_find_e_page0_cmd:\r\n hitag2crack_send_e_cmd failed\r\n");
|
||||||
#endif
|
#endif
|
||||||
|
@ -279,8 +254,7 @@ bool hitag2crack_test_e_p0cmd(uint8_t *keybits, uint8_t *nrar, uint8_t *e_cmd, u
|
||||||
hitag2crack_xor(keybits, plainbits, cipherbits, 42);
|
hitag2crack_xor(keybits, plainbits, cipherbits, 42);
|
||||||
|
|
||||||
// create extended cmd -> 4 * READP0CMD = 40 bits
|
// create extended cmd -> 4 * READP0CMD = 40 bits
|
||||||
for (i=0; i<4; i++)
|
for (i = 0; i < 4; i++) {
|
||||||
{
|
|
||||||
binstringtobinarray(ext_cmd + (i * 10), READP0CMD);
|
binstringtobinarray(ext_cmd + (i * 10), READP0CMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,16 +262,12 @@ bool hitag2crack_test_e_p0cmd(uint8_t *keybits, uint8_t *nrar, uint8_t *e_cmd, u
|
||||||
hitag2crack_xor(e_ext_cmd, ext_cmd, keybits, 40);
|
hitag2crack_xor(e_ext_cmd, ext_cmd, keybits, 40);
|
||||||
|
|
||||||
// send extended encrypted cmd
|
// send extended encrypted cmd
|
||||||
if (hitag2crack_send_e_cmd(responsestr, nrar, e_ext_cmd, 40))
|
if (hitag2crack_send_e_cmd(responsestr, nrar, e_ext_cmd, 40)) {
|
||||||
{
|
|
||||||
// test if it was valid
|
// test if it was valid
|
||||||
if (strcmp(responsestr, ERROR_RESPONSE) != 0)
|
if (strcmp(responsestr, ERROR_RESPONSE) != 0) {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef RFIDLER_DEBUG
|
#ifdef RFIDLER_DEBUG
|
||||||
UserMessage("hitag2crack_test_e_p0cmd:\r\n hitag2crack_send_e_cmd failed\r\n");
|
UserMessage("hitag2crack_test_e_p0cmd:\r\n hitag2crack_send_e_cmd failed\r\n");
|
||||||
#endif
|
#endif
|
||||||
|
@ -330,26 +300,22 @@ bool hitag2crack_read_page(uint8_t *responsestr, uint8_t pagenum, uint8_t *nrar,
|
||||||
uint8_t response[32];
|
uint8_t response[32];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((pagenum < 0) || (pagenum > 7))
|
if ((pagenum < 0) || (pagenum > 7)) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_read_page:\r\n invalid pagenum\r\n");
|
UserMessage("hitag2crack_read_page:\r\n invalid pagenum\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create cmd
|
// create cmd
|
||||||
binstringtobinarray(cmd, READP0CMD);
|
binstringtobinarray(cmd, READP0CMD);
|
||||||
if (pagenum & 0x1)
|
if (pagenum & 0x1) {
|
||||||
{
|
|
||||||
cmd[9] = !cmd[9];
|
cmd[9] = !cmd[9];
|
||||||
cmd[4] = !cmd[4];
|
cmd[4] = !cmd[4];
|
||||||
}
|
}
|
||||||
if (pagenum & 0x2)
|
if (pagenum & 0x2) {
|
||||||
{
|
|
||||||
cmd[8] = !cmd[8];
|
cmd[8] = !cmd[8];
|
||||||
cmd[3] = !cmd[3];
|
cmd[3] = !cmd[3];
|
||||||
}
|
}
|
||||||
if (pagenum & 0x4)
|
if (pagenum & 0x4) {
|
||||||
{
|
|
||||||
cmd[7] = !cmd[7];
|
cmd[7] = !cmd[7];
|
||||||
cmd[2] = !cmd[2];
|
cmd[2] = !cmd[2];
|
||||||
}
|
}
|
||||||
|
@ -358,11 +324,9 @@ bool hitag2crack_read_page(uint8_t *responsestr, uint8_t pagenum, uint8_t *nrar,
|
||||||
hitag2crack_xor(e_cmd, cmd, keybits, 10);
|
hitag2crack_xor(e_cmd, cmd, keybits, 10);
|
||||||
|
|
||||||
// send encrypted command
|
// send encrypted command
|
||||||
if (hitag2crack_send_e_cmd(e_responsestr, nrar, e_cmd, 10))
|
if (hitag2crack_send_e_cmd(e_responsestr, nrar, e_cmd, 10)) {
|
||||||
{
|
|
||||||
// check if it is valid
|
// check if it is valid
|
||||||
if (strcmp(e_responsestr, ERROR_RESPONSE) != 0)
|
if (strcmp(e_responsestr, ERROR_RESPONSE) != 0) {
|
||||||
{
|
|
||||||
// convert to binarray
|
// convert to binarray
|
||||||
hextobinarray(e_response, e_responsestr);
|
hextobinarray(e_response, e_responsestr);
|
||||||
// decrypt response
|
// decrypt response
|
||||||
|
@ -370,14 +334,10 @@ bool hitag2crack_read_page(uint8_t *responsestr, uint8_t pagenum, uint8_t *nrar,
|
||||||
// convert to hexstring
|
// convert to hexstring
|
||||||
binarraytohex(responsestr, response, 32);
|
binarraytohex(responsestr, response, 32);
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_read_page:\r\n hitag2crack_send_e_cmd returned ERROR_RESPONSE\r\n");
|
UserMessage("hitag2crack_read_page:\r\n hitag2crack_send_e_cmd returned ERROR_RESPONSE\r\n");
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_read_page:\r\n hitag2crack_send_e_cmd failed\r\n");
|
UserMessage("hitag2crack_read_page:\r\n hitag2crack_send_e_cmd failed\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,8 +357,7 @@ bool hitag2crack_send_e_cmd(uint8_t *responsestr, uint8_t *nrar, uint8_t *cmd, i
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
// get the UID
|
// get the UID
|
||||||
if(!hitag2_get_uid(uid))
|
if (!hitag2_get_uid(uid)) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_send_e_cmd:\r\n cannot get UID\r\n");
|
UserMessage("hitag2crack_send_e_cmd:\r\n cannot get UID\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -407,22 +366,19 @@ bool hitag2crack_send_e_cmd(uint8_t *responsestr, uint8_t *nrar, uint8_t *cmd, i
|
||||||
CryptoActive = false;
|
CryptoActive = false;
|
||||||
|
|
||||||
// get the UID again
|
// get the UID again
|
||||||
if(!hitag2_get_uid(uid))
|
if (!hitag2_get_uid(uid)) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_send_e_cmd:\r\n cannot get UID (2nd time)\r\n");
|
UserMessage("hitag2crack_send_e_cmd:\r\n cannot get UID (2nd time)\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send nrar and receive (useless) encrypted page 3 value
|
// send nrar and receive (useless) encrypted page 3 value
|
||||||
if (!hitag2crack_tx_rx(e_page3str, nrar, 64, RWD_STATE_WAKING, false))
|
if (!hitag2crack_tx_rx(e_page3str, nrar, 64, RWD_STATE_WAKING, false)) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_send_e_cmd:\r\n tx/rx nrar failed\r\n");
|
UserMessage("hitag2crack_send_e_cmd:\r\n tx/rx nrar failed\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send encrypted command
|
// send encrypted command
|
||||||
if (!hitag2crack_tx_rx(responsestr, cmd, len, RWD_STATE_WAKING, false))
|
if (!hitag2crack_tx_rx(responsestr, cmd, len, RWD_STATE_WAKING, false)) {
|
||||||
{
|
|
||||||
#ifdef RFIDLER_DEBUG
|
#ifdef RFIDLER_DEBUG
|
||||||
UserMessage("hitag2crack_send_e_cmd:\r\n tx/rx cmd failed\r\n");
|
UserMessage("hitag2crack_send_e_cmd:\r\n tx/rx cmd failed\r\n");
|
||||||
#endif
|
#endif
|
||||||
|
@ -444,8 +400,7 @@ bool hitag2crack_tx_rx(uint8_t *responsestr, uint8_t *msg, int len, int state, b
|
||||||
// START_AUTH kills active crypto session
|
// START_AUTH kills active crypto session
|
||||||
CryptoActive = false;
|
CryptoActive = false;
|
||||||
|
|
||||||
if(!rwd_send(msg, len, reset, BLOCK, state, RFIDlerConfig.FrameClock, 0, RFIDlerConfig.RWD_Wait_Switch_RX_TX, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX))
|
if (!rwd_send(msg, len, reset, BLOCK, state, RFIDlerConfig.FrameClock, 0, RFIDlerConfig.RWD_Wait_Switch_RX_TX, RFIDlerConfig.RWD_Zero_Period, RFIDlerConfig.RWD_One_Period, RFIDlerConfig.RWD_Gap_Period, RFIDlerConfig.RWD_Wait_Switch_TX_RX)) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_tx_rx: rwd_send failed\r\n");
|
UserMessage("hitag2crack_tx_rx: rwd_send failed\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -455,11 +410,9 @@ bool hitag2crack_tx_rx(uint8_t *responsestr, uint8_t *msg, int len, int state, b
|
||||||
ret = read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, 37, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY);
|
ret = read_ask_data(RFIDlerConfig.FrameClock, RFIDlerConfig.DataRate, tmp, 37, RFIDlerConfig.Sync, RFIDlerConfig.SyncBits, RFIDlerConfig.Timeout, ONESHOT_READ, BINARY);
|
||||||
|
|
||||||
// check if response was a valid length (5 sync bits + 32 bits response)
|
// check if response was a valid length (5 sync bits + 32 bits response)
|
||||||
if (ret == 37)
|
if (ret == 37) {
|
||||||
{
|
|
||||||
// check sync bits
|
// check sync bits
|
||||||
if (memcmp(tmp, Hitag2Sync, 5) != 0)
|
if (memcmp(tmp, Hitag2Sync, 5) != 0) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_tx_rx: no sync\r\n");
|
UserMessage("hitag2crack_tx_rx: no sync\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -467,9 +420,7 @@ bool hitag2crack_tx_rx(uint8_t *responsestr, uint8_t *msg, int len, int state, b
|
||||||
// convert response to hexstring
|
// convert response to hexstring
|
||||||
binarraytohex(responsestr, tmp + 5, 32);
|
binarraytohex(responsestr, tmp + 5, 32);
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef RFIDLER_DEBUG
|
#ifdef RFIDLER_DEBUG
|
||||||
UserMessage("hitag2crack_tx_rx: wrong rx len\r\n");
|
UserMessage("hitag2crack_tx_rx: wrong rx len\r\n");
|
||||||
#endif
|
#endif
|
||||||
|
@ -489,16 +440,14 @@ bool hitag2crack_rng_init(uint8_t *response, uint8_t *input) {
|
||||||
// extract vals from input
|
// extract vals from input
|
||||||
dataptr = input;
|
dataptr = input;
|
||||||
spaceptr = strchr(dataptr, ' ');
|
spaceptr = strchr(dataptr, ' ');
|
||||||
if (!spaceptr)
|
if (!spaceptr) {
|
||||||
{
|
|
||||||
UserMessage("/r/nformat is 'sharedkey UID nR' in hex\r\n");
|
UserMessage("/r/nformat is 'sharedkey UID nR' in hex\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*spaceptr = 0x00;
|
*spaceptr = 0x00;
|
||||||
|
|
||||||
if (strlen(dataptr) != 12)
|
if (strlen(dataptr) != 12) {
|
||||||
{
|
|
||||||
UserMessage("/r/nsharedkey should be 48 bits long (12 hexchars)\r\n");
|
UserMessage("/r/nsharedkey should be 48 bits long (12 hexchars)\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -507,15 +456,13 @@ bool hitag2crack_rng_init(uint8_t *response, uint8_t *input) {
|
||||||
|
|
||||||
dataptr = spaceptr + 1;
|
dataptr = spaceptr + 1;
|
||||||
spaceptr = strchr(dataptr, ' ');
|
spaceptr = strchr(dataptr, ' ');
|
||||||
if (!spaceptr)
|
if (!spaceptr) {
|
||||||
{
|
|
||||||
UserMessage("/r/nno UID\r\n");
|
UserMessage("/r/nno UID\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*spaceptr = 0x00;
|
*spaceptr = 0x00;
|
||||||
if (strlen(dataptr) != 8)
|
if (strlen(dataptr) != 8) {
|
||||||
{
|
|
||||||
UserMessage("/r/nUID should be 32 bits long (8 hexchars)\r\n");
|
UserMessage("/r/nUID should be 32 bits long (8 hexchars)\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -524,8 +471,7 @@ bool hitag2crack_rng_init(uint8_t *response, uint8_t *input) {
|
||||||
|
|
||||||
dataptr = spaceptr + 1;
|
dataptr = spaceptr + 1;
|
||||||
|
|
||||||
if (strlen(dataptr) != 8)
|
if (strlen(dataptr) != 8) {
|
||||||
{
|
|
||||||
UserMessage("/r/nnR should be 32 bits long (8 hexchars)\r\n");
|
UserMessage("/r/nnR should be 32 bits long (8 hexchars)\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -546,8 +492,7 @@ bool hitag2crack_decrypt_hex(uint8_t *response, uint8_t *hex) {
|
||||||
uint8_t binstr[33];
|
uint8_t binstr[33];
|
||||||
uint32_t binulong;
|
uint32_t binulong;
|
||||||
|
|
||||||
if (strlen(hex) != 8)
|
if (strlen(hex) != 8) {
|
||||||
{
|
|
||||||
UserMessage("/r/nhex must be 32bits (8 hex chars)\r\n");
|
UserMessage("/r/nhex must be 32bits (8 hex chars)\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -572,8 +517,7 @@ bool hitag2crack_decrypt_bin(uint8_t *response, uint8_t *e_binstr) {
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
len = strlen(e_binstr);
|
len = strlen(e_binstr);
|
||||||
if (len > 32)
|
if (len > 32) {
|
||||||
{
|
|
||||||
UserMessage("\r\nbinary string must be <= 32 bits\r\n");
|
UserMessage("\r\nbinary string must be <= 32 bits\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -627,8 +571,7 @@ bool hitag2_keystream(uint8_t *response, uint8_t *nrarhex) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// get uid as hexstring
|
// get uid as hexstring
|
||||||
if(!hitag2_get_uid(uidhex))
|
if (!hitag2_get_uid(uidhex)) {
|
||||||
{
|
|
||||||
UserMessage("Cannot get UID\r\n");
|
UserMessage("Cannot get UID\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -638,35 +581,30 @@ bool hitag2_keystream(uint8_t *response, uint8_t *nrarhex) {
|
||||||
|
|
||||||
// convert nR and aR hexstrings to binarray
|
// convert nR and aR hexstrings to binarray
|
||||||
spaceptr = strchr(nrarhex, ' ');
|
spaceptr = strchr(nrarhex, ' ');
|
||||||
if (!spaceptr)
|
if (!spaceptr) {
|
||||||
{
|
|
||||||
UserMessage("Please supply a valid nR aR pair\r\n");
|
UserMessage("Please supply a valid nR aR pair\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*spaceptr = 0x00;
|
*spaceptr = 0x00;
|
||||||
|
|
||||||
if (hextobinarray(nrar, nrarhex) != 32)
|
if (hextobinarray(nrar, nrarhex) != 32) {
|
||||||
{
|
|
||||||
UserMessage("nR is not 32 bits long\r\n");
|
UserMessage("nR is not 32 bits long\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hextobinarray(nrar + 32, spaceptr + 1) != 32)
|
if (hextobinarray(nrar + 32, spaceptr + 1) != 32) {
|
||||||
{
|
|
||||||
UserMessage("aR is not 32 bits long\r\n");
|
UserMessage("aR is not 32 bits long\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find a valid encrypted command
|
// find a valid encrypted command
|
||||||
if (!hitag2crack_find_valid_e_cmd(e_firstcmd, nrar))
|
if (!hitag2crack_find_valid_e_cmd(e_firstcmd, nrar)) {
|
||||||
{
|
|
||||||
UserMessage("Cannot find a valid encrypted command\r\n");
|
UserMessage("Cannot find a valid encrypted command\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the 'read page 0' command and recover key stream
|
// find the 'read page 0' command and recover key stream
|
||||||
if (!hitag2crack_find_e_page0_cmd(keybits, e_firstcmd, nrar, uid))
|
if (!hitag2crack_find_e_page0_cmd(keybits, e_firstcmd, nrar, uid)) {
|
||||||
{
|
|
||||||
UserMessage("Cannot find encrypted 'read page0' command\r\n");
|
UserMessage("Cannot find encrypted 'read page0' command\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -675,30 +613,25 @@ bool hitag2_keystream(uint8_t *response, uint8_t *nrarhex) {
|
||||||
// increasing lengths to acquire 2048 bits of key stream.
|
// increasing lengths to acquire 2048 bits of key stream.
|
||||||
kslen = 40;
|
kslen = 40;
|
||||||
|
|
||||||
while (kslen < 2048)
|
while (kslen < 2048) {
|
||||||
{
|
|
||||||
ksoffset = 0;
|
ksoffset = 0;
|
||||||
if (!hitag2crack_send_auth(nrar))
|
if (!hitag2crack_send_auth(nrar)) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_send_auth failed\r\n");
|
UserMessage("hitag2crack_send_auth failed\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// while we have at least 52 bits of keystream, consume it with
|
// while we have at least 52 bits of keystream, consume it with
|
||||||
// extended read page 0 commands. 52 = 10 (min command len) +
|
// extended read page 0 commands. 52 = 10 (min command len) +
|
||||||
// 32 (response) + 10 (min command len we'll send)
|
// 32 (response) + 10 (min command len we'll send)
|
||||||
while ((kslen - ksoffset) >= 52)
|
while ((kslen - ksoffset) >= 52) {
|
||||||
{
|
|
||||||
// consume the keystream, updating ksoffset as we go
|
// consume the keystream, updating ksoffset as we go
|
||||||
if (!hitag2crack_consume_keystream(keybits, kslen, &ksoffset, nrar))
|
if (!hitag2crack_consume_keystream(keybits, kslen, &ksoffset, nrar)) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_consume_keystream failed\r\n");
|
UserMessage("hitag2crack_consume_keystream failed\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// send an extended command to retrieve more keystream, updating kslen
|
// send an extended command to retrieve more keystream, updating kslen
|
||||||
// as we go
|
// as we go
|
||||||
if (!hitag2crack_extend_keystream(keybits, &kslen, ksoffset, nrar, uid))
|
if (!hitag2crack_extend_keystream(keybits, &kslen, ksoffset, nrar, uid)) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_extend_keystream failed\r\n");
|
UserMessage("hitag2crack_extend_keystream failed\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -706,8 +639,7 @@ bool hitag2_keystream(uint8_t *response, uint8_t *nrarhex) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<2048; i+=256)
|
for (i = 0; i < 2048; i += 256) {
|
||||||
{
|
|
||||||
binarraytohex(keybitshex, keybits + i, 256);
|
binarraytohex(keybitshex, keybits + i, 256);
|
||||||
UserMessage("%s\r\n", keybitshex);
|
UserMessage("%s\r\n", keybitshex);
|
||||||
}
|
}
|
||||||
|
@ -724,8 +656,7 @@ bool hitag2crack_send_auth(uint8_t *nrar) {
|
||||||
uint8_t e_page3str[9];
|
uint8_t e_page3str[9];
|
||||||
|
|
||||||
// get the UID
|
// get the UID
|
||||||
if(!hitag2_get_uid(uid))
|
if (!hitag2_get_uid(uid)) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_send_auth:\r\n cannot get UID\r\n");
|
UserMessage("hitag2crack_send_auth:\r\n cannot get UID\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -734,15 +665,13 @@ bool hitag2crack_send_auth(uint8_t *nrar) {
|
||||||
CryptoActive = false;
|
CryptoActive = false;
|
||||||
|
|
||||||
// get the UID again
|
// get the UID again
|
||||||
if(!hitag2_get_uid(uid))
|
if (!hitag2_get_uid(uid)) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_send_auth:\r\n cannot get UID (2nd time)\r\n");
|
UserMessage("hitag2crack_send_auth:\r\n cannot get UID (2nd time)\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send nrar and receive (useless) encrypted page 3 value
|
// send nrar and receive (useless) encrypted page 3 value
|
||||||
if (!hitag2crack_tx_rx(e_page3str, nrar, 64, RWD_STATE_WAKING, false))
|
if (!hitag2crack_tx_rx(e_page3str, nrar, 64, RWD_STATE_WAKING, false)) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_send_auth:\r\n tx/rx nrar failed\r\n");
|
UserMessage("hitag2crack_send_auth:\r\n tx/rx nrar failed\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -767,15 +696,13 @@ bool hitag2crack_consume_keystream(uint8_t *keybits, int kslen, int *ksoffset, u
|
||||||
// 42 = 32 bit response + 10 bit command reserved for next command. conlen
|
// 42 = 32 bit response + 10 bit command reserved for next command. conlen
|
||||||
// cannot be longer than 510 bits to fit into the small RWD buffer.
|
// cannot be longer than 510 bits to fit into the small RWD buffer.
|
||||||
conlen = kslen - *ksoffset - 42;
|
conlen = kslen - *ksoffset - 42;
|
||||||
if (conlen < 10)
|
if (conlen < 10) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_consume_keystream:\r\n conlen < 10\r\n");
|
UserMessage("hitag2crack_consume_keystream:\r\n conlen < 10\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sanitise conlen
|
// sanitise conlen
|
||||||
if (conlen > 510)
|
if (conlen > 510) {
|
||||||
{
|
|
||||||
conlen = 510;
|
conlen = 510;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -783,8 +710,7 @@ bool hitag2crack_consume_keystream(uint8_t *keybits, int kslen, int *ksoffset, u
|
||||||
numcmds = conlen / 10;
|
numcmds = conlen / 10;
|
||||||
|
|
||||||
// build extended command
|
// build extended command
|
||||||
for (i=0; i<numcmds; i++)
|
for (i = 0; i < numcmds; i++) {
|
||||||
{
|
|
||||||
binstringtobinarray(ext_cmd + (i * 10), READP0CMD);
|
binstringtobinarray(ext_cmd + (i * 10), READP0CMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -792,15 +718,13 @@ bool hitag2crack_consume_keystream(uint8_t *keybits, int kslen, int *ksoffset, u
|
||||||
hitag2crack_xor(e_ext_cmd, ext_cmd, keybits + *ksoffset, numcmds * 10);
|
hitag2crack_xor(e_ext_cmd, ext_cmd, keybits + *ksoffset, numcmds * 10);
|
||||||
|
|
||||||
// send encrypted command
|
// send encrypted command
|
||||||
if (!hitag2crack_tx_rx(responsestr, e_ext_cmd, numcmds * 10, RWD_STATE_WAKING, false))
|
if (!hitag2crack_tx_rx(responsestr, e_ext_cmd, numcmds * 10, RWD_STATE_WAKING, false)) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_consume_keystream:\r\n tx/rx cmd failed\r\n");
|
UserMessage("hitag2crack_consume_keystream:\r\n tx/rx cmd failed\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test response
|
// test response
|
||||||
if (strcmp(responsestr, ERROR_RESPONSE) == 0)
|
if (strcmp(responsestr, ERROR_RESPONSE) == 0) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_consume_keystream:\r\n got error response from card\r\n");
|
UserMessage("hitag2crack_consume_keystream:\r\n got error response from card\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -828,8 +752,7 @@ bool hitag2crack_extend_keystream(uint8_t *keybits, int *kslen, int ksoffset, ui
|
||||||
|
|
||||||
// calc number of command iterations to send
|
// calc number of command iterations to send
|
||||||
cmdlen = *kslen - ksoffset;
|
cmdlen = *kslen - ksoffset;
|
||||||
if (cmdlen < 10)
|
if (cmdlen < 10) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_extend_keystream:\r\n cmdlen < 10\r\n");
|
UserMessage("hitag2crack_extend_keystream:\r\n cmdlen < 10\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -837,8 +760,7 @@ bool hitag2crack_extend_keystream(uint8_t *keybits, int *kslen, int ksoffset, ui
|
||||||
numcmds = cmdlen / 10;
|
numcmds = cmdlen / 10;
|
||||||
|
|
||||||
// build extended command
|
// build extended command
|
||||||
for (i=0; i<numcmds; i++)
|
for (i = 0; i < numcmds; i++) {
|
||||||
{
|
|
||||||
binstringtobinarray(ext_cmd + (i * 10), READP0CMD);
|
binstringtobinarray(ext_cmd + (i * 10), READP0CMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -846,15 +768,13 @@ bool hitag2crack_extend_keystream(uint8_t *keybits, int *kslen, int ksoffset, ui
|
||||||
hitag2crack_xor(e_ext_cmd, ext_cmd, keybits + ksoffset, numcmds * 10);
|
hitag2crack_xor(e_ext_cmd, ext_cmd, keybits + ksoffset, numcmds * 10);
|
||||||
|
|
||||||
// send extended encrypted cmd
|
// send extended encrypted cmd
|
||||||
if (!hitag2crack_tx_rx(responsestr, e_ext_cmd, numcmds * 10, RWD_STATE_WAKING, false))
|
if (!hitag2crack_tx_rx(responsestr, e_ext_cmd, numcmds * 10, RWD_STATE_WAKING, false)) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_extend_keystream:\r\n tx/rx cmd failed\r\n");
|
UserMessage("hitag2crack_extend_keystream:\r\n tx/rx cmd failed\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// test response
|
// test response
|
||||||
if (strcmp(responsestr, ERROR_RESPONSE) == 0)
|
if (strcmp(responsestr, ERROR_RESPONSE) == 0) {
|
||||||
{
|
|
||||||
UserMessage("hitag2crack_extend_keystream:\r\n got error response from card\r\n");
|
UserMessage("hitag2crack_extend_keystream:\r\n got error response from card\r\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -878,17 +798,13 @@ bool hitag2_reader(uint8_t *response, uint8_t *key, bool interactive) {
|
||||||
|
|
||||||
response[0] = '\0';
|
response[0] = '\0';
|
||||||
// auth to tag
|
// auth to tag
|
||||||
if (hitag2_crypto_auth(tmp, key))
|
if (hitag2_crypto_auth(tmp, key)) {
|
||||||
{
|
|
||||||
// read tag, one page at a time
|
// read tag, one page at a time
|
||||||
for (i= 0; i <= 7; ++i)
|
for (i = 0; i <= 7; ++i) {
|
||||||
{
|
if (!read_tag(tmp, i, i)) {
|
||||||
if(!read_tag(tmp, i, i))
|
|
||||||
{
|
|
||||||
// if read fails, it could be because of auth,
|
// if read fails, it could be because of auth,
|
||||||
// so try to reauth
|
// so try to reauth
|
||||||
if (!hitag2_crypto_auth(tmp, key))
|
if (!hitag2_crypto_auth(tmp, key)) {
|
||||||
{
|
|
||||||
// if we can't reauth, it's a real failure
|
// if we can't reauth, it's a real failure
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -899,25 +815,19 @@ bool hitag2_reader(uint8_t *response, uint8_t *key, bool interactive) {
|
||||||
strcat(response, tmp);
|
strcat(response, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interactive)
|
if (interactive) {
|
||||||
{
|
|
||||||
tmp[8] = '\0';
|
tmp[8] = '\0';
|
||||||
for(i= 0; i <= 7 ; ++i)
|
for (i = 0; i <= 7 ; ++i) {
|
||||||
{
|
|
||||||
UserMessageNum("%d: ", i);
|
UserMessageNum("%d: ", i);
|
||||||
memcpy(tmp, response + (i * 8), 8);
|
memcpy(tmp, response + (i * 8), 8);
|
||||||
UserMessage("%s\r\n", tmp);
|
UserMessage("%s\r\n", tmp);
|
||||||
}
|
}
|
||||||
UserMessage("%s", "\r\n");
|
UserMessage("%s", "\r\n");
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
hitag2_nvm_store_tag(response);
|
hitag2_nvm_store_tag(response);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue