mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
style
This commit is contained in:
parent
08cd7315e4
commit
94c3bdd91c
17 changed files with 355 additions and 297 deletions
|
@ -169,12 +169,12 @@ void RunMod(void) {
|
||||||
|
|
||||||
Dbprintf(_YELLOW_("HF UNISNIFF started"));
|
Dbprintf(_YELLOW_("HF UNISNIFF started"));
|
||||||
|
|
||||||
const char *protocols[] = {"14a", "14b", "15", "iclass","user"};
|
const char *protocols[] = {"14a", "14b", "15", "iclass", "user"};
|
||||||
|
|
||||||
// some magic to allow for `hw standalone` command to trigger a particular sniff from inside the pm3 client
|
// some magic to allow for `hw standalone` command to trigger a particular sniff from inside the pm3 client
|
||||||
const char *bb = (const char*)BigBuf_get_EM_addr();
|
const char *bb = (const char *)BigBuf_get_EM_addr();
|
||||||
uint8_t sniff_protocol;
|
uint8_t sniff_protocol;
|
||||||
if (strlen(bb) > 0 ) {
|
if (strlen(bb) > 0) {
|
||||||
for (sniff_protocol = 0; sniff_protocol < ARRAYLEN(protocols); sniff_protocol++) {
|
for (sniff_protocol = 0; sniff_protocol < ARRAYLEN(protocols); sniff_protocol++) {
|
||||||
if (strcmp(protocols[sniff_protocol], bb) == 0) {
|
if (strcmp(protocols[sniff_protocol], bb) == 0) {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -31,13 +31,13 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#if defined(NDEBUG)
|
#if defined(NDEBUG)
|
||||||
#define ASSERT(x) ((void)0)
|
#define ASSERT(x) ((void)0)
|
||||||
#elif defined(ID48_NO_STDIO)
|
#elif defined(ID48_NO_STDIO)
|
||||||
#define ASSERT(x) ((void)0)
|
#define ASSERT(x) ((void)0)
|
||||||
#else // neither NDEBUG nor ID48_NO_STDIO defined
|
#else // neither NDEBUG nor ID48_NO_STDIO defined
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#define ASSERT(x) assert((x))
|
#define ASSERT(x) assert((x))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,11 +128,11 @@ typedef struct _ID48LIB_GRN {
|
||||||
/// Note: In C++, each parameter would be a reference (not pointer).
|
/// Note: In C++, each parameter would be a reference (not pointer).
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
void id48lib_generator(
|
void id48lib_generator(
|
||||||
const ID48LIB_KEY* key_96bit,
|
const ID48LIB_KEY *key_96bit,
|
||||||
const ID48LIB_NONCE* nonce_56bit,
|
const ID48LIB_NONCE *nonce_56bit,
|
||||||
ID48LIB_FRN* frn28_out,
|
ID48LIB_FRN *frn28_out,
|
||||||
ID48LIB_GRN* grn20_out
|
ID48LIB_GRN *grn20_out
|
||||||
);
|
);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes to allow iterative recovery
|
/// Initializes to allow iterative recovery
|
||||||
|
@ -165,10 +165,10 @@ void id48lib_generator(
|
||||||
/// Note: In C++, each parameter would be a reference (not pointer).
|
/// Note: In C++, each parameter would be a reference (not pointer).
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
void id48lib_key_recovery_init(
|
void id48lib_key_recovery_init(
|
||||||
const ID48LIB_KEY* input_partial_key,
|
const ID48LIB_KEY *input_partial_key,
|
||||||
const ID48LIB_NONCE* input_nonce,
|
const ID48LIB_NONCE *input_nonce,
|
||||||
const ID48LIB_FRN* input_frn,
|
const ID48LIB_FRN *input_frn,
|
||||||
const ID48LIB_GRN* input_grn
|
const ID48LIB_GRN *input_grn
|
||||||
);
|
);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This can be repeated called (after calling init())
|
/// This can be repeated called (after calling init())
|
||||||
|
@ -195,7 +195,7 @@ void id48lib_key_recovery_init(
|
||||||
/// Note: In C++, each parameter would be a reference (not pointer).
|
/// Note: In C++, each parameter would be a reference (not pointer).
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
bool id48lib_key_recovery_next(
|
bool id48lib_key_recovery_next(
|
||||||
ID48LIB_KEY* potential_key_output
|
ID48LIB_KEY *potential_key_output
|
||||||
);
|
);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
|
|
@ -50,7 +50,7 @@ static const uint8_t small_lut_group4[4] = { // aka 32 bits
|
||||||
0x8f, 0x34, 0x52, 0xe9,
|
0x8f, 0x34, 0x52, 0xe9,
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool get_bit(const uint8_t* table_start, uint32_t bit_idx) {
|
static inline bool get_bit(const uint8_t *table_start, uint32_t bit_idx) {
|
||||||
const uint32_t byte = bit_idx / 8u;
|
const uint32_t byte = bit_idx / 8u;
|
||||||
const uint8_t mask = 1u << (bit_idx % 8u);
|
const uint8_t mask = 1u << (bit_idx % 8u);
|
||||||
return (table_start[byte] & mask) != 0;
|
return (table_start[byte] & mask) != 0;
|
||||||
|
|
|
@ -242,34 +242,33 @@ static inline uint64_t reverse_bits_64(uint64_t n) {
|
||||||
// 0 // == 0 value defines as unstable state
|
// 0 // == 0 value defines as unstable state
|
||||||
#pragma endregion // bit definitions for the (stable) id48lib state register
|
#pragma endregion // bit definitions for the (stable) id48lib state register
|
||||||
#pragma region // single bit test/set/clear/flip/assign
|
#pragma region // single bit test/set/clear/flip/assign
|
||||||
static inline bool is_ssr_state_stable (const ID48LIBX_STATE_REGISTERS* ssr) { ASSERT(ssr != nullptr); return ((ssr->Raw & 1u) == 1u); }
|
static inline bool is_ssr_state_stable(const ID48LIBX_STATE_REGISTERS *ssr) { ASSERT(ssr != nullptr); return ((ssr->Raw & 1u) == 1u); }
|
||||||
static inline bool test_single_ssr_bit (const ID48LIBX_STATE_REGISTERS* ssr, size_t bit_index) { ASSERT(ssr != nullptr); ASSERT(bit_index < (sizeof(uint64_t) * 8)); return ((ssr->Raw) >> bit_index) & 1; }
|
static inline bool test_single_ssr_bit(const ID48LIBX_STATE_REGISTERS *ssr, size_t bit_index) { ASSERT(ssr != nullptr); ASSERT(bit_index < (sizeof(uint64_t) * 8)); return ((ssr->Raw) >> bit_index) & 1; }
|
||||||
static inline void set_single_ssr_bit ( ID48LIBX_STATE_REGISTERS* ssr, size_t bit_index) { ASSERT(ssr != nullptr); ASSERT(bit_index < (sizeof(uint64_t) * 8)); ssr->Raw |= ((uint64_t)(1ull << bit_index)); }
|
static inline void set_single_ssr_bit(ID48LIBX_STATE_REGISTERS *ssr, size_t bit_index) { ASSERT(ssr != nullptr); ASSERT(bit_index < (sizeof(uint64_t) * 8)); ssr->Raw |= ((uint64_t)(1ull << bit_index)); }
|
||||||
static inline void clear_single_ssr_bit ( ID48LIBX_STATE_REGISTERS* ssr, size_t bit_index) { ASSERT(ssr != nullptr); ASSERT(bit_index < (sizeof(uint64_t) * 8)); ssr->Raw &= ~((uint64_t)(1ull << bit_index)); }
|
static inline void clear_single_ssr_bit(ID48LIBX_STATE_REGISTERS *ssr, size_t bit_index) { ASSERT(ssr != nullptr); ASSERT(bit_index < (sizeof(uint64_t) * 8)); ssr->Raw &= ~((uint64_t)(1ull << bit_index)); }
|
||||||
static inline void flip_single_ssr_bit ( ID48LIBX_STATE_REGISTERS* ssr, size_t bit_index) { ASSERT(ssr != nullptr); ASSERT(bit_index < (sizeof(uint64_t) * 8)); ssr->Raw ^= ((uint64_t)(1ull << bit_index)); }
|
static inline void flip_single_ssr_bit(ID48LIBX_STATE_REGISTERS *ssr, size_t bit_index) { ASSERT(ssr != nullptr); ASSERT(bit_index < (sizeof(uint64_t) * 8)); ssr->Raw ^= ((uint64_t)(1ull << bit_index)); }
|
||||||
static inline void assign_single_ssr_bit ( ID48LIBX_STATE_REGISTERS* ssr, size_t bit_index, bool value) {
|
static inline void assign_single_ssr_bit(ID48LIBX_STATE_REGISTERS *ssr, size_t bit_index, bool value) {
|
||||||
ASSERT(ssr != nullptr);
|
ASSERT(ssr != nullptr);
|
||||||
ASSERT(bit_index < (sizeof(uint64_t) * 8));
|
ASSERT(bit_index < (sizeof(uint64_t) * 8));
|
||||||
if (value) {
|
if (value) {
|
||||||
set_single_ssr_bit(ssr, bit_index);
|
set_single_ssr_bit(ssr, bit_index);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
clear_single_ssr_bit(ssr, bit_index);
|
clear_single_ssr_bit(ssr, bit_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#pragma endregion // single bit test/set/clear/flip/assign
|
#pragma endregion // single bit test/set/clear/flip/assign
|
||||||
#pragma region // test/assign of temporaries a/b/c/i/j
|
#pragma region // test/assign of temporaries a/b/c/i/j
|
||||||
static inline void test_temporary_a(ID48LIBX_STATE_REGISTERS* ssr) { ASSERT(!is_ssr_state_stable(ssr)); test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_a); }
|
static inline void test_temporary_a(ID48LIBX_STATE_REGISTERS *ssr) { ASSERT(!is_ssr_state_stable(ssr)); test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_a); }
|
||||||
static inline void test_temporary_b(ID48LIBX_STATE_REGISTERS* ssr) { ASSERT(!is_ssr_state_stable(ssr)); test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_b); }
|
static inline void test_temporary_b(ID48LIBX_STATE_REGISTERS *ssr) { ASSERT(!is_ssr_state_stable(ssr)); test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_b); }
|
||||||
static inline void test_temporary_c(ID48LIBX_STATE_REGISTERS* ssr) { ASSERT(!is_ssr_state_stable(ssr)); test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_c); }
|
static inline void test_temporary_c(ID48LIBX_STATE_REGISTERS *ssr) { ASSERT(!is_ssr_state_stable(ssr)); test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_c); }
|
||||||
static inline void test_temporary_i(ID48LIBX_STATE_REGISTERS* ssr) { ASSERT(!is_ssr_state_stable(ssr)); test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_i); }
|
static inline void test_temporary_i(ID48LIBX_STATE_REGISTERS *ssr) { ASSERT(!is_ssr_state_stable(ssr)); test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_i); }
|
||||||
static inline void test_temporary_j(ID48LIBX_STATE_REGISTERS* ssr) { ASSERT(!is_ssr_state_stable(ssr)); test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_j); }
|
static inline void test_temporary_j(ID48LIBX_STATE_REGISTERS *ssr) { ASSERT(!is_ssr_state_stable(ssr)); test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_j); }
|
||||||
|
|
||||||
static inline void assign_temporary_a(ID48LIBX_STATE_REGISTERS* ssr, bool v) { ASSERT(!is_ssr_state_stable(ssr)); assign_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_a, v); }
|
static inline void assign_temporary_a(ID48LIBX_STATE_REGISTERS *ssr, bool v) { ASSERT(!is_ssr_state_stable(ssr)); assign_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_a, v); }
|
||||||
static inline void assign_temporary_b(ID48LIBX_STATE_REGISTERS* ssr, bool v) { ASSERT(!is_ssr_state_stable(ssr)); assign_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_b, v); }
|
static inline void assign_temporary_b(ID48LIBX_STATE_REGISTERS *ssr, bool v) { ASSERT(!is_ssr_state_stable(ssr)); assign_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_b, v); }
|
||||||
static inline void assign_temporary_c(ID48LIBX_STATE_REGISTERS* ssr, bool v) { ASSERT(!is_ssr_state_stable(ssr)); assign_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_c, v); }
|
static inline void assign_temporary_c(ID48LIBX_STATE_REGISTERS *ssr, bool v) { ASSERT(!is_ssr_state_stable(ssr)); assign_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_c, v); }
|
||||||
static inline void assign_temporary_i(ID48LIBX_STATE_REGISTERS* ssr, bool v) { ASSERT(!is_ssr_state_stable(ssr)); assign_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_i, v); }
|
static inline void assign_temporary_i(ID48LIBX_STATE_REGISTERS *ssr, bool v) { ASSERT(!is_ssr_state_stable(ssr)); assign_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_i, v); }
|
||||||
static inline void assign_temporary_j(ID48LIBX_STATE_REGISTERS* ssr, bool v) { ASSERT(!is_ssr_state_stable(ssr)); assign_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_j, v); }
|
static inline void assign_temporary_j(ID48LIBX_STATE_REGISTERS *ssr, bool v) { ASSERT(!is_ssr_state_stable(ssr)); assign_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_j, v); }
|
||||||
#pragma endregion // test/assign of temporaries a/b/c/i/j
|
#pragma endregion // test/assign of temporaries a/b/c/i/j
|
||||||
|
|
||||||
#pragma region // Mask & Macro to get registers (in minimal bit form)
|
#pragma region // Mask & Macro to get registers (in minimal bit form)
|
||||||
|
@ -301,17 +300,17 @@ static inline void assign_temporary_j(ID48LIBX_STATE_REGISTERS* ssr, bool v) { A
|
||||||
#define SSR_VALUE_MASK_REG_M (0x00007Fu) // 7 bits
|
#define SSR_VALUE_MASK_REG_M (0x00007Fu) // 7 bits
|
||||||
#define SSR_VALUE_MASK_REG_R (0x00007Fu) // 7 bits
|
#define SSR_VALUE_MASK_REG_R (0x00007Fu) // 7 bits
|
||||||
|
|
||||||
static inline uint16_t get_register_h(const ID48LIBX_STATE_REGISTERS* ssr) { return ((uint16_t)(ssr->Raw >> SSR_SHIFT_COUNT_REG_H)) & (SSR_VALUE_MASK_REG_H); }
|
static inline uint16_t get_register_h(const ID48LIBX_STATE_REGISTERS *ssr) { return ((uint16_t)(ssr->Raw >> SSR_SHIFT_COUNT_REG_H)) & (SSR_VALUE_MASK_REG_H); }
|
||||||
static inline uint32_t get_register_g(const ID48LIBX_STATE_REGISTERS* ssr) { return ((uint32_t)(ssr->Raw >> SSR_SHIFT_COUNT_REG_G)) & (SSR_VALUE_MASK_REG_G); }
|
static inline uint32_t get_register_g(const ID48LIBX_STATE_REGISTERS *ssr) { return ((uint32_t)(ssr->Raw >> SSR_SHIFT_COUNT_REG_G)) & (SSR_VALUE_MASK_REG_G); }
|
||||||
static inline uint8_t get_register_l(const ID48LIBX_STATE_REGISTERS* ssr) { return ((uint8_t )(ssr->Raw >> SSR_SHIFT_COUNT_REG_L)) & (SSR_VALUE_MASK_REG_L); }
|
static inline uint8_t get_register_l(const ID48LIBX_STATE_REGISTERS *ssr) { return ((uint8_t)(ssr->Raw >> SSR_SHIFT_COUNT_REG_L)) & (SSR_VALUE_MASK_REG_L); }
|
||||||
static inline uint8_t get_register_m(const ID48LIBX_STATE_REGISTERS* ssr) { return ((uint8_t )(ssr->Raw >> SSR_SHIFT_COUNT_REG_M)) & (SSR_VALUE_MASK_REG_M); }
|
static inline uint8_t get_register_m(const ID48LIBX_STATE_REGISTERS *ssr) { return ((uint8_t)(ssr->Raw >> SSR_SHIFT_COUNT_REG_M)) & (SSR_VALUE_MASK_REG_M); }
|
||||||
static inline uint8_t get_register_r(const ID48LIBX_STATE_REGISTERS* ssr) { return ((uint8_t )(ssr->Raw >> SSR_SHIFT_COUNT_REG_R)) & (SSR_VALUE_MASK_REG_R); }
|
static inline uint8_t get_register_r(const ID48LIBX_STATE_REGISTERS *ssr) { return ((uint8_t)(ssr->Raw >> SSR_SHIFT_COUNT_REG_R)) & (SSR_VALUE_MASK_REG_R); }
|
||||||
|
|
||||||
static inline void set_register_h(ID48LIBX_STATE_REGISTERS* ssr, uint16_t v) { ASSERT((v & SSR_VALUE_MASK_REG_H) == v); ssr->Raw = (ssr->Raw & SSR_BITMASK_WITHOUT_REG_H) | (((uint64_t)(v & SSR_VALUE_MASK_REG_H)) << SSR_SHIFT_COUNT_REG_H); }
|
static inline void set_register_h(ID48LIBX_STATE_REGISTERS *ssr, uint16_t v) { ASSERT((v & SSR_VALUE_MASK_REG_H) == v); ssr->Raw = (ssr->Raw & SSR_BITMASK_WITHOUT_REG_H) | (((uint64_t)(v & SSR_VALUE_MASK_REG_H)) << SSR_SHIFT_COUNT_REG_H); }
|
||||||
static inline void set_register_g(ID48LIBX_STATE_REGISTERS* ssr, uint32_t v) { ASSERT((v & SSR_VALUE_MASK_REG_G) == v); ssr->Raw = (ssr->Raw & SSR_BITMASK_WITHOUT_REG_G) | (((uint64_t)(v & SSR_VALUE_MASK_REG_G)) << SSR_SHIFT_COUNT_REG_G); }
|
static inline void set_register_g(ID48LIBX_STATE_REGISTERS *ssr, uint32_t v) { ASSERT((v & SSR_VALUE_MASK_REG_G) == v); ssr->Raw = (ssr->Raw & SSR_BITMASK_WITHOUT_REG_G) | (((uint64_t)(v & SSR_VALUE_MASK_REG_G)) << SSR_SHIFT_COUNT_REG_G); }
|
||||||
static inline void set_register_l(ID48LIBX_STATE_REGISTERS* ssr, uint8_t v) { ASSERT((v & SSR_VALUE_MASK_REG_L) == v); ssr->Raw = (ssr->Raw & SSR_BITMASK_WITHOUT_REG_L) | (((uint64_t)(v & SSR_VALUE_MASK_REG_L)) << SSR_SHIFT_COUNT_REG_L); }
|
static inline void set_register_l(ID48LIBX_STATE_REGISTERS *ssr, uint8_t v) { ASSERT((v & SSR_VALUE_MASK_REG_L) == v); ssr->Raw = (ssr->Raw & SSR_BITMASK_WITHOUT_REG_L) | (((uint64_t)(v & SSR_VALUE_MASK_REG_L)) << SSR_SHIFT_COUNT_REG_L); }
|
||||||
static inline void set_register_m(ID48LIBX_STATE_REGISTERS* ssr, uint8_t v) { ASSERT((v & SSR_VALUE_MASK_REG_M) == v); ssr->Raw = (ssr->Raw & SSR_BITMASK_WITHOUT_REG_M) | (((uint64_t)(v & SSR_VALUE_MASK_REG_M)) << SSR_SHIFT_COUNT_REG_M); }
|
static inline void set_register_m(ID48LIBX_STATE_REGISTERS *ssr, uint8_t v) { ASSERT((v & SSR_VALUE_MASK_REG_M) == v); ssr->Raw = (ssr->Raw & SSR_BITMASK_WITHOUT_REG_M) | (((uint64_t)(v & SSR_VALUE_MASK_REG_M)) << SSR_SHIFT_COUNT_REG_M); }
|
||||||
static inline void set_register_r(ID48LIBX_STATE_REGISTERS* ssr, uint8_t v) { ASSERT((v & SSR_VALUE_MASK_REG_R) == v); ssr->Raw = (ssr->Raw & SSR_BITMASK_WITHOUT_REG_R) | (((uint64_t)(v & SSR_VALUE_MASK_REG_R)) << SSR_SHIFT_COUNT_REG_R); }
|
static inline void set_register_r(ID48LIBX_STATE_REGISTERS *ssr, uint8_t v) { ASSERT((v & SSR_VALUE_MASK_REG_R) == v); ssr->Raw = (ssr->Raw & SSR_BITMASK_WITHOUT_REG_R) | (((uint64_t)(v & SSR_VALUE_MASK_REG_R)) << SSR_SHIFT_COUNT_REG_R); }
|
||||||
#pragma endregion // Mask & Macro to get registers (in minimal bit form)
|
#pragma endregion // Mask & Macro to get registers (in minimal bit form)
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -322,7 +321,7 @@ static inline void set_register_r(ID48LIBX_STATE_REGISTERS* ssr, uint8_t v) { A
|
||||||
/// <param name="k96">key in pm3 order</param>
|
/// <param name="k96">key in pm3 order</param>
|
||||||
/// <param name="n56">nonce in pm3 order</param>
|
/// <param name="n56">nonce in pm3 order</param>
|
||||||
/// <returns>56-bit value p₅₅..p₀₀</returns>
|
/// <returns>56-bit value p₅₅..p₀₀</returns>
|
||||||
static inline uint64_t calculate__p55_p00(const ID48LIB_KEY* k96, const ID48LIB_NONCE* n56) {
|
static inline uint64_t calculate__p55_p00(const ID48LIB_KEY *k96, const ID48LIB_NONCE *n56) {
|
||||||
// messy ... have to reverse the bits AND shift them into position,
|
// messy ... have to reverse the bits AND shift them into position,
|
||||||
// perform the addition, and then reverse bits again to return to
|
// perform the addition, and then reverse bits again to return to
|
||||||
// native bit order (subscript is same as bit position).
|
// native bit order (subscript is same as bit position).
|
||||||
|
@ -367,7 +366,7 @@ static inline uint64_t calculate__p55_p00(const ID48LIB_KEY* k96, const ID48LIB_
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="p55_p00">56 bit value: p₅₅..p₀₀</param>
|
/// <param name="p55_p00">56 bit value: p₅₅..p₀₀</param>
|
||||||
/// <returns>44-bit value: q₄₃..q₀₀</returns>
|
/// <returns>44-bit value: q₄₃..q₀₀</returns>
|
||||||
static inline uint64_t calculate__q43_q00(const uint64_t* p55_p00) {
|
static inline uint64_t calculate__q43_q00(const uint64_t *p55_p00) {
|
||||||
ASSERT(p55_p00 != nullptr);
|
ASSERT(p55_p00 != nullptr);
|
||||||
static const uint64_t C_BITMASK44 = (1ull << 44) - 1u;
|
static const uint64_t C_BITMASK44 = (1ull << 44) - 1u;
|
||||||
uint64_t result = (*p55_p00 >> 2);
|
uint64_t result = (*p55_p00 >> 2);
|
||||||
|
@ -382,7 +381,7 @@ static inline uint64_t calculate__q43_q00(const uint64_t* p55_p00) {
|
||||||
/// Relies on old g22 bit (now in L00).
|
/// Relies on old g22 bit (now in L00).
|
||||||
/// May modify G00, G03, G04, G05, G06, G13, G16
|
/// May modify G00, G03, G04, G05, G06, G13, G16
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static inline void g_successor(ID48LIBX_STATE_REGISTERS* ssr) {
|
static inline void g_successor(ID48LIBX_STATE_REGISTERS *ssr) {
|
||||||
ASSERT(ssr != nullptr);
|
ASSERT(ssr != nullptr);
|
||||||
ASSERT(!is_ssr_state_stable(ssr));
|
ASSERT(!is_ssr_state_stable(ssr));
|
||||||
assign_single_ssr_bit(ssr, SSR_BIT_G00, test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_j));
|
assign_single_ssr_bit(ssr, SSR_BIT_G00, test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_j));
|
||||||
|
@ -403,11 +402,12 @@ static inline void g_successor(ID48LIBX_STATE_REGISTERS* ssr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline ID48LIBX_STATE_REGISTERS init_id48libx_state_register(const ID48LIB_KEY* k96, const ID48LIB_NONCE* n56) {
|
static inline ID48LIBX_STATE_REGISTERS init_id48libx_state_register(const ID48LIB_KEY *k96, const ID48LIB_NONCE *n56) {
|
||||||
ASSERT(k96 != nullptr);
|
ASSERT(k96 != nullptr);
|
||||||
ASSERT(n56 != nullptr);
|
ASSERT(n56 != nullptr);
|
||||||
ID48LIBX_STATE_REGISTERS result; result.Raw = 0;
|
ID48LIBX_STATE_REGISTERS result;
|
||||||
ID48LIBX_STATE_REGISTERS* const ssr = &result; // the pointer is constant ... not the value it points to
|
result.Raw = 0;
|
||||||
|
ID48LIBX_STATE_REGISTERS *const ssr = &result; // the pointer is constant ... not the value it points to
|
||||||
|
|
||||||
const uint64_t p55_p00 = calculate__p55_p00(k96, n56);
|
const uint64_t p55_p00 = calculate__p55_p00(k96, n56);
|
||||||
// p55_p00 is used to set initial value of register l
|
// p55_p00 is used to set initial value of register l
|
||||||
|
@ -442,13 +442,12 @@ static inline ID48LIBX_STATE_REGISTERS init_id48libx_state_register(const ID48LI
|
||||||
// input bits for `j` during init are q00..q19, with q19 used first
|
// input bits for `j` during init are q00..q19, with q19 used first
|
||||||
// For ease of use, I'll generate this as q00..q19, so the loop
|
// For ease of use, I'll generate this as q00..q19, so the loop
|
||||||
// can test the lsb (and then shift it right one bit)
|
// can test the lsb (and then shift it right one bit)
|
||||||
uint32_t q00_q19 = reverse_bits_32( ((uint32_t)q43_q00) << 12 );
|
uint32_t q00_q19 = reverse_bits_32(((uint32_t)q43_q00) << 12);
|
||||||
uint32_t q_lsb_next = q00_q19;
|
uint32_t q_lsb_next = q00_q19;
|
||||||
ssr->Raw |= 1u;
|
ssr->Raw |= 1u;
|
||||||
|
|
||||||
// G(g,0,j) twenty times, using q19, q18, ... q00 for `j`
|
// G(g,0,j) twenty times, using q19, q18, ... q00 for `j`
|
||||||
for (uint8_t ix = 0; ix < 20; ++ix)
|
for (uint8_t ix = 0; ix < 20; ++ix) {
|
||||||
{
|
|
||||||
ASSERT(is_ssr_state_stable(ssr));
|
ASSERT(is_ssr_state_stable(ssr));
|
||||||
ssr->Raw <<= 1; // starts the process ... it's now an unstable value
|
ssr->Raw <<= 1; // starts the process ... it's now an unstable value
|
||||||
ASSERT(!is_ssr_state_stable(ssr));
|
ASSERT(!is_ssr_state_stable(ssr));
|
||||||
|
@ -485,7 +484,7 @@ static inline ID48LIBX_STATE_REGISTERS init_id48libx_state_register(const ID48LI
|
||||||
/// If ssr is in unstable state, caller is responsible for ensuring
|
/// If ssr is in unstable state, caller is responsible for ensuring
|
||||||
/// the values have not changed.
|
/// the values have not changed.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
static inline bool calculate_feedback_h(const ID48LIBX_STATE_REGISTERS* ssr) {
|
static inline bool calculate_feedback_h(const ID48LIBX_STATE_REGISTERS *ssr) {
|
||||||
ASSERT(ssr != nullptr);
|
ASSERT(ssr != nullptr);
|
||||||
// ( h₀₁ && h₀₈ ) || ( h₀₉ && h₁₁ ) || (!h₁₂ )
|
// ( h₀₁ && h₀₈ ) || ( h₀₉ && h₁₁ ) || (!h₁₂ )
|
||||||
// \____ a1 ____/ \____ a2 ____/ \____ a3 ____/
|
// \____ a1 ____/ \____ a2 ____/ \____ a3 ____/
|
||||||
|
@ -510,7 +509,7 @@ static inline bool calculate_feedback_h(const ID48LIBX_STATE_REGISTERS* ssr) {
|
||||||
/// fₗ(...) matches the research paper, definition 3.4
|
/// fₗ(...) matches the research paper, definition 3.4
|
||||||
/// hard-coded to use bits for calculation of 'a'
|
/// hard-coded to use bits for calculation of 'a'
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static inline bool calculate_feedback_l(const ID48LIBX_STATE_REGISTERS* ssr) {
|
static inline bool calculate_feedback_l(const ID48LIBX_STATE_REGISTERS *ssr) {
|
||||||
ASSERT(ssr != nullptr);
|
ASSERT(ssr != nullptr);
|
||||||
// a = fₗ( g00 g04 g06 g13 g18 h03 ) ⊕ g22 ⊕ r02 ⊕ r06
|
// a = fₗ( g00 g04 g06 g13 g18 h03 ) ⊕ g22 ⊕ r02 ⊕ r06
|
||||||
// fₗ( x₀ x₁ x₂ x₃ x₄ x₅ )
|
// fₗ( x₀ x₁ x₂ x₃ x₄ x₅ )
|
||||||
|
@ -534,7 +533,7 @@ static inline bool calculate_feedback_l(const ID48LIBX_STATE_REGISTERS* ssr) {
|
||||||
/// fₘ(...) matches the research paper, definition 3.5
|
/// fₘ(...) matches the research paper, definition 3.5
|
||||||
/// hard-coded to use bits for calculation of 'b'
|
/// hard-coded to use bits for calculation of 'b'
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static inline bool calculate_feedback_m(const ID48LIBX_STATE_REGISTERS* ssr) {
|
static inline bool calculate_feedback_m(const ID48LIBX_STATE_REGISTERS *ssr) {
|
||||||
ASSERT(ssr != nullptr);
|
ASSERT(ssr != nullptr);
|
||||||
// b = fₘ( g01 g05 g10 g15 h00 h07 ) ⊕ l00 ⊕ l03 ⊕ l06
|
// b = fₘ( g01 g05 g10 g15 h00 h07 ) ⊕ l00 ⊕ l03 ⊕ l06
|
||||||
// fₘ( x₀ x₁ x₂ x₃ x₄ x₅ )
|
// fₘ( x₀ x₁ x₂ x₃ x₄ x₅ )
|
||||||
|
@ -558,7 +557,7 @@ static inline bool calculate_feedback_m(const ID48LIBX_STATE_REGISTERS* ssr) {
|
||||||
/// fᵣ(...) matches the research paper, definition 3.6
|
/// fᵣ(...) matches the research paper, definition 3.6
|
||||||
/// hard-coded to use bits for calculation of 'c'
|
/// hard-coded to use bits for calculation of 'c'
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static inline bool calculate_feedback_r(const ID48LIBX_STATE_REGISTERS* ssr) {
|
static inline bool calculate_feedback_r(const ID48LIBX_STATE_REGISTERS *ssr) {
|
||||||
ASSERT(ssr != nullptr);
|
ASSERT(ssr != nullptr);
|
||||||
ASSERT(!is_ssr_state_stable(ssr));
|
ASSERT(!is_ssr_state_stable(ssr));
|
||||||
// c = fᵣ( g02 g03⊕i g09 g14 g16 h01 ) ⊕ m00 ⊕ m03 ⊕ m06
|
// c = fᵣ( g02 g03⊕i g09 g14 g16 h01 ) ⊕ m00 ⊕ m03 ⊕ m06
|
||||||
|
@ -583,7 +582,7 @@ static inline bool calculate_feedback_r(const ID48LIBX_STATE_REGISTERS* ssr) {
|
||||||
/// Matches the research paper, definition 3.7
|
/// Matches the research paper, definition 3.7
|
||||||
/// See also Definition 3.2, defining that parameter as `j`.
|
/// See also Definition 3.2, defining that parameter as `j`.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static inline bool calculate_j(const ID48LIBX_STATE_REGISTERS* ssr) {
|
static inline bool calculate_j(const ID48LIBX_STATE_REGISTERS *ssr) {
|
||||||
ASSERT(ssr != nullptr);
|
ASSERT(ssr != nullptr);
|
||||||
// g′ := G(g, i, l₀₁ ⊕ m₀₆ ⊕ h₀₂ ⊕ h₀₈ ⊕ h₁₂)
|
// g′ := G(g, i, l₀₁ ⊕ m₀₆ ⊕ h₀₂ ⊕ h₀₈ ⊕ h₁₂)
|
||||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^------ calculates `j`
|
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^------ calculates `j`
|
||||||
|
@ -602,9 +601,9 @@ static inline bool calculate_j(const ID48LIBX_STATE_REGISTERS* ssr) {
|
||||||
/// Calculates a, b, c, j and new value for H₀₀.
|
/// Calculates a, b, c, j and new value for H₀₀.
|
||||||
/// These are the only bits changed by this function.
|
/// These are the only bits changed by this function.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static inline void calculate_temporaries(ID48LIBX_STATE_REGISTERS* ssr) {
|
static inline void calculate_temporaries(ID48LIBX_STATE_REGISTERS *ssr) {
|
||||||
ASSERT(ssr != nullptr);
|
ASSERT(ssr != nullptr);
|
||||||
#pragma region // to be removed after all is validated
|
#pragma region // to be removed after all is validated
|
||||||
static const uint64_t bits_must_remain_same_mask =
|
static const uint64_t bits_must_remain_same_mask =
|
||||||
~(
|
~(
|
||||||
(1ull << SSR_UNSTABLE_BIT_a) |
|
(1ull << SSR_UNSTABLE_BIT_a) |
|
||||||
|
@ -616,7 +615,7 @@ static inline void calculate_temporaries(ID48LIBX_STATE_REGISTERS* ssr) {
|
||||||
|
|
||||||
const uint64_t backup = ssr->Raw & bits_must_remain_same_mask;
|
const uint64_t backup = ssr->Raw & bits_must_remain_same_mask;
|
||||||
(void)backup; // to avoid warning about unused variable
|
(void)backup; // to avoid warning about unused variable
|
||||||
#pragma endregion // to be removed after all is validated
|
#pragma endregion // to be removed after all is validated
|
||||||
|
|
||||||
// Only bits that change value: H00, a, b, c, j
|
// Only bits that change value: H00, a, b, c, j
|
||||||
|
|
||||||
|
@ -643,25 +642,26 @@ static inline void calculate_temporaries(ID48LIBX_STATE_REGISTERS* ssr) {
|
||||||
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_M03)) flip_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_c);
|
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_M03)) flip_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_c);
|
||||||
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_M06)) flip_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_c);
|
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_M06)) flip_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_c);
|
||||||
|
|
||||||
#pragma region // to be removed after all is validated
|
#pragma region // to be removed after all is validated
|
||||||
const uint64_t chk = ssr->Raw & bits_must_remain_same_mask;
|
const uint64_t chk = ssr->Raw & bits_must_remain_same_mask;
|
||||||
(void)chk; // to avoid warning about unused variable
|
(void)chk; // to avoid warning about unused variable
|
||||||
ASSERT(chk == backup);
|
ASSERT(chk == backup);
|
||||||
#pragma endregion // to be removed after all is validated
|
#pragma endregion // to be removed after all is validated
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline OUTPUT_INDEX2 calculate_output_index(const ID48LIBX_STATE_REGISTERS* ssr) {
|
static inline OUTPUT_INDEX2 calculate_output_index(const ID48LIBX_STATE_REGISTERS *ssr) {
|
||||||
// Fₒ( abc l₀l₂l₃l₄l₅l₆ m₀m₁m₃m₅ r₀r₁r₂r₃r₄r₅r₆ )
|
// Fₒ( abc l₀l₂l₃l₄l₅l₆ m₀m₁m₃m₅ r₀r₁r₂r₃r₄r₅r₆ )
|
||||||
// msb 19 ---^ lsb 00 ---^^
|
// msb 19 ---^ lsb 00 ---^^
|
||||||
ASSERT(ssr != nullptr);
|
ASSERT(ssr != nullptr);
|
||||||
ASSERT(!is_ssr_state_stable(ssr));
|
ASSERT(!is_ssr_state_stable(ssr));
|
||||||
OUTPUT_INDEX2 result; result.Raw = 0;
|
OUTPUT_INDEX2 result;
|
||||||
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_a )) result.Raw |= (1u << 19);
|
result.Raw = 0;
|
||||||
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_b )) result.Raw |= (1u << 18);
|
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_a)) result.Raw |= (1u << 19);
|
||||||
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_c )) result.Raw |= (1u << 17);
|
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_b)) result.Raw |= (1u << 18);
|
||||||
|
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_c)) result.Raw |= (1u << 17);
|
||||||
//bool bit17 = test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_c);
|
//bool bit17 = test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_c);
|
||||||
//if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_i) ) bit17 = !bit17;
|
//if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_i) ) bit17 = !bit17;
|
||||||
//if (bit17 ) result.Raw |= (1u << 17);
|
//if (bit17 ) result.Raw |= (1u << 17);
|
||||||
|
@ -686,7 +686,7 @@ static inline OUTPUT_INDEX2 calculate_output_index(const ID48LIBX_STATE_REGISTER
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns a single bit corresponding to the output bit for this transition
|
// returns a single bit corresponding to the output bit for this transition
|
||||||
static inline bool calculate_successor_state(ID48LIBX_STATE_REGISTERS* ssr, bool i) {
|
static inline bool calculate_successor_state(ID48LIBX_STATE_REGISTERS *ssr, bool i) {
|
||||||
ASSERT(ssr != nullptr);
|
ASSERT(ssr != nullptr);
|
||||||
ASSERT(is_ssr_state_stable(ssr));
|
ASSERT(is_ssr_state_stable(ssr));
|
||||||
|
|
||||||
|
@ -748,14 +748,15 @@ static inline bool calculate_successor_state(ID48LIBX_STATE_REGISTERS* ssr, bool
|
||||||
/// by one bit each iteration (allowing least significant bit
|
/// by one bit each iteration (allowing least significant bit
|
||||||
/// to always be the input bit).
|
/// to always be the input bit).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static inline INPUT_BITS2 get_key_input_bits(const ID48LIB_KEY* k) {
|
static inline INPUT_BITS2 get_key_input_bits(const ID48LIB_KEY *k) {
|
||||||
ASSERT(k != nullptr);
|
ASSERT(k != nullptr);
|
||||||
|
|
||||||
// Per research paper, key bit 39 is used first.
|
// Per research paper, key bit 39 is used first.
|
||||||
// So, what should end up in result is: 0²⁴ k₀₀..K₃₉
|
// So, what should end up in result is: 0²⁴ k₀₀..K₃₉
|
||||||
// This allows simply shifting the lsb out each cycle....
|
// This allows simply shifting the lsb out each cycle....
|
||||||
|
|
||||||
INPUT_BITS2 result; result.Raw = 0;
|
INPUT_BITS2 result;
|
||||||
|
result.Raw = 0;
|
||||||
|
|
||||||
// k[ 0] :== K₉₅..K₈₈
|
// k[ 0] :== K₉₅..K₈₈
|
||||||
// ...
|
// ...
|
||||||
|
@ -775,19 +776,19 @@ static inline INPUT_BITS2 get_key_input_bits(const ID48LIB_KEY* k) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool shift_out_next_input_bit(INPUT_BITS2* inputs) {
|
static inline bool shift_out_next_input_bit(INPUT_BITS2 *inputs) {
|
||||||
ASSERT(inputs != nullptr);
|
ASSERT(inputs != nullptr);
|
||||||
bool result = inputs->Raw & 1ull;
|
bool result = inputs->Raw & 1ull;
|
||||||
inputs->Raw >>= 1;
|
inputs->Raw >>= 1;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
static inline void shift_in_next_output_bit(OUTPUT_BITS2* outputs, bool v) {
|
static inline void shift_in_next_output_bit(OUTPUT_BITS2 *outputs, bool v) {
|
||||||
ASSERT(outputs != nullptr);
|
ASSERT(outputs != nullptr);
|
||||||
outputs->Raw <<= 1;
|
outputs->Raw <<= 1;
|
||||||
if (v) outputs->Raw |= 1ull;
|
if (v) outputs->Raw |= 1ull;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void extract_frn(const OUTPUT_BITS2* outputs, ID48LIB_FRN* frn28_out) {
|
static inline void extract_frn(const OUTPUT_BITS2 *outputs, ID48LIB_FRN *frn28_out) {
|
||||||
ASSERT(outputs != nullptr);
|
ASSERT(outputs != nullptr);
|
||||||
ASSERT(frn28_out != nullptr);
|
ASSERT(frn28_out != nullptr);
|
||||||
|
|
||||||
|
@ -802,7 +803,7 @@ static inline void extract_frn(const OUTPUT_BITS2* outputs, ID48LIB_FRN* frn28_o
|
||||||
frn28_out->frn[2] = (uint8_t)((tmp >> (8 * 1)) & 0xFFu);
|
frn28_out->frn[2] = (uint8_t)((tmp >> (8 * 1)) & 0xFFu);
|
||||||
frn28_out->frn[3] = (uint8_t)((tmp >> (8 * 0)) & 0xFFu);
|
frn28_out->frn[3] = (uint8_t)((tmp >> (8 * 0)) & 0xFFu);
|
||||||
}
|
}
|
||||||
static inline void extract_grn(const OUTPUT_BITS2* outputs, ID48LIB_GRN* grn20_out) {
|
static inline void extract_grn(const OUTPUT_BITS2 *outputs, ID48LIB_GRN *grn20_out) {
|
||||||
ASSERT(outputs != nullptr);
|
ASSERT(outputs != nullptr);
|
||||||
ASSERT(grn20_out != nullptr);
|
ASSERT(grn20_out != nullptr);
|
||||||
memset(grn20_out, 0, sizeof(ID48LIB_GRN));
|
memset(grn20_out, 0, sizeof(ID48LIB_GRN));
|
||||||
|
@ -817,12 +818,11 @@ static inline void extract_grn(const OUTPUT_BITS2* outputs, ID48LIB_GRN* grn20_o
|
||||||
}
|
}
|
||||||
|
|
||||||
static void retro_generator_impl(
|
static void retro_generator_impl(
|
||||||
const ID48LIB_KEY* k,
|
const ID48LIB_KEY *k,
|
||||||
const ID48LIB_NONCE* n,
|
const ID48LIB_NONCE *n,
|
||||||
ID48LIB_FRN* frn28_out,
|
ID48LIB_FRN *frn28_out,
|
||||||
ID48LIB_GRN* grn20_out
|
ID48LIB_GRN *grn20_out
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
ASSERT(k != nullptr);
|
ASSERT(k != nullptr);
|
||||||
ASSERT(n != nullptr);
|
ASSERT(n != nullptr);
|
||||||
ASSERT(frn28_out != nullptr);
|
ASSERT(frn28_out != nullptr);
|
||||||
|
@ -834,7 +834,8 @@ static void retro_generator_impl(
|
||||||
|
|
||||||
// get 55-bit successor state input
|
// get 55-bit successor state input
|
||||||
INPUT_BITS2 inputs = get_key_input_bits(k);
|
INPUT_BITS2 inputs = get_key_input_bits(k);
|
||||||
OUTPUT_BITS2 outputs; outputs.Raw = 0ull;
|
OUTPUT_BITS2 outputs;
|
||||||
|
outputs.Raw = 0ull;
|
||||||
for (uint8_t ix = 0; ix < 55; ix++) {
|
for (uint8_t ix = 0; ix < 55; ix++) {
|
||||||
ASSERT(is_ssr_state_stable(&ssr));
|
ASSERT(is_ssr_state_stable(&ssr));
|
||||||
|
|
||||||
|
@ -865,9 +866,10 @@ static void retro_generator_impl(
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// internal function
|
// internal function
|
||||||
ID48LIBX_SUCCESSOR_RESULT id48libx_retro003_successor(const ID48LIBX_STATE_REGISTERS* initial_state, uint8_t input_bit) {
|
ID48LIBX_SUCCESSOR_RESULT id48libx_retro003_successor(const ID48LIBX_STATE_REGISTERS *initial_state, uint8_t input_bit) {
|
||||||
ASSERT(initial_state != nullptr);
|
ASSERT(initial_state != nullptr);
|
||||||
ID48LIBX_SUCCESSOR_RESULT r; memset(&r, 0, sizeof(ID48LIBX_SUCCESSOR_RESULT));
|
ID48LIBX_SUCCESSOR_RESULT r;
|
||||||
|
memset(&r, 0, sizeof(ID48LIBX_SUCCESSOR_RESULT));
|
||||||
ID48LIBX_STATE_REGISTERS s = *initial_state;
|
ID48LIBX_STATE_REGISTERS s = *initial_state;
|
||||||
bool output_bit = calculate_successor_state(&s, !!input_bit);
|
bool output_bit = calculate_successor_state(&s, !!input_bit);
|
||||||
r.state.Raw = s.Raw;
|
r.state.Raw = s.Raw;
|
||||||
|
@ -875,23 +877,23 @@ ID48LIBX_SUCCESSOR_RESULT id48libx_retro003_successor(const ID48LIBX_STATE_REGIS
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
// internal function
|
// internal function
|
||||||
ID48LIBX_STATE_REGISTERS id48libx_retro003_init(const ID48LIB_KEY* key, const ID48LIB_NONCE* nonce) {
|
ID48LIBX_STATE_REGISTERS id48libx_retro003_init(const ID48LIB_KEY *key, const ID48LIB_NONCE *nonce) {
|
||||||
ASSERT(key != nullptr);
|
ASSERT(key != nullptr);
|
||||||
ASSERT(nonce != nullptr);
|
ASSERT(nonce != nullptr);
|
||||||
|
|
||||||
ID48LIBX_STATE_REGISTERS ssr = init_id48libx_state_register(key, nonce);
|
ID48LIBX_STATE_REGISTERS ssr = init_id48libx_state_register(key, nonce);
|
||||||
ID48LIBX_STATE_REGISTERS result; memset(&result, 0, sizeof(ID48LIBX_STATE_REGISTERS));
|
ID48LIBX_STATE_REGISTERS result;
|
||||||
|
memset(&result, 0, sizeof(ID48LIBX_STATE_REGISTERS));
|
||||||
result.Raw = ssr.Raw;
|
result.Raw = ssr.Raw;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public API
|
// public API
|
||||||
void id48lib_generator(
|
void id48lib_generator(
|
||||||
const ID48LIB_KEY* k,
|
const ID48LIB_KEY *k,
|
||||||
const ID48LIB_NONCE* n,
|
const ID48LIB_NONCE *n,
|
||||||
ID48LIB_FRN* frn28_out,
|
ID48LIB_FRN *frn28_out,
|
||||||
ID48LIB_GRN* grn20_out
|
ID48LIB_GRN *grn20_out
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
retro_generator_impl(k, n, frn28_out, grn20_out);
|
retro_generator_impl(k, n, frn28_out, grn20_out);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,8 @@ typedef struct _ID48LIBX_SUCCESSOR_RESULT {
|
||||||
} ID48LIBX_SUCCESSOR_RESULT;
|
} ID48LIBX_SUCCESSOR_RESULT;
|
||||||
|
|
||||||
// the following are used in key recovery but implemented in id48.c
|
// the following are used in key recovery but implemented in id48.c
|
||||||
ID48LIBX_SUCCESSOR_RESULT id48libx_retro003_successor(const ID48LIBX_STATE_REGISTERS* initial_state, uint8_t input_bit);
|
ID48LIBX_SUCCESSOR_RESULT id48libx_retro003_successor(const ID48LIBX_STATE_REGISTERS *initial_state, uint8_t input_bit);
|
||||||
ID48LIBX_STATE_REGISTERS id48libx_retro003_init (const ID48LIB_KEY* key, const ID48LIB_NONCE* nonce);
|
ID48LIBX_STATE_REGISTERS id48libx_retro003_init(const ID48LIB_KEY *key, const ID48LIB_NONCE *nonce);
|
||||||
|
|
||||||
bool id48libx_output_lookup(uint32_t output_index);
|
bool id48libx_output_lookup(uint32_t output_index);
|
||||||
|
|
||||||
|
|
|
@ -116,8 +116,8 @@ typedef struct _RECOVERY_STATE {
|
||||||
} RECOVERY_STATE;
|
} RECOVERY_STATE;
|
||||||
|
|
||||||
// Need equivalent of the following two function pointers:
|
// Need equivalent of the following two function pointers:
|
||||||
typedef ID48LIBX_SUCCESSOR_RESULT (*ID48LIB_SUCCESSOR_FN)(const ID48LIBX_STATE_REGISTERS* initial_state, uint8_t input_bit);
|
typedef ID48LIBX_SUCCESSOR_RESULT(*ID48LIB_SUCCESSOR_FN)(const ID48LIBX_STATE_REGISTERS *initial_state, uint8_t input_bit);
|
||||||
typedef ID48LIBX_STATE_REGISTERS(*ID48LIB_INIT_FN )(const ID48LIB_KEY* key, const ID48LIB_NONCE* nonce);
|
typedef ID48LIBX_STATE_REGISTERS(*ID48LIB_INIT_FN)(const ID48LIB_KEY *key, const ID48LIB_NONCE *nonce);
|
||||||
|
|
||||||
static const ID48LIB_INIT_FN init_fn = id48libx_retro003_init;
|
static const ID48LIB_INIT_FN init_fn = id48libx_retro003_init;
|
||||||
static const ID48LIB_SUCCESSOR_FN successor_fn = id48libx_retro003_successor;
|
static const ID48LIB_SUCCESSOR_FN successor_fn = id48libx_retro003_successor;
|
||||||
|
@ -129,7 +129,7 @@ static const ID48LIB_SUCCESSOR_FN successor_fn = id48libx_retro003_successor;
|
||||||
/// <param name="input_partial_key">Key with K₉₅..K₄₈, in PM3 compatible layout</param>
|
/// <param name="input_partial_key">Key with K₉₅..K₄₈, in PM3 compatible layout</param>
|
||||||
/// <param name="more_bits">0 K₃₃..K₄₇ (to support simple incrementing input)</param>
|
/// <param name="more_bits">0 K₃₃..K₄₇ (to support simple incrementing input)</param>
|
||||||
/// <returns>PM3-formatted key: K₉₅..K₃₃ 0³³</returns>
|
/// <returns>PM3-formatted key: K₉₅..K₃₃ 0³³</returns>
|
||||||
static ID48LIB_KEY create_partial_key56(const ID48LIB_KEY * input_partial_key, uint8_t k47_to_k40) {
|
static ID48LIB_KEY create_partial_key56(const ID48LIB_KEY *input_partial_key, uint8_t k47_to_k40) {
|
||||||
ID48LIB_KEY result;
|
ID48LIB_KEY result;
|
||||||
result.k[ 0] = input_partial_key->k[0]; // k[ 0] :== K₉₅..K₈₈
|
result.k[ 0] = input_partial_key->k[0]; // k[ 0] :== K₉₅..K₈₈
|
||||||
result.k[ 1] = input_partial_key->k[1]; // k[ 1] :== K₈₇..K₈₀
|
result.k[ 1] = input_partial_key->k[1]; // k[ 1] :== K₈₇..K₈₀
|
||||||
|
@ -153,7 +153,7 @@ static ID48LIB_KEY create_partial_key56(const ID48LIB_KEY * input_partial_key, u
|
||||||
/// <param name="input_frn">PM3 compatible input for frn</param>
|
/// <param name="input_frn">PM3 compatible input for frn</param>
|
||||||
/// <param name="input_grn">PM3 compatible input for grn</param>
|
/// <param name="input_grn">PM3 compatible input for grn</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
static EXPECTED_OUTPUT_BITS create_expected_output_bits(const ID48LIB_FRN* input_frn, const ID48LIB_GRN* input_grn) {
|
static EXPECTED_OUTPUT_BITS create_expected_output_bits(const ID48LIB_FRN *input_frn, const ID48LIB_GRN *input_grn) {
|
||||||
// inputs:
|
// inputs:
|
||||||
// frn[ 0] :== O₀₀..O₀₇
|
// frn[ 0] :== O₀₀..O₀₇
|
||||||
// frn[ 1] :== O₀₈..O₁₅
|
// frn[ 1] :== O₀₈..O₁₅
|
||||||
|
@ -162,15 +162,23 @@ static EXPECTED_OUTPUT_BITS create_expected_output_bits(const ID48LIB_FRN* input
|
||||||
// grn[ 0] :== O₂₈ .. O₃₅
|
// grn[ 0] :== O₂₈ .. O₃₅
|
||||||
// grn[ 1] :== O₃₆ .. O₄₃
|
// grn[ 1] :== O₃₆ .. O₄₃
|
||||||
// grn[ 2] :== O₄₄..O₄₇ 0000
|
// grn[ 2] :== O₄₄..O₄₇ 0000
|
||||||
EXPECTED_OUTPUT_BITS result; result.Raw = 0u;
|
EXPECTED_OUTPUT_BITS result;
|
||||||
result.Raw <<= 4; result.Raw |= reverse_bits_08(input_grn->grn[2] & 0xF0u); // adds grn₁₉..grn₁₆ aka O₄₇..O₄₄
|
result.Raw = 0u;
|
||||||
result.Raw <<= 8; result.Raw |= reverse_bits_08(input_grn->grn[1] & 0xFFu); // adds grn₁₅..grn₀₈ aka O₄₃..O₃₆
|
result.Raw <<= 4;
|
||||||
result.Raw <<= 8; result.Raw |= reverse_bits_08(input_grn->grn[0] & 0xFFu); // adds grn₀₇..grn₀₀ aka O₃₅..O₂₈
|
result.Raw |= reverse_bits_08(input_grn->grn[2] & 0xF0u); // adds grn₁₉..grn₁₆ aka O₄₇..O₄₄
|
||||||
|
result.Raw <<= 8;
|
||||||
|
result.Raw |= reverse_bits_08(input_grn->grn[1] & 0xFFu); // adds grn₁₅..grn₀₈ aka O₄₃..O₃₆
|
||||||
|
result.Raw <<= 8;
|
||||||
|
result.Raw |= reverse_bits_08(input_grn->grn[0] & 0xFFu); // adds grn₀₇..grn₀₀ aka O₃₅..O₂₈
|
||||||
|
|
||||||
result.Raw <<= 4; result.Raw |= reverse_bits_08(input_frn->frn[3] & 0xF0u); // adds frn₂₇..frn₂₄ aka O₂₇..O₂₄
|
result.Raw <<= 4;
|
||||||
result.Raw <<= 8; result.Raw |= reverse_bits_08(input_frn->frn[2] & 0xFFu); // adds frn₂₃..frn₁₆ aka O₂₃..O₁₆
|
result.Raw |= reverse_bits_08(input_frn->frn[3] & 0xF0u); // adds frn₂₇..frn₂₄ aka O₂₇..O₂₄
|
||||||
result.Raw <<= 8; result.Raw |= reverse_bits_08(input_frn->frn[1] & 0xFFu); // adds frn₁₅..frn₀₈ aka O₁₅..O₀₈
|
result.Raw <<= 8;
|
||||||
result.Raw <<= 8; result.Raw |= reverse_bits_08(input_frn->frn[0] & 0xFFu); // adds frn₀₇..frn₀₀ aka O₀₇..O₀₀
|
result.Raw |= reverse_bits_08(input_frn->frn[2] & 0xFFu); // adds frn₂₃..frn₁₆ aka O₂₃..O₁₆
|
||||||
|
result.Raw <<= 8;
|
||||||
|
result.Raw |= reverse_bits_08(input_frn->frn[1] & 0xFFu); // adds frn₁₅..frn₀₈ aka O₁₅..O₀₈
|
||||||
|
result.Raw <<= 8;
|
||||||
|
result.Raw |= reverse_bits_08(input_frn->frn[0] & 0xFFu); // adds frn₀₇..frn₀₀ aka O₀₇..O₀₀
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -180,7 +188,7 @@ static EXPECTED_OUTPUT_BITS create_expected_output_bits(const ID48LIB_FRN* input
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="recovery_state">A value in the range [0,55]</param>
|
/// <param name="recovery_state">A value in the range [0,55]</param>
|
||||||
/// <returns>Zero or non-zero (boolean) corresponding to the expected output.</returns>
|
/// <returns>Zero or non-zero (boolean) corresponding to the expected output.</returns>
|
||||||
static bool get_expected_output_bit(const RECOVERY_STATE* recovery_state, uint8_t current_state_index) {
|
static bool get_expected_output_bit(const RECOVERY_STATE *recovery_state, uint8_t current_state_index) {
|
||||||
ASSERT(recovery_state != nullptr);
|
ASSERT(recovery_state != nullptr);
|
||||||
ASSERT(current_state_index >= 7);
|
ASSERT(current_state_index >= 7);
|
||||||
ASSERT(current_state_index <= 55);
|
ASSERT(current_state_index <= 55);
|
||||||
|
@ -188,7 +196,7 @@ static bool get_expected_output_bit(const RECOVERY_STATE* recovery_state, uint8_
|
||||||
return !!(shifted & 0x1u); // return the single bit result
|
return !!(shifted & 0x1u); // return the single bit result
|
||||||
}
|
}
|
||||||
|
|
||||||
static void restart_and_calculate_s00(RECOVERY_STATE* s, const KEY_BITS_K47_TO_K00* k_low) {
|
static void restart_and_calculate_s00(RECOVERY_STATE *s, const KEY_BITS_K47_TO_K00 *k_low) {
|
||||||
ASSERT(s != nullptr);
|
ASSERT(s != nullptr);
|
||||||
ASSERT(k_low != nullptr);
|
ASSERT(k_low != nullptr);
|
||||||
memset(&(s->states[0]), 0xAA, sizeof(ID48LIBX_STATE_REGISTERS) * MAXIMUM_STATE_HISTORY);
|
memset(&(s->states[0]), 0xAA, sizeof(ID48LIBX_STATE_REGISTERS) * MAXIMUM_STATE_HISTORY);
|
||||||
|
@ -197,11 +205,11 @@ static void restart_and_calculate_s00(RECOVERY_STATE* s, const KEY_BITS_K47_TO_K
|
||||||
s->states[0] = init_fn(&start_56b_key, &(s->known_nonce));
|
s->states[0] = init_fn(&start_56b_key, &(s->known_nonce));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool validate_output_from_additional_fifteen_zero_bits(RECOVERY_STATE* s) {
|
static bool validate_output_from_additional_fifteen_zero_bits(RECOVERY_STATE *s) {
|
||||||
bool all_still_match = true;
|
bool all_still_match = true;
|
||||||
for (uint8_t i = 0; all_still_match && i < 15; i++) {
|
for (uint8_t i = 0; all_still_match && i < 15; i++) {
|
||||||
const uint8_t src_idx = 40 + i;
|
const uint8_t src_idx = 40 + i;
|
||||||
const ID48LIBX_STATE_REGISTERS* state = &(s->states[src_idx]);
|
const ID48LIBX_STATE_REGISTERS *state = &(s->states[src_idx]);
|
||||||
ID48LIBX_SUCCESSOR_RESULT r = successor_fn(state, 0);
|
ID48LIBX_SUCCESSOR_RESULT r = successor_fn(state, 0);
|
||||||
bool expected_result = get_expected_output_bit(s, src_idx);
|
bool expected_result = get_expected_output_bit(s, src_idx);
|
||||||
if (expected_result != (!!r.output)) {
|
if (expected_result != (!!r.output)) {
|
||||||
|
@ -220,12 +228,11 @@ static bool validate_output_from_additional_fifteen_zero_bits(RECOVERY_STATE* s)
|
||||||
RECOVERY_STATE g_S = { 0 };
|
RECOVERY_STATE g_S = { 0 };
|
||||||
|
|
||||||
static void init(
|
static void init(
|
||||||
const ID48LIB_KEY * input_partial_key,
|
const ID48LIB_KEY *input_partial_key,
|
||||||
const ID48LIB_NONCE * input_nonce,
|
const ID48LIB_NONCE *input_nonce,
|
||||||
const ID48LIB_FRN * input_frn,
|
const ID48LIB_FRN *input_frn,
|
||||||
const ID48LIB_GRN * input_grn
|
const ID48LIB_GRN *input_grn
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
memset(&g_S, 0, sizeof(RECOVERY_STATE));
|
memset(&g_S, 0, sizeof(RECOVERY_STATE));
|
||||||
memset(&(g_S.states[0]), 0xAA, sizeof(ID48LIBX_STATE_REGISTERS) * MAXIMUM_STATE_HISTORY);
|
memset(&(g_S.states[0]), 0xAA, sizeof(ID48LIBX_STATE_REGISTERS) * MAXIMUM_STATE_HISTORY);
|
||||||
g_S.known_k95_to_k48.k[0] = input_partial_key->k[0];
|
g_S.known_k95_to_k48.k[0] = input_partial_key->k[0];
|
||||||
|
@ -240,7 +247,7 @@ static void init(
|
||||||
g_S.is_fresh_initialization = true;
|
g_S.is_fresh_initialization = true;
|
||||||
}
|
}
|
||||||
static bool get_next_potential_key(
|
static bool get_next_potential_key(
|
||||||
ID48LIB_KEY* potential_key_output
|
ID48LIB_KEY *potential_key_output
|
||||||
) {
|
) {
|
||||||
memset(potential_key_output, 0, sizeof(ID48LIB_KEY));
|
memset(potential_key_output, 0, sizeof(ID48LIB_KEY));
|
||||||
|
|
||||||
|
@ -271,8 +278,7 @@ static bool get_next_potential_key(
|
||||||
g_S.is_fresh_initialization = false;
|
g_S.is_fresh_initialization = false;
|
||||||
k_low.Raw = 0ull;
|
k_low.Raw = 0ull;
|
||||||
current_key_bit_shift = 47;
|
current_key_bit_shift = 47;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// by definition, a returned potential key had all the bits defined
|
// by definition, a returned potential key had all the bits defined
|
||||||
current_key_bit_shift = 0;
|
current_key_bit_shift = 0;
|
||||||
k_low = g_S.last_returned_potential_key;
|
k_low = g_S.last_returned_potential_key;
|
||||||
|
@ -417,16 +423,15 @@ static bool get_next_potential_key(
|
||||||
|
|
||||||
|
|
||||||
void id48lib_key_recovery_init(
|
void id48lib_key_recovery_init(
|
||||||
const ID48LIB_KEY * input_partial_key,
|
const ID48LIB_KEY *input_partial_key,
|
||||||
const ID48LIB_NONCE * input_nonce,
|
const ID48LIB_NONCE *input_nonce,
|
||||||
const ID48LIB_FRN * input_frn,
|
const ID48LIB_FRN *input_frn,
|
||||||
const ID48LIB_GRN * input_grn
|
const ID48LIB_GRN *input_grn
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
init(input_partial_key, input_nonce, input_frn, input_grn);
|
init(input_partial_key, input_nonce, input_frn, input_grn);
|
||||||
}
|
}
|
||||||
bool id48lib_key_recovery_next(
|
bool id48lib_key_recovery_next(
|
||||||
ID48LIB_KEY* potential_key_output
|
ID48LIB_KEY *potential_key_output
|
||||||
) {
|
) {
|
||||||
return get_next_potential_key(potential_key_output);
|
return get_next_potential_key(potential_key_output);
|
||||||
}
|
}
|
||||||
|
|
|
@ -740,7 +740,7 @@ static int mfc_read_tag(iso14a_card_select_t *card, uint8_t *carddata, uint8_t n
|
||||||
memcpy(carddata + (MFBLOCK_SIZE * (mfFirstBlockOfSector(sectorNo) + blockNo)), data, MFBLOCK_SIZE);
|
memcpy(carddata + (MFBLOCK_SIZE * (mfFirstBlockOfSector(sectorNo) + blockNo)), data, MFBLOCK_SIZE);
|
||||||
PrintAndLogEx(INPLACE, "Sector... " _YELLOW_("%2d") " block..." _YELLOW_("%2d") " ( " _GREEN_("ok") " )", sectorNo, blockNo);
|
PrintAndLogEx(INPLACE, "Sector... " _YELLOW_("%2d") " block..." _YELLOW_("%2d") " ( " _GREEN_("ok") " )", sectorNo, blockNo);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(FAILED, "\nSector... %2d Block... %2d ( " _RED_("fail") " )" , sectorNo, blockNo);
|
PrintAndLogEx(FAILED, "\nSector... %2d Block... %2d ( " _RED_("fail") " )", sectorNo, blockNo);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Timeout reading sector... %2d block... %2d", sectorNo, blockNo);
|
PrintAndLogEx(WARNING, "Timeout reading sector... %2d block... %2d", sectorNo, blockNo);
|
||||||
|
|
|
@ -423,6 +423,7 @@ const static vocabulary_t vocabulary[] = {
|
||||||
{ 0, "hf mfu restore" },
|
{ 0, "hf mfu restore" },
|
||||||
{ 0, "hf mfu tamper" },
|
{ 0, "hf mfu tamper" },
|
||||||
{ 1, "hf mfu view" },
|
{ 1, "hf mfu view" },
|
||||||
|
{ 0, "hf mfu wipe" },
|
||||||
{ 0, "hf mfu wrbl" },
|
{ 0, "hf mfu wrbl" },
|
||||||
{ 0, "hf mfu eload" },
|
{ 0, "hf mfu eload" },
|
||||||
{ 0, "hf mfu esave" },
|
{ 0, "hf mfu esave" },
|
||||||
|
@ -512,6 +513,8 @@ const static vocabulary_t vocabulary[] = {
|
||||||
{ 1, "hf vas help" },
|
{ 1, "hf vas help" },
|
||||||
{ 0, "hf vas reader" },
|
{ 0, "hf vas reader" },
|
||||||
{ 1, "hf vas decrypt" },
|
{ 1, "hf vas decrypt" },
|
||||||
|
{ 1, "hf waveshare help" },
|
||||||
|
{ 1, "hf waveshare load" },
|
||||||
{ 1, "hf xerox help" },
|
{ 1, "hf xerox help" },
|
||||||
{ 1, "hf xerox list" },
|
{ 1, "hf xerox list" },
|
||||||
{ 0, "hf xerox info" },
|
{ 0, "hf xerox info" },
|
||||||
|
|
|
@ -3061,7 +3061,7 @@
|
||||||
},
|
},
|
||||||
"hf help": {
|
"hf help": {
|
||||||
"command": "hf help",
|
"command": "hf help",
|
||||||
"description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } fudan { Fudan RFIDs... } gallagher { Gallagher DESFire RFIDs... } iclass { ICLASS RFIDs... } ict { ICT MFC/DESfire RFIDs... } jooki { Jooki RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } tesla { TESLA Cards... } texkom { Texkom RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } vas { Apple Value Added Service } xerox { Fuji/Xerox cartridge RFIDs... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags --------------------------------------------------------------------------------------- hf list available offline: yes Alias of `trace list -t raw` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol",
|
"description": "-------- ----------------------- High Frequency ----------------------- 14a { ISO14443A RFIDs... } 14b { ISO14443B RFIDs... } 15 { ISO15693 RFIDs... } cipurse { Cipurse transport Cards... } epa { German Identification Card... } emrtd { Machine Readable Travel Document... } felica { ISO18092 / FeliCa RFIDs... } fido { FIDO and FIDO2 authenticators... } fudan { Fudan RFIDs... } gallagher { Gallagher DESFire RFIDs... } iclass { ICLASS RFIDs... } ict { ICT MFC/DESfire RFIDs... } jooki { Jooki RFIDs... } ksx6924 { KS X 6924 (T-Money, Snapper+) RFIDs } legic { LEGIC RFIDs... } lto { LTO Cartridge Memory RFIDs... } mf { MIFARE RFIDs... } mfp { MIFARE Plus RFIDs... } mfu { MIFARE Ultralight RFIDs... } mfdes { MIFARE Desfire RFIDs... } ntag424 { NXP NTAG 4242 DNA RFIDs... } seos { SEOS RFIDs... } st25ta { ST25TA RFIDs... } tesla { TESLA Cards... } texkom { Texkom RFIDs... } thinfilm { Thinfilm RFIDs... } topaz { TOPAZ (NFC Type 1) RFIDs... } vas { Apple Value Added Service } waveshare { Waveshare NFC ePaper... } xerox { Fuji/Xerox cartridge RFIDs... } ----------- --------------------- General --------------------- help This help list List protocol data in trace buffer search Search for known HF tags --------------------------------------------------------------------------------------- hf list available offline: yes Alias of `trace list -t raw` with selected protocol data to annotate trace buffer You can load a trace from file (see `trace load -h`) or it be downloaded from device by default It accepts all other arguments of `trace list`. Note that some might not be relevant for this specific protocol",
|
||||||
"notes": [
|
"notes": [
|
||||||
"hf list --frame -> show frame delay times",
|
"hf list --frame -> show frame delay times",
|
||||||
"hf list -1 -> use trace buffer"
|
"hf list -1 -> use trace buffer"
|
||||||
|
@ -7084,6 +7084,20 @@
|
||||||
],
|
],
|
||||||
"usage": "hf mfu view [-hvz] -f <fn>"
|
"usage": "hf mfu view [-hvz] -f <fn>"
|
||||||
},
|
},
|
||||||
|
"hf mfu wipe": {
|
||||||
|
"command": "hf mfu wipe",
|
||||||
|
"description": "Wipe card to zeros. It will ignore block0,1,2,3 you will need to call it with password in order to wipe the config and sett default pwd/pack Abort by pressing a key New password... FFFFFFFF",
|
||||||
|
"notes": [
|
||||||
|
"hf mfu wipe"
|
||||||
|
],
|
||||||
|
"offline": false,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"-k, --key <hex> Key for authentication (UL-C 16 bytes, EV1/NTAG 4 bytes)",
|
||||||
|
"-l Swap entered key's endianness"
|
||||||
|
],
|
||||||
|
"usage": "hf mfu wipe [-hl] [-k <hex>]"
|
||||||
|
},
|
||||||
"hf mfu wrbl": {
|
"hf mfu wrbl": {
|
||||||
"command": "hf mfu wrbl",
|
"command": "hf mfu wrbl",
|
||||||
"description": "Write a block. It autodetects card type.",
|
"description": "Write a block. It autodetects card type.",
|
||||||
|
@ -7722,6 +7736,28 @@
|
||||||
],
|
],
|
||||||
"usage": "hf vas reader [-h@v] [--pid <str>] [-f <fn>] [--url <str>]"
|
"usage": "hf vas reader [-h@v] [--pid <str>] [-f <fn>] [--url <str>]"
|
||||||
},
|
},
|
||||||
|
"hf waveshare help": {
|
||||||
|
"command": "hf waveshare help",
|
||||||
|
"description": "help This help load Load image file to Waveshare NFC ePaper --------------------------------------------------------------------------------------- hf waveshare load available offline: yes Load image file to Waveshare NFC ePaper",
|
||||||
|
"notes": [
|
||||||
|
"hf waveshare load -f myfile -m 0 -> 2.13 inch e-paper ( 122, 250 )",
|
||||||
|
"hf waveshare load -f myfile -m 1 -> 2.9 inch e-paper ( 296, 128 )",
|
||||||
|
"hf waveshare load -f myfile -m 2 -> 4.2 inch e-paper ( 400, 300 )",
|
||||||
|
"hf waveshare load -f myfile -m 3 -> 7.5 inch e-paper ( 800, 480 )",
|
||||||
|
"hf waveshare load -f myfile -m 4 -> 2.7 inch e-paper ( 176, 276 )",
|
||||||
|
"hf waveshare load -f myfile -m 5 -> 2.13 inch e-paper B (with red) ( 104, 212 )",
|
||||||
|
"hf waveshare load -f myfile -m 6 -> 1.54 inch e-paper B (with red) ( 200, 200 )",
|
||||||
|
"hf waveshare load -f myfile -m 7 -> 7.5 inch e-paper HD ( 880, 528 )"
|
||||||
|
],
|
||||||
|
"offline": true,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"-m <nr> model number [0 - 7] of your tag",
|
||||||
|
"-f, --file <fn> specify image to upload to tag",
|
||||||
|
"-s, --save <fn> save paletized version in file"
|
||||||
|
],
|
||||||
|
"usage": "hf waveshare load [-h] -m <nr> -f <fn> [-s <fn>]"
|
||||||
|
},
|
||||||
"hf xerox dump": {
|
"hf xerox dump": {
|
||||||
"command": "hf xerox dump",
|
"command": "hf xerox dump",
|
||||||
"description": "Dump all memory from a Fuji/Xerox tag ISO/IEC 14443 type B based communications",
|
"description": "Dump all memory from a Fuji/Xerox tag ISO/IEC 14443 type B based communications",
|
||||||
|
@ -8039,9 +8075,10 @@
|
||||||
"offline": false,
|
"offline": false,
|
||||||
"options": [
|
"options": [
|
||||||
"-h, --help This help",
|
"-h, --help This help",
|
||||||
"-a, --arg <dec> argument byte"
|
"-a, --arg <dec> argument byte",
|
||||||
|
"-b <str> UniSniff arg: 14a, 14b, 15, iclass"
|
||||||
],
|
],
|
||||||
"usage": "hw standalone [-h] [-a <dec>]"
|
"usage": "hw standalone [-h] [-a <dec>] [-b <str>]"
|
||||||
},
|
},
|
||||||
"hw status": {
|
"hw status": {
|
||||||
"command": "hw status",
|
"command": "hw status",
|
||||||
|
@ -8889,7 +8926,7 @@
|
||||||
},
|
},
|
||||||
"lf em 4x70 help": {
|
"lf em 4x70 help": {
|
||||||
"command": "lf em 4x70 help",
|
"command": "lf em 4x70 help",
|
||||||
"description": "help This help --------------------------------------------------------------------------------------- lf em 4x70 brute available offline: no Optimized partial key-update attack of 16-bit key block 7, 8 or 9 of an EM4x70 This attack does NOT write anything to the tag. Before starting this attack, 0000 must be written to the 16-bit key block: 'lf em 4x70 write -b 9 -d 0000'. After success, the 16-bit key block have to be restored with the key found: 'lf em 4x70 write -b 9 -d c0de'",
|
"description": "help This help recover Recover remaining key from partial key --------------------------------------------------------------------------------------- lf em 4x70 brute available offline: no Optimized partial key-update attack of 16-bit key block 7, 8 or 9 of an EM4x70 This attack does NOT write anything to the tag. Before starting this attack, 0000 must be written to the 16-bit key block: 'lf em 4x70 write -b 9 -d 0000'. After success, the 16-bit key block have to be restored with the key found: 'lf em 4x70 write -b 9 -d c0de'",
|
||||||
"notes": [
|
"notes": [
|
||||||
"lf em 4x70 brute -b 9 --rnd 45F54ADA252AAC --frn 4866BB70 -> bruteforcing key bits k95...k80"
|
"lf em 4x70 brute -b 9 --rnd 45F54ADA252AAC --frn 4866BB70 -> bruteforcing key bits k95...k80"
|
||||||
],
|
],
|
||||||
|
@ -8925,7 +8962,7 @@
|
||||||
"lf em 4x70 recover --key F32AA98CF5BE --rnd 45F54ADA252AAC --frn 4866BB70 --grn 9BD180 (pm3 test key)",
|
"lf em 4x70 recover --key F32AA98CF5BE --rnd 45F54ADA252AAC --frn 4866BB70 --grn 9BD180 (pm3 test key)",
|
||||||
"lf em 4x70 recover --key A090A0A02080 --rnd 3FFE1FB6CC513F --frn F355F1A0 --grn 609D60 (research paper key)"
|
"lf em 4x70 recover --key A090A0A02080 --rnd 3FFE1FB6CC513F --frn F355F1A0 --grn 609D60 (research paper key)"
|
||||||
],
|
],
|
||||||
"offline": false,
|
"offline": true,
|
||||||
"options": [
|
"options": [
|
||||||
"-h, --help This help",
|
"-h, --help This help",
|
||||||
"--par Add parity bit when sending commands",
|
"--par Add parity bit when sending commands",
|
||||||
|
@ -8936,6 +8973,36 @@
|
||||||
],
|
],
|
||||||
"usage": "lf em 4x70 recover [-h] [--par] -k <hex> --rnd <hex> --frn <hex> --grn <hex>"
|
"usage": "lf em 4x70 recover [-h] [--par] -k <hex> --rnd <hex> --frn <hex> --grn <hex>"
|
||||||
},
|
},
|
||||||
|
"lf em 4x70 setkey": {
|
||||||
|
"command": "lf em 4x70 setkey",
|
||||||
|
"description": "Write new 96-bit key to tag",
|
||||||
|
"notes": [
|
||||||
|
"lf em 4x70 setkey -k F32AA98CF5BE4ADFA6D3480B (pm3 test key)",
|
||||||
|
"lf em 4x70 setkey -k A090A0A02080000000000000 (research paper key)"
|
||||||
|
],
|
||||||
|
"offline": false,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"--par Add parity bit when sending commands",
|
||||||
|
"-k, --key <hex> Key as 12 hex bytes"
|
||||||
|
],
|
||||||
|
"usage": "lf em 4x70 setkey [-h] [--par] -k <hex>"
|
||||||
|
},
|
||||||
|
"lf em 4x70 setpin": {
|
||||||
|
"command": "lf em 4x70 setpin",
|
||||||
|
"description": "Write new PIN",
|
||||||
|
"notes": [
|
||||||
|
"lf em 4x70 setpin -p 11223344 -> Write new PIN",
|
||||||
|
"lf em 4x70 setpin -p 11223344 --par -> Write new PIN using parity commands"
|
||||||
|
],
|
||||||
|
"offline": false,
|
||||||
|
"options": [
|
||||||
|
"-h, --help This help",
|
||||||
|
"--par Add parity bit when sending commands",
|
||||||
|
"-p, --pin <hex> pin, 4 bytes"
|
||||||
|
],
|
||||||
|
"usage": "lf em 4x70 setpin [-h] [--par] -p <hex>"
|
||||||
|
},
|
||||||
"lf em 4x70 unlock": {
|
"lf em 4x70 unlock": {
|
||||||
"command": "lf em 4x70 unlock",
|
"command": "lf em 4x70 unlock",
|
||||||
"description": "Unlock EM4x70 by sending PIN Default pin may be: AAAAAAAA 00000000",
|
"description": "Unlock EM4x70 by sending PIN Default pin may be: AAAAAAAA 00000000",
|
||||||
|
@ -8967,36 +9034,6 @@
|
||||||
],
|
],
|
||||||
"usage": "lf em 4x70 write [-h] [--par] -b <dec> -d <hex>"
|
"usage": "lf em 4x70 write [-h] [--par] -b <dec> -d <hex>"
|
||||||
},
|
},
|
||||||
"lf em 4x70 setkey": {
|
|
||||||
"command": "lf em 4x70 setkey",
|
|
||||||
"description": "Write new 96-bit key to tag",
|
|
||||||
"notes": [
|
|
||||||
"lf em 4x70 setkey -k F32AA98CF5BE4ADFA6D3480B (pm3 test key)",
|
|
||||||
"lf em 4x70 setkey -k A090A0A02080000000000000 (research paper key)"
|
|
||||||
],
|
|
||||||
"offline": false,
|
|
||||||
"options": [
|
|
||||||
"-h, --help This help",
|
|
||||||
"--par Add parity bit when sending commands",
|
|
||||||
"-k, --key <hex> Key as 12 hex bytes"
|
|
||||||
],
|
|
||||||
"usage": "lf em 4x70 setkey [-h] [--par] -k <hex>"
|
|
||||||
},
|
|
||||||
"lf em 4x70 setpin": {
|
|
||||||
"command": "lf em 4x70 setpin",
|
|
||||||
"description": "Write PIN",
|
|
||||||
"notes": [
|
|
||||||
"lf em 4x70 setpin -p 11223344 -> Write new PIN",
|
|
||||||
"lf em 4x70 setpin -p 11223344 --par -> Write new PIN using parity commands"
|
|
||||||
],
|
|
||||||
"offline": false,
|
|
||||||
"options": [
|
|
||||||
"-h, --help This help",
|
|
||||||
"--par Add parity bit when sending commands",
|
|
||||||
"-p, --pin <hex> pin, 4 bytes"
|
|
||||||
],
|
|
||||||
"usage": "lf em 4x70 setpin [-h] [--par] -p <hex>"
|
|
||||||
},
|
|
||||||
"lf em help": {
|
"lf em help": {
|
||||||
"command": "lf em help",
|
"command": "lf em help",
|
||||||
"description": "help This help 410x { EM 4102 commands... } 4x05 { EM 4205 / 4305 / 4369 / 4469 commands... } 4x50 { EM 4350 / 4450 commands... } 4x70 { EM 4070 / 4170 commands... } ======================================================================================= lf em 410x { EM 4102 commands... } --------------------------------------------------------------------------------------- lf em 410x help available offline: yes help This help demod demodulate a EM410x tag from the GraphBuffer --------------------------------------------------------------------------------------- lf em 410x demod available offline: yes Try to find EM 410x preamble, if found decode / descramble data",
|
"description": "help This help 410x { EM 4102 commands... } 4x05 { EM 4205 / 4305 / 4369 / 4469 commands... } 4x50 { EM 4350 / 4450 commands... } 4x70 { EM 4070 / 4170 commands... } ======================================================================================= lf em 410x { EM 4102 commands... } --------------------------------------------------------------------------------------- lf em 410x help available offline: yes help This help demod demodulate a EM410x tag from the GraphBuffer --------------------------------------------------------------------------------------- lf em 410x demod available offline: yes Try to find EM 410x preamble, if found decode / descramble data",
|
||||||
|
@ -12529,8 +12566,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"commands_extracted": 723,
|
"commands_extracted": 725,
|
||||||
"extracted_by": "PM3Help2JSON v1.00",
|
"extracted_by": "PM3Help2JSON v1.00",
|
||||||
"extracted_on": "2024-03-12T00:21:47"
|
"extracted_on": "2024-03-14T10:14:29"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -610,6 +610,7 @@ Check column "offline" for their availability.
|
||||||
|`hf mfu restore `|N |`Restore a dump file onto a tag`
|
|`hf mfu restore `|N |`Restore a dump file onto a tag`
|
||||||
|`hf mfu tamper `|N |`NTAG 213TT - Configure the tamper feature`
|
|`hf mfu tamper `|N |`NTAG 213TT - Configure the tamper feature`
|
||||||
|`hf mfu view `|Y |`Display content from tag dump file`
|
|`hf mfu view `|Y |`Display content from tag dump file`
|
||||||
|
|`hf mfu wipe `|N |`Wipe card to zeros and default key`
|
||||||
|`hf mfu wrbl `|N |`Write block`
|
|`hf mfu wrbl `|N |`Write block`
|
||||||
|`hf mfu eload `|N |`Upload file into emulator memory`
|
|`hf mfu eload `|N |`Upload file into emulator memory`
|
||||||
|`hf mfu esave `|N |`Save emulator memory to file`
|
|`hf mfu esave `|N |`Save emulator memory to file`
|
||||||
|
@ -773,6 +774,16 @@ Check column "offline" for their availability.
|
||||||
|`hf vas decrypt `|Y |`Decrypt a previously captured VAS cryptogram`
|
|`hf vas decrypt `|Y |`Decrypt a previously captured VAS cryptogram`
|
||||||
|
|
||||||
|
|
||||||
|
### hf waveshare
|
||||||
|
|
||||||
|
{ Waveshare NFC ePaper... }
|
||||||
|
|
||||||
|
|command |offline |description
|
||||||
|
|------- |------- |-----------
|
||||||
|
|`hf waveshare help `|Y |`This help`
|
||||||
|
|`hf waveshare load `|Y |`Load image file to Waveshare NFC ePaper`
|
||||||
|
|
||||||
|
|
||||||
### hf xerox
|
### hf xerox
|
||||||
|
|
||||||
{ Fuji/Xerox cartridge RFIDs... }
|
{ Fuji/Xerox cartridge RFIDs... }
|
||||||
|
@ -960,8 +971,8 @@ Check column "offline" for their availability.
|
||||||
|`lf em 4x70 write `|N |`Write EM4x70`
|
|`lf em 4x70 write `|N |`Write EM4x70`
|
||||||
|`lf em 4x70 unlock `|N |`Unlock EM4x70 for writing`
|
|`lf em 4x70 unlock `|N |`Unlock EM4x70 for writing`
|
||||||
|`lf em 4x70 auth `|N |`Authenticate EM4x70`
|
|`lf em 4x70 auth `|N |`Authenticate EM4x70`
|
||||||
|`lf em 4x70 setpin `|N |`Write new PIN`
|
|`lf em 4x70 setpin `|N |`Write PIN`
|
||||||
|`lf em 4x70 setkey `|N |`Write new key`
|
|`lf em 4x70 setkey `|N |`Write key`
|
||||||
|`lf em 4x70 recover `|Y |`Recover remaining key from partial key`
|
|`lf em 4x70 recover `|Y |`Recover remaining key from partial key`
|
||||||
|`lf em 4x70 autorecover `|N |`Recover entire key from writable tag`
|
|`lf em 4x70 autorecover `|N |`Recover entire key from writable tag`
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue