mirror of
https://github.com/RfidResearchGroup/ChameleonUltra.git
synced 2026-05-12 11:22:59 -07:00
Merge branch 'RfidResearchGroup:main' into main
This commit is contained in:
+1
-1
@@ -13,7 +13,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||
- Fix the issue where some reader cause CU to enter a strange state (@xianglin1998)
|
||||
- The transmission performance of USB has been improved (@xianglin1998)
|
||||
- Added cmd for set mf1 config 'field_off_do_reset' (@xianglin1998)
|
||||
|
||||
- Fix Windows build (@suut)
|
||||
|
||||
## [v2.1.0][2025-09-02]
|
||||
- Added UV, formatter and linter. Contribution guidelines. (@GameTec-live)
|
||||
|
||||
@@ -627,12 +627,16 @@ static data_frame_tx_t *cmd_processor_mf1_manipulate_value_block(uint16_t cmd, u
|
||||
}
|
||||
|
||||
static data_frame_tx_t *cmd_processor_em410x_scan(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
uint8_t card_buffer[7] = {0x00};
|
||||
uint8_t card_buffer[2 + LF_EM410X_ELECTRA_TAG_ID_SIZE] = {0x00};
|
||||
status = scan_em410x(card_buffer);
|
||||
if (status != STATUS_LF_TAG_OK) {
|
||||
return data_frame_make(cmd, status, 0, NULL);
|
||||
}
|
||||
return data_frame_make(cmd, STATUS_LF_TAG_OK, sizeof(card_buffer), card_buffer);
|
||||
|
||||
tag_specific_type_t tag_type = (card_buffer[0] << 8) | card_buffer[1];
|
||||
uint16_t id_size = (tag_type == TAG_TYPE_EM410X_ELECTRA) ? LF_EM410X_ELECTRA_TAG_ID_SIZE : LF_EM410X_TAG_ID_SIZE;
|
||||
|
||||
return data_frame_make(cmd, STATUS_LF_TAG_OK, 2 + id_size, card_buffer);
|
||||
}
|
||||
|
||||
static data_frame_tx_t *cmd_processor_em410x_write_to_t55xx(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
@@ -650,6 +654,21 @@ static data_frame_tx_t *cmd_processor_em410x_write_to_t55xx(uint16_t cmd, uint16
|
||||
return data_frame_make(cmd, status, 0, NULL);
|
||||
}
|
||||
|
||||
static data_frame_tx_t *cmd_processor_em410x_electra_write_to_t55xx(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
typedef struct {
|
||||
uint8_t id[13];
|
||||
uint8_t new_key[4];
|
||||
uint8_t old_keys[4]; // we can have more than one... struct just to compute offsets with min 1 key
|
||||
} PACKED payload_t;
|
||||
payload_t *payload = (payload_t *)data;
|
||||
if (length < sizeof(payload_t) || (length - offsetof(payload_t, old_keys)) % sizeof(payload->old_keys) != 0) {
|
||||
return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL);
|
||||
}
|
||||
|
||||
status = write_em410x_electra_to_t55xx(payload->id, payload->new_key, payload->old_keys, (length - offsetof(payload_t, old_keys)) / sizeof(payload->old_keys));
|
||||
return data_frame_make(cmd, status, 0, NULL);
|
||||
}
|
||||
|
||||
static data_frame_tx_t *cmd_processor_hidprox_write_to_t55xx(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
typedef struct {
|
||||
uint8_t id[13];
|
||||
@@ -830,24 +849,41 @@ static data_frame_tx_t *cmd_processor_wipe_fds(uint16_t cmd, uint16_t status, ui
|
||||
return data_frame_make(cmd, status, 0, NULL);
|
||||
}
|
||||
|
||||
static bool get_active_em410x_type(tag_specific_type_t *tag_type_out, uint16_t *id_size_out) {
|
||||
tag_slot_specific_type_t tag_types;
|
||||
tag_emulation_get_specific_types_by_slot(tag_emulation_get_slot(), &tag_types);
|
||||
if (tag_types.tag_lf == TAG_TYPE_EM410X || tag_types.tag_lf == TAG_TYPE_EM410X_ELECTRA) {
|
||||
*tag_type_out = tag_types.tag_lf;
|
||||
*id_size_out = (tag_types.tag_lf == TAG_TYPE_EM410X_ELECTRA) ? LF_EM410X_ELECTRA_TAG_ID_SIZE : LF_EM410X_TAG_ID_SIZE;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static data_frame_tx_t *cmd_processor_em410x_set_emu_id(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
if (length != LF_EM410X_TAG_ID_SIZE) {
|
||||
tag_specific_type_t tag_type;
|
||||
uint16_t id_size;
|
||||
if (!get_active_em410x_type(&tag_type, &id_size) || length != id_size) {
|
||||
return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL);
|
||||
}
|
||||
tag_data_buffer_t *buffer = get_buffer_by_tag_type(TAG_TYPE_EM410X);
|
||||
memcpy(buffer->buffer, data, LF_EM410X_TAG_ID_SIZE);
|
||||
tag_emulation_load_by_buffer(TAG_TYPE_EM410X, false);
|
||||
tag_data_buffer_t *buffer = get_buffer_by_tag_type(tag_type);
|
||||
memcpy(buffer->buffer, data, id_size);
|
||||
tag_emulation_load_by_buffer(tag_type, false);
|
||||
return data_frame_make(cmd, STATUS_SUCCESS, 0, NULL);
|
||||
}
|
||||
|
||||
static data_frame_tx_t *cmd_processor_em410x_get_emu_id(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
tag_slot_specific_type_t tag_types;
|
||||
tag_emulation_get_specific_types_by_slot(tag_emulation_get_slot(), &tag_types);
|
||||
if (tag_types.tag_lf != TAG_TYPE_EM410X) {
|
||||
tag_specific_type_t tag_type;
|
||||
uint16_t id_size;
|
||||
if (!get_active_em410x_type(&tag_type, &id_size)) {
|
||||
return data_frame_make(cmd, STATUS_PAR_ERR, 0, data); // no data in slot, don't send garbage
|
||||
}
|
||||
tag_data_buffer_t *buffer = get_buffer_by_tag_type(TAG_TYPE_EM410X);
|
||||
return data_frame_make(cmd, STATUS_SUCCESS, LF_EM410X_TAG_ID_SIZE, buffer->buffer);
|
||||
tag_data_buffer_t *buffer = get_buffer_by_tag_type(tag_type);
|
||||
uint8_t resp[2 + LF_EM410X_ELECTRA_TAG_ID_SIZE] = {0x00};
|
||||
resp[0] = tag_type >> 8;
|
||||
resp[1] = tag_type;
|
||||
memcpy(resp + 2, buffer->buffer, id_size);
|
||||
return data_frame_make(cmd, STATUS_SUCCESS, 2 + id_size, resp);
|
||||
}
|
||||
|
||||
static data_frame_tx_t *cmd_processor_hidprox_set_emu_id(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
@@ -1615,6 +1651,7 @@ static cmd_data_map_t m_data_cmd_map[] = {
|
||||
|
||||
{ DATA_CMD_EM410X_SCAN, before_reader_run, cmd_processor_em410x_scan, NULL },
|
||||
{ DATA_CMD_EM410X_WRITE_TO_T55XX, before_reader_run, cmd_processor_em410x_write_to_t55xx, NULL },
|
||||
{ DATA_CMD_EM410X_ELECTRA_WRITE_TO_T55XX,before_reader_run, cmd_processor_em410x_electra_write_to_t55xx, NULL },
|
||||
{ DATA_CMD_HIDPROX_SCAN, before_reader_run, cmd_processor_hidprox_scan, NULL },
|
||||
{ DATA_CMD_HIDPROX_WRITE_TO_T55XX, before_reader_run, cmd_processor_hidprox_write_to_t55xx, NULL },
|
||||
{ DATA_CMD_VIKING_SCAN, before_reader_run, cmd_processor_viking_scan, NULL },
|
||||
|
||||
@@ -648,10 +648,22 @@ static void btn_fn_copy_lf(uint8_t slot, tag_specific_type_t type) {
|
||||
data = id_buffer;
|
||||
break;
|
||||
case TAG_TYPE_EM410X:
|
||||
case TAG_TYPE_EM410X_ELECTRA: {
|
||||
status = scan_em410x(id_buffer);
|
||||
size = LF_EM410X_TAG_ID_SIZE;
|
||||
data = id_buffer + 2; // skip tag type
|
||||
tag_specific_type_t detected_type = (id_buffer[0] << 8) | id_buffer[1];
|
||||
tag_specific_type_t new_type =
|
||||
detected_type == TAG_TYPE_EM410X_ELECTRA ? TAG_TYPE_EM410X_ELECTRA : TAG_TYPE_EM410X;
|
||||
|
||||
// If we read Electra but the slot was classic (or vice versa), switch slot type automatically.
|
||||
if (new_type != type) {
|
||||
tag_emulation_change_type(slot, new_type);
|
||||
type = new_type;
|
||||
}
|
||||
|
||||
size = (new_type == TAG_TYPE_EM410X_ELECTRA) ? LF_EM410X_ELECTRA_TAG_ID_SIZE : LF_EM410X_TAG_ID_SIZE;
|
||||
data = id_buffer + 2; // skip tag type
|
||||
break;
|
||||
}
|
||||
case TAG_TYPE_VIKING:
|
||||
status = scan_viking(id_buffer);
|
||||
size = LF_VIKING_TAG_ID_SIZE;
|
||||
@@ -1011,4 +1023,4 @@ int main(void) {
|
||||
// Some task process done, we can enter cpu sleep state.
|
||||
sleep_system_run(system_off_enter, nrf_pwr_mgmt_run);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
//
|
||||
#define DATA_CMD_EM410X_SCAN (3000)
|
||||
#define DATA_CMD_EM410X_WRITE_TO_T55XX (3001)
|
||||
#define DATA_CMD_EM410X_ELECTRA_WRITE_TO_T55XX (3006)
|
||||
#define DATA_CMD_HIDPROX_SCAN (3002)
|
||||
#define DATA_CMD_HIDPROX_WRITE_TO_T55XX (3003)
|
||||
#define DATA_CMD_VIKING_SCAN (3004)
|
||||
|
||||
@@ -155,6 +155,10 @@ static enum {
|
||||
LF_SENSE_STATE_ENABLE,
|
||||
} m_lf_sense_state = LF_SENSE_STATE_NONE;
|
||||
|
||||
static uint16_t lf_em410x_id_size(tag_specific_type_t type) {
|
||||
return type == TAG_TYPE_EM410X_ELECTRA ? LF_EM410X_ELECTRA_TAG_ID_SIZE : LF_EM410X_TAG_ID_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief switchLfFieldInductionToEnableTheState
|
||||
*/
|
||||
@@ -182,13 +186,14 @@ void lf_tag_125khz_sense_switch(bool enable) {
|
||||
int lf_tag_data_loadcb(tag_specific_type_t type, tag_data_buffer_t *buffer) {
|
||||
// ensure buffer size is large enough for specific tag type,
|
||||
// so that tag data (e.g., card numbers) can be converted to corresponding pwm sequence here.
|
||||
if (type == TAG_TYPE_EM410X && buffer->length >= LF_EM410X_TAG_ID_SIZE) {
|
||||
if ((type == TAG_TYPE_EM410X || type == TAG_TYPE_EM410X_ELECTRA) && buffer->length >= lf_em410x_id_size(type)) {
|
||||
const protocol *p = type == TAG_TYPE_EM410X_ELECTRA ? &em410x_electra : &em410x_64;
|
||||
m_tag_type = type;
|
||||
void *codec = em410x_64.alloc();
|
||||
m_pwm_seq = em410x_64.modulator(codec, buffer->buffer);
|
||||
em410x_64.free(codec);
|
||||
NRF_LOG_INFO("load lf em410x data finish.");
|
||||
return LF_EM410X_TAG_ID_SIZE;
|
||||
void *codec = p->alloc();
|
||||
m_pwm_seq = p->modulator(codec, buffer->buffer);
|
||||
p->free(codec);
|
||||
NRF_LOG_INFO("load lf em410x%s data finish.", type == TAG_TYPE_EM410X_ELECTRA ? " electra" : "");
|
||||
return lf_em410x_id_size(type);
|
||||
}
|
||||
|
||||
if (type == TAG_TYPE_HID_PROX && buffer->length >= LF_HIDPROX_TAG_ID_SIZE) {
|
||||
@@ -221,7 +226,13 @@ int lf_tag_data_loadcb(tag_specific_type_t type, tag_data_buffer_t *buffer) {
|
||||
int lf_tag_em410x_data_savecb(tag_specific_type_t type, tag_data_buffer_t *buffer) {
|
||||
// Make sure to load this tag before allowing saving
|
||||
// Just save the original card package directly
|
||||
return m_tag_type == TAG_TYPE_EM410X ? LF_EM410X_TAG_ID_SIZE : 0;
|
||||
if (m_tag_type == TAG_TYPE_EM410X) {
|
||||
return LF_EM410X_TAG_ID_SIZE;
|
||||
}
|
||||
if (m_tag_type == TAG_TYPE_EM410X_ELECTRA) {
|
||||
return LF_EM410X_ELECTRA_TAG_ID_SIZE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @brief Id card deposit card number before callback
|
||||
@@ -252,7 +263,7 @@ bool lf_tag_data_factory(uint8_t slot, tag_specific_type_t tag_type, uint8_t *ta
|
||||
fds_slot_record_map_t map_info; // Get the special card slot FDS record information
|
||||
get_fds_map_by_slot_sense_type_for_dump(slot, sense_type, &map_info);
|
||||
// Call the blocked FDS to write the function, and write the data of the specified field type of the card slot into the Flash
|
||||
bool ret = fds_write_sync(map_info.id, map_info.key, sizeof(tag_id), (uint8_t *)tag_id);
|
||||
bool ret = fds_write_sync(map_info.id, map_info.key, length, (uint8_t *)tag_id);
|
||||
if (ret) {
|
||||
NRF_LOG_INFO("Factory slot data success.");
|
||||
} else {
|
||||
@@ -267,9 +278,18 @@ bool lf_tag_data_factory(uint8_t slot, tag_specific_type_t tag_type, uint8_t *ta
|
||||
* @return Whether the format is successful, if the formatting is successful, it will return to True, otherwise False will be returned
|
||||
*/
|
||||
bool lf_tag_em410x_data_factory(uint8_t slot, tag_specific_type_t tag_type) {
|
||||
// default id, must to align(4), more word...
|
||||
uint8_t tag_id[5] = {0xDE, 0xAD, 0xBE, 0xEF, 0x88};
|
||||
return lf_tag_data_factory(slot, tag_type, tag_id, sizeof(tag_id));
|
||||
static const uint8_t tag_id_base[LF_EM410X_TAG_ID_SIZE] = {0xDE, 0xAD, 0xBE, 0xEF, 0x88};
|
||||
static const uint8_t tag_id_electra[LF_EM410X_ELECTRA_TAG_ID_SIZE] = {0xDE, 0xAD, 0xBE, 0xEF, 0x88,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
switch (tag_type) {
|
||||
case TAG_TYPE_EM410X_ELECTRA:
|
||||
return lf_tag_data_factory(slot, tag_type, (uint8_t *)tag_id_electra, sizeof(tag_id_electra));
|
||||
case TAG_TYPE_EM410X:
|
||||
return lf_tag_data_factory(slot, tag_type, (uint8_t *)tag_id_base, sizeof(tag_id_base));
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Id card deposit card number before callback
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "tag_emulation.h"
|
||||
|
||||
#define LF_EM410X_TAG_ID_SIZE 5
|
||||
#define LF_EM410X_ELECTRA_TAG_ID_SIZE 13
|
||||
#define LF_HIDPROX_TAG_ID_SIZE 13
|
||||
#define LF_VIKING_TAG_ID_SIZE 4
|
||||
|
||||
|
||||
@@ -15,11 +15,17 @@
|
||||
#define EM_BITS_PER_ROW_COUNT (EM_COLUMN_COUNT + 1)
|
||||
|
||||
#define EM_RAW_SIZE (64)
|
||||
#define EM_DATA_SIZE (5)
|
||||
#define EM_DATA_SIZE_BASE (5)
|
||||
#define EM_ELECTRA_EPILOGUE_SIZE (8)
|
||||
#define EM_DATA_SIZE_ELECTRA (EM_DATA_SIZE_BASE + EM_ELECTRA_EPILOGUE_SIZE)
|
||||
#define EM_DATA_SIZE_MAX (EM_DATA_SIZE_ELECTRA)
|
||||
#define EM_T55XX_ELECTRA_BLOCK_COUNT (5)
|
||||
#define EM_ROW_COUNT (10)
|
||||
#define EM_COLUMN_COUNT (4)
|
||||
#define EM_HEADER (0x1ff) // 9 bits of 1
|
||||
|
||||
#define EM_ENCODED_DATA_HEADER (0xFF80000000000000ULL)
|
||||
|
||||
#define EM_T55XX_BLOCK_COUNT (3)
|
||||
|
||||
#define EM_READ_TIME1_BASE (0x40)
|
||||
@@ -33,16 +39,25 @@
|
||||
#include "nrf_log_default_backends.h"
|
||||
NRF_LOG_MODULE_REGISTER();
|
||||
|
||||
static nrf_pwm_values_wave_form_t m_em410x_pwm_seq_vals[EM_RAW_SIZE] = {};
|
||||
static nrf_pwm_values_wave_form_t m_em410x_pwm_seq_vals_base[EM_RAW_SIZE] = {};
|
||||
static nrf_pwm_values_wave_form_t m_em410x_pwm_seq_vals_electra[EM_RAW_SIZE * 2] = {};
|
||||
|
||||
nrf_pwm_sequence_t const m_em410x_pwm_seq = {
|
||||
.values.p_wave_form = m_em410x_pwm_seq_vals,
|
||||
.length = NRF_PWM_VALUES_LENGTH(m_em410x_pwm_seq_vals),
|
||||
nrf_pwm_sequence_t const m_em410x_pwm_seq_base = {
|
||||
.values.p_wave_form = m_em410x_pwm_seq_vals_base,
|
||||
.length = NRF_PWM_VALUES_LENGTH(m_em410x_pwm_seq_vals_base),
|
||||
.repeats = 0,
|
||||
.end_delay = 0,
|
||||
};
|
||||
|
||||
nrf_pwm_sequence_t const m_em410x_pwm_seq_electra = {
|
||||
.values.p_wave_form = m_em410x_pwm_seq_vals_electra,
|
||||
.length = NRF_PWM_VALUES_LENGTH(m_em410x_pwm_seq_vals_electra),
|
||||
.repeats = 0,
|
||||
.end_delay = 0,
|
||||
};
|
||||
|
||||
const protocol *em410x_protocols[] = {
|
||||
&em410x_electra,
|
||||
&em410x_64,
|
||||
&em410x_32,
|
||||
&em410x_16,
|
||||
@@ -51,9 +66,11 @@ const protocol *em410x_protocols[] = {
|
||||
size_t em410x_protocols_size = ARRAY_SIZE(em410x_protocols);
|
||||
|
||||
typedef struct {
|
||||
uint8_t data[EM_DATA_SIZE];
|
||||
uint8_t data[EM_DATA_SIZE_MAX];
|
||||
uint64_t raw;
|
||||
uint64_t epilogue;
|
||||
uint8_t raw_length;
|
||||
uint8_t total_length;
|
||||
manchester *modem;
|
||||
} em410x_codec;
|
||||
|
||||
@@ -80,6 +97,17 @@ uint64_t em410x_raw_data(uint8_t *uid) {
|
||||
return raw;
|
||||
}
|
||||
|
||||
uint64_t em410x_raw_epilogue(uint8_t *uid) {
|
||||
uint64_t raw = 0;
|
||||
|
||||
for (int i = 0; i < EM_ELECTRA_EPILOGUE_SIZE; i++) {
|
||||
raw <<= 8;
|
||||
raw |= uid[EM_DATA_SIZE_BASE + i];
|
||||
}
|
||||
|
||||
return raw;
|
||||
}
|
||||
|
||||
bool em410x_get_time(uint16_t divisor, uint8_t interval, uint8_t base) {
|
||||
return interval >= (base - EM_READ_JITTER_TIME_BASE) / divisor &&
|
||||
interval <= (base + EM_READ_JITTER_TIME_BASE) / divisor;
|
||||
@@ -142,9 +170,11 @@ void em410x_free(em410x_codec *d) {
|
||||
uint8_t *em410x_get_data(em410x_codec *d) { return d->data; };
|
||||
|
||||
void em410x_decoder_start(em410x_codec *d, uint8_t format) {
|
||||
memset(d->data, 0, EM_DATA_SIZE);
|
||||
memset(d->data, 0, EM_DATA_SIZE_MAX);
|
||||
d->raw = 0;
|
||||
d->raw_length = 0;
|
||||
d->total_length = 0;
|
||||
d->epilogue = 0;
|
||||
manchester_reset(d->modem);
|
||||
};
|
||||
|
||||
@@ -202,6 +232,8 @@ bool em410x_decoder_feed(em410x_codec *d, uint16_t interval) {
|
||||
if (bitlen == -1) {
|
||||
d->raw = 0;
|
||||
d->raw_length = 0;
|
||||
d->total_length = 0;
|
||||
d->epilogue = 0;
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < bitlen; i++) {
|
||||
@@ -212,6 +244,79 @@ bool em410x_decoder_feed(em410x_codec *d, uint16_t interval) {
|
||||
return false;
|
||||
};
|
||||
|
||||
void em410x_electra_decoder_start(em410x_codec *d, uint8_t format) {
|
||||
em410x_decoder_start(d, format);
|
||||
}
|
||||
|
||||
static bool em410x_electra_decode_feed(em410x_codec *d, bool bit) {
|
||||
bool carry_bit = (d->epilogue >> 63) & 0x01;
|
||||
|
||||
if (d->total_length < EM_RAW_SIZE + EM_RAW_SIZE) {
|
||||
d->total_length++;
|
||||
}
|
||||
d->raw = (d->raw << 1) | carry_bit;
|
||||
d->epilogue = (d->epilogue << 1) | (bit ? 1 : 0);
|
||||
|
||||
if (d->total_length < EM_RAW_SIZE + EM_RAW_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((d->raw & EM_ENCODED_DATA_HEADER) != EM_ENCODED_DATA_HEADER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d->raw & 0x01) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t pc = 0;
|
||||
for (int i = 0; i < EM_ROW_COUNT + 1; i++) {
|
||||
uint8_t row = d->raw >> (EM_RAW_SIZE - 9 - (i + 1) * EM_BITS_PER_ROW_COUNT) & 0x1f;
|
||||
uint8_t data = (row >> 1) & 0x0f;
|
||||
pc ^= data;
|
||||
if (i == 10) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!oddparity8(row)) { // row parity
|
||||
return false;
|
||||
}
|
||||
|
||||
if (i % 2) {
|
||||
d->data[i >> 1] |= data;
|
||||
} else {
|
||||
d->data[i >> 1] = data << 4;
|
||||
}
|
||||
}
|
||||
|
||||
// if we only saw the same frame twice, treat as standard EM410X
|
||||
if (d->raw == d->epilogue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < EM_ELECTRA_EPILOGUE_SIZE; i++) {
|
||||
d->data[EM_DATA_SIZE_BASE + i] = (d->epilogue >> ((EM_ELECTRA_EPILOGUE_SIZE - 1 - i) * 8)) & 0xFF;
|
||||
}
|
||||
|
||||
return pc == 0x00;
|
||||
}
|
||||
|
||||
bool em410x_electra_decoder_feed(em410x_codec *d, uint16_t interval) {
|
||||
bool bits[2] = {0};
|
||||
int8_t bitlen = 0;
|
||||
manchester_feed(d->modem, (uint8_t)interval, bits, &bitlen);
|
||||
if (bitlen == -1) {
|
||||
em410x_decoder_start(d, 0);
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < bitlen; i++) {
|
||||
if (em410x_electra_decode_feed(d, bits[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const nrf_pwm_sequence_t *em410x_modulator(em410x_codec *d, uint8_t *buf) {
|
||||
uint64_t lo = em410x_raw_data(buf);
|
||||
for (int i = 0; i < EM_RAW_SIZE; i++) {
|
||||
@@ -219,16 +324,50 @@ const nrf_pwm_sequence_t *em410x_modulator(em410x_codec *d, uint8_t *buf) {
|
||||
if (IS_SET(lo, EM_RAW_SIZE - i - 1)) {
|
||||
msb = (1 << 15);
|
||||
}
|
||||
m_em410x_pwm_seq_vals[i].channel_0 = msb | 32;
|
||||
m_em410x_pwm_seq_vals[i].counter_top = 64;
|
||||
m_em410x_pwm_seq_vals_base[i].channel_0 = msb | 32;
|
||||
m_em410x_pwm_seq_vals_base[i].counter_top = 64;
|
||||
}
|
||||
return &m_em410x_pwm_seq;
|
||||
return &m_em410x_pwm_seq_base;
|
||||
};
|
||||
|
||||
const nrf_pwm_sequence_t *em410x_electra_modulator(em410x_codec *d, uint8_t *buf) {
|
||||
uint64_t data[] = {em410x_raw_data(buf), em410x_raw_epilogue(buf)};
|
||||
uint16_t output_index = 0;
|
||||
|
||||
for (int frame = 0; frame < 2; frame++) {
|
||||
for (int i = 0; i < EM_RAW_SIZE; i++) {
|
||||
uint16_t msb = 0x00;
|
||||
if (IS_SET(data[frame], EM_RAW_SIZE - i - 1)) {
|
||||
msb = (1 << 15);
|
||||
}
|
||||
m_em410x_pwm_seq_vals_electra[output_index].channel_0 = msb | 32;
|
||||
m_em410x_pwm_seq_vals_electra[output_index].counter_top = 64;
|
||||
output_index++;
|
||||
}
|
||||
}
|
||||
|
||||
return &m_em410x_pwm_seq_electra;
|
||||
};
|
||||
|
||||
// EM-Micro, EM410x/64 (std)
|
||||
const protocol em410x_electra = {
|
||||
.tag_type = TAG_TYPE_EM410X_ELECTRA,
|
||||
.data_size = EM_DATA_SIZE_ELECTRA,
|
||||
.alloc = (codec_alloc)em410x_64_alloc,
|
||||
.free = (codec_free)em410x_free,
|
||||
.get_data = (codec_get_data)em410x_get_data,
|
||||
.modulator = (modulator)em410x_electra_modulator,
|
||||
.decoder =
|
||||
{
|
||||
.start = (decoder_start)em410x_electra_decoder_start,
|
||||
.feed = (decoder_feed)em410x_electra_decoder_feed,
|
||||
},
|
||||
};
|
||||
|
||||
// EM-Micro, EM410x/64 (std)
|
||||
const protocol em410x_64 = {
|
||||
.tag_type = TAG_TYPE_EM410X_64,
|
||||
.data_size = EM_DATA_SIZE,
|
||||
.data_size = EM_DATA_SIZE_BASE,
|
||||
.alloc = (codec_alloc)em410x_64_alloc,
|
||||
.free = (codec_free)em410x_free,
|
||||
.get_data = (codec_get_data)em410x_get_data,
|
||||
@@ -243,7 +382,7 @@ const protocol em410x_64 = {
|
||||
// EM-Micro, EM410x/32
|
||||
const protocol em410x_32 = {
|
||||
.tag_type = TAG_TYPE_EM410X_32,
|
||||
.data_size = EM_DATA_SIZE,
|
||||
.data_size = EM_DATA_SIZE_BASE,
|
||||
.alloc = (codec_alloc)em410x_32_alloc,
|
||||
.free = (codec_free)em410x_free,
|
||||
.get_data = (codec_get_data)em410x_get_data,
|
||||
@@ -258,7 +397,7 @@ const protocol em410x_32 = {
|
||||
// EM-Micro, EM410x/16
|
||||
const protocol em410x_16 = {
|
||||
.tag_type = TAG_TYPE_EM410X_16,
|
||||
.data_size = EM_DATA_SIZE,
|
||||
.data_size = EM_DATA_SIZE_BASE,
|
||||
.alloc = (codec_alloc)em410x_16_alloc,
|
||||
.free = (codec_free)em410x_free,
|
||||
.get_data = (codec_get_data)em410x_get_data,
|
||||
@@ -277,4 +416,17 @@ uint8_t em410x_t55xx_writer(uint8_t *uid, uint32_t *blks) {
|
||||
blks[1] = raw >> 32;
|
||||
blks[2] = raw & 0xffffffff;
|
||||
return EM_T55XX_BLOCK_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t em410x_electra_t55xx_writer(uint8_t *uid, uint32_t *blks) {
|
||||
uint64_t raw_data = em410x_raw_data(uid);
|
||||
uint64_t raw_epilogue = em410x_raw_epilogue(uid);
|
||||
|
||||
blks[0] = T5577_EM410X_ELECTRA_CONFIG;
|
||||
blks[1] = raw_data >> 32;
|
||||
blks[2] = raw_data & 0xffffffff;
|
||||
blks[3] = raw_epilogue >> 32;
|
||||
blks[4] = raw_epilogue & 0xffffffff;
|
||||
|
||||
return EM_T55XX_ELECTRA_BLOCK_COUNT;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
extern const protocol em410x_64;
|
||||
extern const protocol em410x_32;
|
||||
extern const protocol em410x_16;
|
||||
extern const protocol em410x_electra;
|
||||
|
||||
extern const protocol* em410x_protocols[];
|
||||
extern size_t em410x_protocols_size;
|
||||
|
||||
uint8_t em410x_t55xx_writer(uint8_t* uid, uint32_t* blks);
|
||||
uint8_t em410x_t55xx_writer(uint8_t* uid, uint32_t* blks);
|
||||
uint8_t em410x_electra_t55xx_writer(uint8_t* uid, uint32_t* blks);
|
||||
|
||||
@@ -51,6 +51,12 @@ extern "C" {
|
||||
T5577_PWD | \
|
||||
(2 << T5577_MAXBLOCK_SHIFT))
|
||||
|
||||
#define T5577_EM410X_ELECTRA_CONFIG ( \
|
||||
T5577_BITRATE_RF_64 | \
|
||||
T5577_MODULATION_MANCHESTER | \
|
||||
T5577_PWD | \
|
||||
(4 << T5577_MAXBLOCK_SHIFT))
|
||||
|
||||
#define T5577_HIDPROX_CONFIG ( \
|
||||
T5577_BITRATE_RF_50 | \
|
||||
T5577_MODULATION_FSK2a | \
|
||||
@@ -68,4 +74,4 @@ void t55xx_reset_passwd(uint32_t old_passwd, uint32_t new_passwd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -38,6 +38,7 @@ typedef enum {
|
||||
TAG_TYPE_EM410X_16,
|
||||
TAG_TYPE_EM410X_32,
|
||||
TAG_TYPE_EM410X_64,
|
||||
TAG_TYPE_EM410X_ELECTRA,
|
||||
// FDX-B
|
||||
// securakey
|
||||
// gallagher
|
||||
@@ -106,7 +107,7 @@ typedef enum {
|
||||
}
|
||||
|
||||
#define TAG_SPECIFIC_TYPE_LF_VALUES \
|
||||
TAG_TYPE_EM410X, TAG_TYPE_HID_PROX, TAG_TYPE_VIKING
|
||||
TAG_TYPE_EM410X, TAG_TYPE_EM410X_ELECTRA, TAG_TYPE_HID_PROX, TAG_TYPE_VIKING
|
||||
|
||||
#define TAG_SPECIFIC_TYPE_HF_VALUES \
|
||||
TAG_TYPE_MIFARE_Mini, TAG_TYPE_MIFARE_1024, TAG_TYPE_MIFARE_2048, \
|
||||
|
||||
@@ -90,6 +90,7 @@ static uint16_t m_slot_config_crc;
|
||||
static tag_base_handler_map_t tag_base_map[] = {
|
||||
// LF tag emulation
|
||||
{TAG_SENSE_LF, TAG_TYPE_EM410X, lf_tag_data_loadcb, lf_tag_em410x_data_savecb, lf_tag_em410x_data_factory, &m_tag_data_lf},
|
||||
{TAG_SENSE_LF, TAG_TYPE_EM410X_ELECTRA, lf_tag_data_loadcb, lf_tag_em410x_data_savecb, lf_tag_em410x_data_factory, &m_tag_data_lf},
|
||||
{TAG_SENSE_LF, TAG_TYPE_HID_PROX, lf_tag_data_loadcb, lf_tag_hidprox_data_savecb, lf_tag_hidprox_data_factory, &m_tag_data_lf},
|
||||
{TAG_SENSE_LF, TAG_TYPE_VIKING, lf_tag_data_loadcb, lf_tag_viking_data_savecb, lf_tag_viking_data_factory, &m_tag_data_lf},
|
||||
// MF1 tag emulation
|
||||
|
||||
@@ -90,6 +90,15 @@ uint8_t write_em410x_to_t55xx(uint8_t *uid, uint8_t *new_passwd, uint8_t *old_pa
|
||||
return write_t55xx(blks, blk_count, new_passwd, old_passwds, old_passwd_count);
|
||||
}
|
||||
|
||||
uint8_t write_em410x_electra_to_t55xx(uint8_t *uid, uint8_t *new_passwd, uint8_t *old_passwds, uint8_t old_passwd_count) {
|
||||
uint32_t blks[7] = {0x00};
|
||||
uint8_t blk_count = em410x_electra_t55xx_writer(uid, blks);
|
||||
if (blk_count == 0) {
|
||||
return STATUS_PAR_ERR;
|
||||
}
|
||||
return write_t55xx(blks, blk_count, new_passwd, old_passwds, old_passwd_count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write hidprox card data to t55xx
|
||||
*/
|
||||
@@ -124,4 +133,4 @@ uint8_t write_viking_to_t55xx(uint8_t *uid, uint8_t *new_passwd, uint8_t *old_pa
|
||||
/**
|
||||
* Set the LF card scanning timeout value (in milliseconds).
|
||||
*/
|
||||
void set_scan_tag_timeout(uint32_t ms) { g_timeout_readem_ms = ms; }
|
||||
void set_scan_tag_timeout(uint32_t ms) { g_timeout_readem_ms = ms; }
|
||||
|
||||
@@ -12,5 +12,6 @@ uint8_t scan_em410x(uint8_t *uid);
|
||||
uint8_t scan_hidprox(uint8_t *uid, uint8_t format_hint);
|
||||
uint8_t scan_viking(uint8_t *uid);
|
||||
uint8_t write_em410x_to_t55xx(uint8_t *uid, uint8_t *newkey, uint8_t *old_keys, uint8_t old_key_count);
|
||||
uint8_t write_em410x_electra_to_t55xx(uint8_t *uid, uint8_t *newkey, uint8_t *old_keys, uint8_t old_key_count);
|
||||
uint8_t write_hidprox_to_t55xx(uint8_t format, uint32_t fc, uint64_t cn, uint32_t il, uint32_t oem, uint8_t *new_passwd, uint8_t *old_passwds, uint8_t old_passwd_count);
|
||||
uint8_t write_viking_to_t55xx(uint8_t *uid, uint8_t *newkey, uint8_t *old_keys, uint8_t old_key_count);
|
||||
|
||||
@@ -406,8 +406,8 @@ class LFEMIdArgsUnit(DeviceRequiredUnit):
|
||||
def before_exec(self, args: argparse.Namespace):
|
||||
if not super().before_exec(args):
|
||||
return False
|
||||
if args.id is None or not re.match(r"^[a-fA-F0-9]{10}$", args.id):
|
||||
raise ArgsParserError("ID must include 10 HEX symbols")
|
||||
if args.id is None or not re.match(r"^([a-fA-F0-9]{10}|[a-fA-F0-9]{26})$", args.id):
|
||||
raise ArgsParserError("ID must include 10 or 26 HEX symbols")
|
||||
return True
|
||||
|
||||
def args_parser(self) -> ArgumentParserNoExit:
|
||||
@@ -2263,7 +2263,7 @@ class HFMFEConfig(SlotIndexArgsAndGoUnit, HF14AAntiCollArgsUnit, DeviceRequiredU
|
||||
change_done = True
|
||||
else:
|
||||
print(f'{color_string((CY, "Requested logging of MFC authentication data already disabled"))}')
|
||||
if args.enable_set_field_off_do_reset:
|
||||
if args.enable_field_off_do_reset:
|
||||
change_requested = True
|
||||
if not field_off_do_reset:
|
||||
field_off_do_reset = True
|
||||
@@ -2271,7 +2271,7 @@ class HFMFEConfig(SlotIndexArgsAndGoUnit, HF14AAntiCollArgsUnit, DeviceRequiredU
|
||||
change_done = True
|
||||
else:
|
||||
print(f'{color_string((CY, "Requested FIELD_OFF_DO_RESET already enabled"))}')
|
||||
elif args.disable_set_field_off_do_reset:
|
||||
elif args.disable_field_off_do_reset:
|
||||
change_requested = True
|
||||
if field_off_do_reset:
|
||||
field_off_do_reset = False
|
||||
@@ -3623,9 +3623,11 @@ class LFEM410xWriteT55xx(LFEMIdArgsUnit, ReaderRequiredUnit):
|
||||
|
||||
def on_exec(self, args: argparse.Namespace):
|
||||
id_hex = args.id
|
||||
if len(id_hex) not in (10, 26):
|
||||
raise ArgsParserError("Writing to T55xx supports 5-byte EM410X (10 hex) or 13-byte Electra (26 hex) IDs.")
|
||||
id_bytes = bytes.fromhex(id_hex)
|
||||
self.cmd.em410x_write_to_t55xx(id_bytes)
|
||||
print(f" - EM410x ID(10H): {id_hex} write done.")
|
||||
print(f" - EM410x ID write done: {id_hex}")
|
||||
|
||||
|
||||
@lf_hid_prox.command('read')
|
||||
|
||||
@@ -434,7 +434,12 @@ class ChameleonCMD:
|
||||
"""
|
||||
resp = self.device.send_cmd_sync(Command.EM410X_SCAN)
|
||||
if resp.status == Status.LF_TAG_OK:
|
||||
resp.parsed = struct.unpack('!h5s', resp.data) # tag type + uid
|
||||
tag_type = struct.unpack('!H', resp.data[:2])[0]
|
||||
if tag_type == TagSpecificType.EM410X_ELECTRA:
|
||||
fmt = '!H13s'
|
||||
else:
|
||||
fmt = '!H5s'
|
||||
resp.parsed = struct.unpack(fmt, resp.data[:struct.calcsize(fmt)]) # tag type + uid
|
||||
return resp
|
||||
|
||||
@expect_response(Status.LF_TAG_OK)
|
||||
@@ -445,10 +450,13 @@ class ChameleonCMD:
|
||||
:param id_bytes: ID card number
|
||||
:return:
|
||||
"""
|
||||
if len(id_bytes) != 5:
|
||||
raise ValueError("The id bytes length must equal 5")
|
||||
data = struct.pack(f'!5s4s{4*len(old_keys)}s', id_bytes, new_key, b''.join(old_keys))
|
||||
return self.device.send_cmd_sync(Command.EM410X_WRITE_TO_T55XX, data)
|
||||
if len(id_bytes) == 5:
|
||||
data = struct.pack(f'!5s4s{4*len(old_keys)}s', id_bytes, new_key, b''.join(old_keys))
|
||||
return self.device.send_cmd_sync(Command.EM410X_WRITE_TO_T55XX, data)
|
||||
if len(id_bytes) == 13:
|
||||
data = struct.pack(f'!13s4s{4*len(old_keys)}s', id_bytes, new_key, b''.join(old_keys))
|
||||
return self.device.send_cmd_sync(Command.EM410X_ELECTRA_WRITE_TO_T55XX, data)
|
||||
raise ValueError("The id bytes length must equal 5 (EM410X) or 13 (Electra)")
|
||||
|
||||
@expect_response(Status.LF_TAG_OK)
|
||||
def hidprox_scan(self, format: int):
|
||||
@@ -591,6 +599,12 @@ class ChameleonCMD:
|
||||
data = struct.pack('!BBB', SlotNumber.to_fw(slot_index), sense_type, enabled)
|
||||
return self.device.send_cmd_sync(Command.SET_SLOT_ENABLE, data)
|
||||
|
||||
def _get_active_lf_tag_type(self) -> TagSpecificType:
|
||||
slotinfo = self.get_slot_info()
|
||||
active_slot = SlotNumber.from_fw(self.get_active_slot())
|
||||
lf_tag_value = slotinfo[active_slot - 1]['lf']
|
||||
return TagSpecificType(lf_tag_value)
|
||||
|
||||
@expect_response(Status.SUCCESS)
|
||||
def em410x_set_emu_id(self, id: bytes):
|
||||
"""
|
||||
@@ -599,9 +613,18 @@ class ChameleonCMD:
|
||||
:param id_bytes: byte of the card number
|
||||
:return:
|
||||
"""
|
||||
if len(id) != 5:
|
||||
raise ValueError("The id bytes length must equal 5")
|
||||
data = struct.pack('5s', id)
|
||||
lf_tag_type = self._get_active_lf_tag_type()
|
||||
if lf_tag_type == TagSpecificType.EM410X_ELECTRA:
|
||||
expected_len = 13
|
||||
elif lf_tag_type == TagSpecificType.EM410X:
|
||||
expected_len = 5
|
||||
else:
|
||||
raise ValueError(f"Active LF slot type {lf_tag_type} is not EM410X")
|
||||
|
||||
if len(id) != expected_len:
|
||||
raise ValueError(f"The id bytes length must equal {expected_len}")
|
||||
|
||||
data = struct.pack(f'!{expected_len}s', id)
|
||||
return self.device.send_cmd_sync(Command.EM410X_SET_EMU_ID, data)
|
||||
|
||||
@expect_response(Status.SUCCESS)
|
||||
@@ -610,7 +633,34 @@ class ChameleonCMD:
|
||||
Get the emulated EM410x card id
|
||||
"""
|
||||
resp = self.device.send_cmd_sync(Command.EM410X_GET_EMU_ID)
|
||||
resp.parsed = resp.data
|
||||
if resp.status == Status.SUCCESS:
|
||||
data = resp.data
|
||||
id_bytes = data
|
||||
tag_type = None
|
||||
|
||||
if len(data) >= 2:
|
||||
try:
|
||||
candidate = TagSpecificType(int.from_bytes(data[:2], byteorder='big'))
|
||||
except ValueError:
|
||||
candidate = None
|
||||
|
||||
if candidate in (TagSpecificType.EM410X, TagSpecificType.EM410X_ELECTRA):
|
||||
expected_len = 13 if candidate == TagSpecificType.EM410X_ELECTRA else 5
|
||||
if len(data) == expected_len + 2:
|
||||
tag_type = candidate
|
||||
id_bytes = data[2:2 + expected_len]
|
||||
|
||||
if tag_type is None:
|
||||
lf_tag_type = self._get_active_lf_tag_type()
|
||||
if lf_tag_type == TagSpecificType.EM410X_ELECTRA:
|
||||
expected_len = 13
|
||||
elif lf_tag_type == TagSpecificType.EM410X:
|
||||
expected_len = 5
|
||||
else:
|
||||
expected_len = len(data)
|
||||
id_bytes = data[:expected_len]
|
||||
|
||||
resp.parsed = id_bytes
|
||||
return resp
|
||||
|
||||
@expect_response(Status.SUCCESS)
|
||||
|
||||
@@ -76,6 +76,7 @@ class Command(enum.IntEnum):
|
||||
|
||||
EM410X_SCAN = 3000
|
||||
EM410X_WRITE_TO_T55XX = 3001
|
||||
EM410X_ELECTRA_WRITE_TO_T55XX = 3006
|
||||
HIDPROX_SCAN = 3002
|
||||
HIDPROX_WRITE_TO_T55XX = 3003
|
||||
VIKING_SCAN = 3004
|
||||
@@ -261,6 +262,7 @@ class TagSpecificType(enum.IntEnum):
|
||||
EM410X_16 = 101
|
||||
EM410X_32 = 102
|
||||
EM410X_64 = 103
|
||||
EM410X_ELECTRA = 104
|
||||
# FDX-B
|
||||
# securakey
|
||||
# gallagher
|
||||
@@ -352,6 +354,8 @@ class TagSpecificType(enum.IntEnum):
|
||||
return "EM410X/32"
|
||||
elif self == TagSpecificType.EM410X_64:
|
||||
return "EM410X/64"
|
||||
elif self == TagSpecificType.EM410X_ELECTRA:
|
||||
return "EM410X Electra"
|
||||
elif self == TagSpecificType.HIDProx:
|
||||
return "HIDProx"
|
||||
elif self == TagSpecificType.Viking:
|
||||
@@ -630,4 +634,3 @@ class HIDFormat(enum.IntEnum):
|
||||
if self in descriptions:
|
||||
return descriptions[self]
|
||||
return "Invalid"
|
||||
|
||||
|
||||
@@ -221,16 +221,18 @@ endif()
|
||||
add_executable(mfulc_des_brute mfulc_des_brute.c)
|
||||
target_include_directories(mfulc_des_brute PRIVATE ${SRC_DIR})
|
||||
target_link_libraries(mfulc_des_brute PRIVATE ${LIBTHREAD} OpenSSL::Crypto)
|
||||
target_compile_options(mfulc_des_brute PRIVATE -Wno-deprecated-declarations)
|
||||
if (MSVC)
|
||||
target_compile_options(mfulc_des_brute PRIVATE /wd4996) # disable "deprecated declaration" warning
|
||||
else()
|
||||
target_compile_options(mfulc_des_brute PRIVATE -Wno-deprecated-declarations)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
target_compile_definitions(mfulc_des_brute PRIVATE _GNU_SOURCE)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
endif()
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||
target_compile_definitions(mfulc_des_brute PRIVATE HAVE_STRUCT_TIMESPEC)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
endif()
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
|
||||
# --- hardnested Executable ---
|
||||
add_executable(hardnested ${COMMON_FILES} ${HARDNESTED_SOURCES})
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
#include <pthread.h>
|
||||
#include <openssl/des.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define bswap64 _byteswap_uint64
|
||||
#else
|
||||
# define bswap64 __builtin_bswap64
|
||||
#endif
|
||||
|
||||
#define BLOCK_SIZE 8 // DES (and 3DES) block size in bytes
|
||||
#define KEY_SIZE 16 // Full 2TDEA key size (K1 || K2)
|
||||
#define BENCHMARK_FULL_KEYSPACE 0
|
||||
@@ -57,7 +63,7 @@ static void print_hex(const unsigned char *buf, size_t len) {
|
||||
}
|
||||
|
||||
static bool valid_lfsr_ulcg(uint64_t x64) {
|
||||
x64 = __builtin_bswap64(x64);
|
||||
x64 = bswap64(x64);
|
||||
uint16_t x16 = x64 >> 48;
|
||||
x16 = x16 << 15 | ((x16 >> 1) ^ ((x16 >> 3 ^ x16 >> 4 ^ x16 >> 6) & 1));
|
||||
if (x16 != ((x64 >> 32) & 0xFFFF)) return false;
|
||||
@@ -69,7 +75,7 @@ static bool valid_lfsr_ulcg(uint64_t x64) {
|
||||
}
|
||||
|
||||
static bool valid_lfsr_uscuidul(uint64_t x64) {
|
||||
x64 = __builtin_bswap64(x64);
|
||||
x64 = bswap64(x64);
|
||||
uint16_t x16 = x64 & 0xFFFF;
|
||||
for (int i = 0; i < 16; i++) x16 = x16 >> 1 | (x16 ^ x16 >> 2 ^ x16 >> 3 ^ x16 >> 5) << 15;
|
||||
if (x16 != ((x64 >> 16) & 0xFFFF)) return false;
|
||||
@@ -193,9 +199,9 @@ static void *worker(void *arg) {
|
||||
|
||||
// Check if out is 8-bit (1-byte) left rotated version of init_out
|
||||
// Need to convert to big-endian for byte rotation, then back to little-endian
|
||||
uint64_t init_be = __builtin_bswap64(init_out);
|
||||
uint64_t init_be = bswap64(init_out);
|
||||
uint64_t rotated_be = (init_be << 8) | (init_be >> 56);
|
||||
uint64_t rotated = __builtin_bswap64(rotated_be);
|
||||
uint64_t rotated = bswap64(rotated_be);
|
||||
match = (out == rotated);
|
||||
} else {
|
||||
// In counterfeit mode, check the resulting plaintext against LFSR
|
||||
|
||||
Reference in New Issue
Block a user