make style

This commit is contained in:
Philippe Teuwen 2020-01-15 19:26:12 +01:00
commit b57f40e3d7
2 changed files with 321 additions and 311 deletions

View file

@ -16,7 +16,7 @@
// (c) 2012 Roel Verdult // (c) 2012 Roel Verdult
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Piwi, 2019 // Piwi, 2019
// Iceman, 2019 // Iceman, 2019
// Anon, 2019 // Anon, 2019
#include "hitag2.h" #include "hitag2.h"
@ -299,10 +299,10 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_
// sim // sim
static void hitag_reader_send_bit(int bit) { static void hitag_reader_send_bit(int bit) {
LED_A_ON(); LED_A_ON();
// Binary pulse length modulation (BPLM) is used to encode the data stream // Binary pulse length modulation (BPLM) is used to encode the data stream
// This means that a transmission of a one takes longer than that of a zero // This means that a transmission of a one takes longer than that of a zero
// Enable modulation, which means, drop the field // Enable modulation, which means, drop the field
lf_modulation(true); lf_modulation(true);
// Wait for 4-10 times the carrier period // Wait for 4-10 times the carrier period
@ -328,241 +328,247 @@ static void hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) {
for (size_t i = 0; i < frame_len; i++) { for (size_t i = 0; i < frame_len; i++) {
hitag_reader_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1); hitag_reader_send_bit((frame[i / 8] >> (7 - (i % 8))) & 1);
} }
// Enable modulation, which means, drop the field // Enable modulation, which means, drop the field
lf_modulation(true); lf_modulation(true);
// Wait for 4-10 times the carrier period // Wait for 4-10 times the carrier period
lf_wait_periods(8); lf_wait_periods(8);
// Disable modulation, just activates the field again // Disable modulation, just activates the field again
lf_modulation(false); lf_modulation(false);
// t_stop, high field for stop condition (> 36) // t_stop, high field for stop condition (> 36)
lf_wait_periods(28); lf_wait_periods(28);
} }
size_t blocknr; size_t blocknr;
uint8_t hitag_crc(uint8_t *data, size_t length){ uint8_t hitag_crc(uint8_t *data, size_t length) {
uint8_t crc = 0xff; uint8_t crc = 0xff;
unsigned int byte, bit; unsigned int byte, bit;
for(byte=0; byte<((length+7)/8); byte++){ for (byte = 0; byte < ((length + 7) / 8); byte++) {
crc ^= *(data + byte); crc ^= *(data + byte);
bit = length < (8*(byte+1)) ? (length % 8) : 8; bit = length < (8 * (byte + 1)) ? (length % 8) : 8;
while(bit--){ while (bit--) {
if(crc & 0x80){ if (crc & 0x80) {
crc<<=1; crc <<= 1;
crc ^= 0x1d; crc ^= 0x1d;
} else { } else {
crc<<=1; crc <<= 1;
} }
} }
} }
return crc; return crc;
} }
#define test_bit(data, i) (*(data+(i/8)) >> (7-(i%8))) & 1 #define test_bit(data, i) (*(data+(i/8)) >> (7-(i%8))) & 1
#define set_bit(data, i) *(data+(i/8)) |= (1 << (7-(i%8))) #define set_bit(data, i) *(data+(i/8)) |= (1 << (7-(i%8)))
#define clear_bit(data, i) *(data+(i/8)) &= ~(1 << (7-(i%8))) #define clear_bit(data, i) *(data+(i/8)) &= ~(1 << (7-(i%8)))
#define flip_bit(data, i) *(data+(i/8)) ^= (1 << (7-(i%8))) #define flip_bit(data, i) *(data+(i/8)) ^= (1 << (7-(i%8)))
void fix_ac_decoding(uint8_t *input, size_t len){ void fix_ac_decoding(uint8_t *input, size_t len) {
// Reader routine tries to decode AC data after Manchester decoding // Reader routine tries to decode AC data after Manchester decoding
// AC has double the bitrate, extract data from bit-pairs // AC has double the bitrate, extract data from bit-pairs
uint8_t temp[len / 16]; uint8_t temp[len / 16];
memset(temp, 0, sizeof(temp)); memset(temp, 0, sizeof(temp));
for (size_t i = 1; i < len; i += 2) { for (size_t i = 1; i < len; i += 2) {
if (test_bit(input, i) && test_bit(input, (i + 1))){ if (test_bit(input, i) && test_bit(input, (i + 1))) {
set_bit(temp, (i / 2)); set_bit(temp, (i / 2));
} }
} }
memcpy(input, temp, sizeof(temp)); memcpy(input, temp, sizeof(temp));
} }
bool hitag_plain(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen, bool hitag_s) { bool hitag_plain(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool hitag_s) {
uint8_t crc; uint8_t crc;
*txlen = 0; *txlen = 0;
switch (rxlen) { switch (rxlen) {
case 0: { case 0: {
// retry waking up card // retry waking up card
/*tx[0] = 0xb0; // Rev 3.0*/ /*tx[0] = 0xb0; // Rev 3.0*/
tx[0] = 0x30; // Rev 2.0 tx[0] = 0x30; // Rev 2.0
*txlen = 5; *txlen = 5;
if(!bCollision) blocknr--; if (!bCollision) blocknr--;
if(blocknr < 0) { if (blocknr < 0) {
blocknr = 0; blocknr = 0;
} }
if(!hitag_s){ if (!hitag_s) {
if (blocknr > 1 && blocknr < 31) { if (blocknr > 1 && blocknr < 31) {
blocknr=31; blocknr = 31;
} }
} }
bCollision = true; bCollision = true;
return true; return true;
} }
case 32: { case 32: {
if(bCollision){ if (bCollision) {
// Select card by serial from response // Select card by serial from response
tx[0] = 0x00 | rx[0] >> 5; tx[0] = 0x00 | rx[0] >> 5;
tx[1] = rx[0] << 3 | rx[1] >> 5; tx[1] = rx[0] << 3 | rx[1] >> 5;
tx[2] = rx[1] << 3 | rx[2] >> 5; tx[2] = rx[1] << 3 | rx[2] >> 5;
tx[3] = rx[2] << 3 | rx[3] >> 5; tx[3] = rx[2] << 3 | rx[3] >> 5;
tx[4] = rx[3] << 3; tx[4] = rx[3] << 3;
crc = hitag_crc(tx,37); crc = hitag_crc(tx, 37);
tx[4] |= crc >> 5; tx[4] |= crc >> 5;
tx[5] = crc << 3; tx[5] = crc << 3;
*txlen = 45; *txlen = 45;
bCollision = false; bCollision = false;
} else { } else {
memcpy(tag.sectors[blocknr], rx, 4); memcpy(tag.sectors[blocknr], rx, 4);
blocknr++; blocknr++;
if(!hitag_s){ if (!hitag_s) {
if (blocknr > 1 && blocknr < 31) { if (blocknr > 1 && blocknr < 31) {
blocknr=31; blocknr = 31;
} }
} }
if (blocknr > 63) { if (blocknr > 63) {
DbpString("Read succesful!"); DbpString("Read succesful!");
*txlen = 0; *txlen = 0;
bSuccessful = true; bSuccessful = true;
return false; return false;
} }
// read next page of card until done // read next page of card until done
Dbprintf("Reading page %02u", blocknr); Dbprintf("Reading page %02u", blocknr);
tx[0] = 0xc0 | blocknr >> 4; // RDPPAGE tx[0] = 0xc0 | blocknr >> 4; // RDPPAGE
tx[1] = blocknr << 4; tx[1] = blocknr << 4;
crc = hitag_crc(tx,12); crc = hitag_crc(tx, 12);
tx[1] |= crc >> 4; tx[1] |= crc >> 4;
tx[2] = crc << 4; tx[2] = crc << 4;
*txlen = 20; *txlen = 20;
} }
} break; }
default: { break;
Dbprintf("Uknown frame length: %d",rxlen); default: {
return false; Dbprintf("Uknown frame length: %d", rxlen);
} break; return false;
} }
return true; break;
}
return true;
} }
size_t flipped_bit = 0; size_t flipped_bit = 0;
uint32_t byte_value = 0; uint32_t byte_value = 0;
bool hitag1_authenticate(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) { bool hitag1_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) {
uint8_t crc; uint8_t crc;
*txlen = 0; *txlen = 0;
switch (rxlen) { switch (rxlen) {
case 0: { case 0: {
// retry waking up card // retry waking up card
/*tx[0] = 0xb0; // Rev 3.0*/ /*tx[0] = 0xb0; // Rev 3.0*/
tx[0] = 0x30; // Rev 2.0 tx[0] = 0x30; // Rev 2.0
*txlen = 5; *txlen = 5;
if (bCrypto && byte_value <= 0xff){ if (bCrypto && byte_value <= 0xff) {
// to retry // to retry
bCrypto = false; bCrypto = false;
} }
if(!bCollision) blocknr--; if (!bCollision) blocknr--;
if(blocknr < 0) { if (blocknr < 0) {
blocknr = 0; blocknr = 0;
} }
bCollision = true; bCollision = true;
// will receive 32-bit UID // will receive 32-bit UID
} break; }
case 2: { break;
if (bAuthenticating) { case 2: {
// received Auth init ACK, send nonce if (bAuthenticating) {
// TODO Roel, bit-manipulation goes here // received Auth init ACK, send nonce
/*nonce[0] = 0x2d;*/ // TODO Roel, bit-manipulation goes here
/*nonce[1] = 0x74;*/ /*nonce[0] = 0x2d;*/
/*nonce[2] = 0x80;*/ /*nonce[1] = 0x74;*/
/*nonce[3] = 0xa5;*/ /*nonce[2] = 0x80;*/
nonce[0]=byte_value; /*nonce[3] = 0xa5;*/
byte_value++; nonce[0] = byte_value;
/*set_bit(nonce,flipped_bit);*/ byte_value++;
memcpy(tx,nonce,4); /*set_bit(nonce,flipped_bit);*/
*txlen = 32; memcpy(tx, nonce, 4);
// will receive 32 bit encrypted Logdata *txlen = 32;
} else if (bCrypto) { // will receive 32 bit encrypted Logdata
// authed, start reading } else if (bCrypto) {
tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE // authed, start reading
tx[1] = blocknr << 4; tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE
crc = hitag_crc(tx,12); tx[1] = blocknr << 4;
tx[1] |= crc >> 4; crc = hitag_crc(tx, 12);
tx[2] = crc << 4; tx[1] |= crc >> 4;
*txlen = 20; tx[2] = crc << 4;
// will receive 32-bit encrypted page *txlen = 20;
} // will receive 32-bit encrypted page
} break; }
case 32: { }
if (bCollision){ break;
// Select card by serial from response case 32: {
tx[0] = 0x00 | rx[0] >> 5; if (bCollision) {
tx[1] = rx[0] << 3 | rx[1] >> 5; // Select card by serial from response
tx[2] = rx[1] << 3 | rx[2] >> 5; tx[0] = 0x00 | rx[0] >> 5;
tx[3] = rx[2] << 3 | rx[3] >> 5; tx[1] = rx[0] << 3 | rx[1] >> 5;
tx[4] = rx[3] << 3; tx[2] = rx[1] << 3 | rx[2] >> 5;
crc = hitag_crc(tx,37); tx[3] = rx[2] << 3 | rx[3] >> 5;
tx[4] |= crc >> 5; tx[4] = rx[3] << 3;
tx[5] = crc << 3; crc = hitag_crc(tx, 37);
*txlen = 45; tx[4] |= crc >> 5;
bCollision = false; tx[5] = crc << 3;
bSelecting = true; *txlen = 45;
// will receive 32-bit configuration page bCollision = false;
} else if (bSelecting){ bSelecting = true;
// Initiate auth // will receive 32-bit configuration page
tx[0] = 0xa0 | key_no >> 4; // WRCPAGE } else if (bSelecting) {
tx[1] = blocknr << 4; // Initiate auth
crc = hitag_crc(tx,12); tx[0] = 0xa0 | key_no >> 4; // WRCPAGE
tx[1] |= crc >> 4; tx[1] = blocknr << 4;
tx[2] = crc << 4; crc = hitag_crc(tx, 12);
*txlen = 20; tx[1] |= crc >> 4;
bSelecting = false; tx[2] = crc << 4;
bAuthenticating = true; *txlen = 20;
// will receive 2-bit ACK bSelecting = false;
} else if (bAuthenticating) { bAuthenticating = true;
// received 32-bit logdata 0 // will receive 2-bit ACK
// TODO decrypt logdata 0, verify against logdata_0 } else if (bAuthenticating) {
memcpy(tag.sectors[0], rx, 4); // received 32-bit logdata 0
memcpy(tag.sectors[1], tx, 4); // TODO decrypt logdata 0, verify against logdata_0
Dbprintf("%02x%02x%02x%02x %02x%02x%02x%02x", rx[0], rx[1], rx[2], rx[3], tx[0], tx[1], tx[2], tx[3]); memcpy(tag.sectors[0], rx, 4);
// TODO replace with secret data stream memcpy(tag.sectors[1], tx, 4);
// TODO encrypt logdata_1 Dbprintf("%02x%02x%02x%02x %02x%02x%02x%02x", rx[0], rx[1], rx[2], rx[3], tx[0], tx[1], tx[2], tx[3]);
memcpy(tx,logdata_1,4); // TODO replace with secret data stream
*txlen = 32; // TODO encrypt logdata_1
bAuthenticating = false; memcpy(tx, logdata_1, 4);
bCrypto = true; *txlen = 32;
// will receive 2-bit ACK bAuthenticating = false;
} else if (bCrypto) { bCrypto = true;
// received 32-bit encrypted page // will receive 2-bit ACK
// TODO decrypt rx } else if (bCrypto) {
memcpy(tag.sectors[blocknr],rx,4); // received 32-bit encrypted page
blocknr++; // TODO decrypt rx
if (blocknr > 63) { memcpy(tag.sectors[blocknr], rx, 4);
DbpString("Read succesful!"); blocknr++;
bSuccessful = true; if (blocknr > 63) {
return false; DbpString("Read succesful!");
} bSuccessful = true;
return false;
}
// TEST // TEST
Dbprintf("Succesfully authenticated with logdata:"); Dbprintf("Succesfully authenticated with logdata:");
Dbhexdump(4,logdata_1,false); Dbhexdump(4, logdata_1, false);
bSuccessful = true; bSuccessful = true;
return false; return false;
// read next page of card until done // read next page of card until done
tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE tx[0] = 0xe0 | blocknr >> 4; // RDCPAGE
tx[1] = blocknr << 4; tx[1] = blocknr << 4;
crc = hitag_crc(tx,12); crc = hitag_crc(tx, 12);
tx[1] |= crc >> 4; tx[1] |= crc >> 4;
tx[2] = crc << 4; tx[2] = crc << 4;
*txlen = 20; *txlen = 20;
} }
} break; }
default: { break;
Dbprintf("Uknown frame length: %d",rxlen); default: {
return false; Dbprintf("Uknown frame length: %d", rxlen);
} break; return false;
} }
break;
}
return true; return true;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -919,7 +925,7 @@ static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
// Store the received block // Store the received block
memcpy(tag.sectors[blocknr], rx, 4); memcpy(tag.sectors[blocknr], rx, 4);
blocknr++; blocknr++;
Dbhexdump(4, rx, false); Dbhexdump(4, rx, false);
} }
if (blocknr > 0) { if (blocknr > 0) {
@ -944,7 +950,7 @@ void SniffHitag(void) {
LEDsoff(); LEDsoff();
StopTicks(); StopTicks();
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
BigBuf_free(); BigBuf_free();
BigBuf_Clear_ext(false); BigBuf_Clear_ext(false);
@ -968,17 +974,17 @@ void SniffHitag(void) {
/*bool waiting_for_first_edge = true;*/ /*bool waiting_for_first_edge = true;*/
LED_C_ON(); LED_C_ON();
while (!BUTTON_PRESS() && !data_available()) { while (!BUTTON_PRESS() && !data_available()) {
WDT_HIT(); WDT_HIT();
// Receive frame, watch for at most T0*EOF periods // Receive frame, watch for at most T0*EOF periods
lf_reset_counter(); lf_reset_counter();
// Wait "infinite" for reader modulation // Wait "infinite" for reader modulation
periods = lf_detect_gap(20000); periods = lf_detect_gap(20000);
// Test if we detected the first reader modulation edge // Test if we detected the first reader modulation edge
if (periods != 0) { if (periods != 0) {
if (logging == false) { if (logging == false) {
@ -986,29 +992,29 @@ void SniffHitag(void) {
LED_D_ON(); LED_D_ON();
} }
} }
/*lf_count_edge_periods(10000);*/ /*lf_count_edge_periods(10000);*/
while ((periods = lf_detect_gap(64)) != 0){ while ((periods = lf_detect_gap(64)) != 0) {
num_to_bytes(periods, 4, periods_bytes); num_to_bytes(periods, 4, periods_bytes);
LogTrace(periods_bytes, 4, 0, 0, NULL, true); LogTrace(periods_bytes, 4, 0, 0, NULL, true);
} }
/*
// Check if frame was captured
if (rxlen > 0) {
// frame_count++;
LogTrace(rx, nbytes(rxlen), response, 0, NULL, reader_frame);
// Check if we recognize a valid authentication attempt /*
if (nbytes(rxlen) == 8) { // Check if frame was captured
// Store the authentication attempt if (rxlen > 0) {
if (auth_table_len < (AUTH_TABLE_LENGTH - 8)) { // frame_count++;
memcpy(auth_table + auth_table_len, rx, 8); LogTrace(rx, nbytes(rxlen), response, 0, NULL, reader_frame);
auth_table_len += 8;
} // Check if we recognize a valid authentication attempt
} if (nbytes(rxlen) == 8) {
*/ // Store the authentication attempt
if (auth_table_len < (AUTH_TABLE_LENGTH - 8)) {
memcpy(auth_table + auth_table_len, rx, 8);
auth_table_len += 8;
}
}
*/
} }
lf_finalize(); lf_finalize();
@ -1204,54 +1210,56 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
uint8_t txbuf[HITAG_FRAME_LEN]; uint8_t txbuf[HITAG_FRAME_LEN];
uint8_t *tx = txbuf; uint8_t *tx = txbuf;
size_t txlen = 0; size_t txlen = 0;
int t_wait_1; int t_wait_1;
int t_wait_2; int t_wait_2;
size_t tag_size; size_t tag_size;
bool bStop = false; bool bStop = false;
// Raw demodulation/decoding by sampling edge periods // Raw demodulation/decoding by sampling edge periods
size_t periods = 0; size_t periods = 0;
// Reset the return status
bSuccessful = false;
bCrypto = false;
// Clean up trace and prepare it for storing frames
set_tracing(true);
clear_trace();
DbpString("Starting Hitag reader family"); // Reset the return status
bSuccessful = false;
bCrypto = false;
// Clean up trace and prepare it for storing frames
set_tracing(true);
clear_trace();
DbpString("Starting Hitag reader family");
// Check configuration // Check configuration
switch (htf) { switch (htf) {
case RHT1F_PLAIN: { case RHT1F_PLAIN: {
Dbprintf("Read public blocks in plain mode"); Dbprintf("Read public blocks in plain mode");
// this part will be unreadable // this part will be unreadable
memset(tag.sectors+2, 0x0, 30); memset(tag.sectors + 2, 0x0, 30);
blocknr = 0;
} break;
case RHT1F_AUTHENTICATE: {
Dbprintf("Read all blocks in authed mode");
memcpy(nonce, htd->ht1auth.nonce, 4);
memcpy(key, htd->ht1auth.key, 4);
memcpy(logdata_0, htd->ht1auth.logdata_0, 4);
memcpy(logdata_1, htd->ht1auth.logdata_1, 4);
// TEST
memset(nonce, 0x0, 4);
memset(logdata_1, 0x00, 4);
byte_value = 0;
key_no = htd->ht1auth.key_no;
Dbprintf("Authenticating using key #%d:", key_no);
Dbhexdump(4, key, false);
DbpString("Nonce:");
Dbhexdump(4, nonce, false);
DbpString("Logdata_0:");
Dbhexdump(4, logdata_0, false);
DbpString("Logdata_1:");
Dbhexdump(4, logdata_1, false);
blocknr = 0; blocknr = 0;
} break; }
break;
case RHT1F_AUTHENTICATE: {
Dbprintf("Read all blocks in authed mode");
memcpy(nonce, htd->ht1auth.nonce, 4);
memcpy(key, htd->ht1auth.key, 4);
memcpy(logdata_0, htd->ht1auth.logdata_0, 4);
memcpy(logdata_1, htd->ht1auth.logdata_1, 4);
// TEST
memset(nonce, 0x0, 4);
memset(logdata_1, 0x00, 4);
byte_value = 0;
key_no = htd->ht1auth.key_no;
Dbprintf("Authenticating using key #%d:", key_no);
Dbhexdump(4, key, false);
DbpString("Nonce:");
Dbhexdump(4, nonce, false);
DbpString("Logdata_0:");
Dbhexdump(4, logdata_0, false);
DbpString("Logdata_1:");
Dbhexdump(4, logdata_1, false);
blocknr = 0;
}
break;
case RHT2F_PASSWORD: { case RHT2F_PASSWORD: {
Dbprintf("List identifier in password mode"); Dbprintf("List identifier in password mode");
memcpy(password, htd->pwd.password, 4); memcpy(password, htd->pwd.password, 4);
@ -1272,9 +1280,9 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
DbpString("Authenticating using key:"); DbpString("Authenticating using key:");
memcpy(key, htd->crypto.key, 6); //HACK; 4 or 6?? I read both in the code. memcpy(key, htd->crypto.key, 6); //HACK; 4 or 6?? I read both in the code.
Dbhexdump(6, key, false); Dbhexdump(6, key, false);
DbpString("Nonce:"); DbpString("Nonce:");
Dbhexdump(4,nonce,false); Dbhexdump(4, nonce, false);
memcpy(nonce,htd->crypto.data,4); memcpy(nonce, htd->crypto.data, 4);
blocknr = 0; blocknr = 0;
bCrypto = false; bCrypto = false;
bAuthenticating = false; bAuthenticating = false;
@ -1308,9 +1316,9 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
lf_init(true); lf_init(true);
uint8_t attempt_count = 0; uint8_t attempt_count = 0;
// Tag specific configuration settings (sof, timings, etc.) // Tag specific configuration settings (sof, timings, etc.)
if (htf < 10){ if (htf < 10) {
// hitagS settings // hitagS settings
t_wait_1 = 204; t_wait_1 = 204;
t_wait_2 = 128; t_wait_2 = 128;
@ -1356,14 +1364,16 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
// By default reset the transmission buffer // By default reset the transmission buffer
tx = txbuf; tx = txbuf;
switch (htf) { switch (htf) {
case RHT1F_PLAIN: { case RHT1F_PLAIN: {
bStop = !hitag_plain(rx, rxlen, tx, &txlen, false); bStop = !hitag_plain(rx, rxlen, tx, &txlen, false);
} break; }
break;
case RHT1F_AUTHENTICATE: { case RHT1F_AUTHENTICATE: {
bStop = !hitag1_authenticate(rx, rxlen, tx, &txlen); bStop = !hitag1_authenticate(rx, rxlen, tx, &txlen);
} break; }
break;
case RHT2F_PASSWORD: { case RHT2F_PASSWORD: {
bStop = !hitag2_password(rx, rxlen, tx, &txlen, false); bStop = !hitag2_password(rx, rxlen, tx, &txlen, false);
break; break;
@ -1396,7 +1406,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
// Wait for t_wait_2 carrier periods after the last tag bit before transmitting, // Wait for t_wait_2 carrier periods after the last tag bit before transmitting,
lf_wait_periods(t_wait_2); lf_wait_periods(t_wait_2);
// Transmit the reader frame // Transmit the reader frame
hitag_reader_send_frame(tx, txlen); hitag_reader_send_frame(tx, txlen);
@ -1406,13 +1416,13 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
// Reset the response time (in number of periods) // Reset the response time (in number of periods)
response = 0; response = 0;
// Keep administration of the first edge detection // Keep administration of the first edge detection
bool waiting_for_first_edge = true; bool waiting_for_first_edge = true;
// Did we detected any modulaiton at all // Did we detected any modulaiton at all
bool detected_tag_modulation = false; bool detected_tag_modulation = false;
// Use the current modulation state as starting point // Use the current modulation state as starting point
tag_modulation = lf_get_tag_modulation(); tag_modulation = lf_get_tag_modulation();
@ -1427,7 +1437,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
// Just break out of loop after an initial time-out (tag is probably not available) // Just break out of loop after an initial time-out (tag is probably not available)
if (periods == 0) break; if (periods == 0) break;
// Register the number of periods that have passed // Register the number of periods that have passed
response = t_wait_1-64 + periods; response = t_wait_1 - 64 + periods;
// Indicate that we have dealt with the first edge // Indicate that we have dealt with the first edge
waiting_for_first_edge = false; waiting_for_first_edge = false;
// The first edge is always a single NRZ bit, force periods on 16 // The first edge is always a single NRZ bit, force periods on 16
@ -1437,20 +1447,20 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
} else { } else {
// The function lf_count_edge_periods() returns 0 when a time-out occurs // The function lf_count_edge_periods() returns 0 when a time-out occurs
if (periods == 0) { if (periods == 0) {
Dbprintf("Detected timeout after [%d] nrz samples",nrzs); Dbprintf("Detected timeout after [%d] nrz samples", nrzs);
break; break;
} }
} }
// Evaluate the number of periods before the next edge // Evaluate the number of periods before the next edge
if (periods > 24 && periods <= 64){ if (periods > 24 && periods <= 64) {
// Detected two sequential equal bits and a modulation switch // Detected two sequential equal bits and a modulation switch
// NRZ modulation: (11 => --|) or (11 __|) // NRZ modulation: (11 => --|) or (11 __|)
nrz_samples[nrzs++] = tag_modulation; nrz_samples[nrzs++] = tag_modulation;
nrz_samples[nrzs++] = tag_modulation; nrz_samples[nrzs++] = tag_modulation;
// Invert tag modulation state // Invert tag modulation state
tag_modulation ^= 1; tag_modulation ^= 1;
} else if (periods > 0 && periods <= 24){ } else if (periods > 0 && periods <= 24) {
// Detected one bit and a modulation switch // Detected one bit and a modulation switch
// NRZ modulation: (1 => -|) or (0 _|) // NRZ modulation: (1 => -|) or (0 _|)
nrz_samples[nrzs++] = tag_modulation; nrz_samples[nrzs++] = tag_modulation;
@ -1492,24 +1502,24 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
LED_B_ON(); LED_B_ON();
// decode bitstream // decode bitstream
manrawdecode((uint8_t*)nrz_samples, &nrzs, true, 0); manrawdecode((uint8_t *)nrz_samples, &nrzs, true, 0);
// decode frame // decode frame
// Verify if the header consists of five consecutive ones // Verify if the header consists of five consecutive ones
if (nrzs < 5) { if (nrzs < 5) {
Dbprintf("Detected unexpected number of manchester decoded samples [%d]",nrzs); Dbprintf("Detected unexpected number of manchester decoded samples [%d]", nrzs);
break; break;
} else { } else {
for (size_t i = 0; i < 5; i++){ for (size_t i = 0; i < 5; i++) {
if (nrz_samples[i] != 1) { if (nrz_samples[i] != 1) {
Dbprintf("Detected incorrect header, the bit [%d] is zero instead of one",i); Dbprintf("Detected incorrect header, the bit [%d] is zero instead of one", i);
} }
} }
} }
// Pack the response into a byte array // Pack the response into a byte array
for (size_t i = 5; i < nrzs; i++){ for (size_t i = 5; i < nrzs; i++) {
uint8_t bit = nrz_samples[i]; uint8_t bit = nrz_samples[i];
rx[rxlen / 8] |= bit << (7 - (rxlen % 8)); rx[rxlen / 8] |= bit << (7 - (rxlen % 8));
rxlen++; rxlen++;
@ -1529,11 +1539,11 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
LogTrace(rx, nbytes(rxlen), response, 0, NULL, false); LogTrace(rx, nbytes(rxlen), response, 0, NULL, false);
Dbhexdump(nbytes(rxlen), rx, false); Dbhexdump(nbytes(rxlen), rx, false);
} }
} }
out: out:
lf_finalize(); lf_finalize();
Dbprintf("frame received: %u", frame_count); Dbprintf("frame received: %u", frame_count);
// release allocated memory from BigBuff. // release allocated memory from BigBuff.
BigBuf_free(); BigBuf_free();

View file

@ -21,8 +21,8 @@ typedef enum {
RHTSF_KEY = 02, RHTSF_KEY = 02,
WHTSF_CHALLENGE = 03, WHTSF_CHALLENGE = 03,
WHTSF_KEY = 04, WHTSF_KEY = 04,
RHT1F_PLAIN = 11, RHT1F_PLAIN = 11,
RHT1F_AUTHENTICATE = 12, RHT1F_AUTHENTICATE = 12,
RHT2F_PASSWORD = 21, RHT2F_PASSWORD = 21,
RHT2F_AUTHENTICATE = 22, RHT2F_AUTHENTICATE = 22,
RHT2F_CRYPTO = 23, RHT2F_CRYPTO = 23,
@ -47,16 +47,16 @@ typedef struct {
} PACKED rht2d_crypto; } PACKED rht2d_crypto;
typedef struct { typedef struct {
bool key_no; bool key_no;
uint8_t logdata_0[4]; uint8_t logdata_0[4];
uint8_t logdata_1[4]; uint8_t logdata_1[4];
uint8_t nonce[4]; uint8_t nonce[4];
uint8_t key[4]; uint8_t key[4];
} PACKED rht1d_authenticate; } PACKED rht1d_authenticate;
typedef union { typedef union {
rht2d_password pwd; rht2d_password pwd;
rht1d_authenticate ht1auth; rht1d_authenticate ht1auth;
rht2d_authenticate auth; rht2d_authenticate auth;
rht2d_crypto crypto; rht2d_crypto crypto;
} hitag_data; } hitag_data;