mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
style
This commit is contained in:
parent
08cd7315e4
commit
94c3bdd91c
17 changed files with 355 additions and 297 deletions
|
@ -60,14 +60,14 @@
|
|||
* which protocol to sniff. If you choose a protocol it will go directly
|
||||
* to work. If you choose 'user' you may select the protocol at the start
|
||||
* of each session.
|
||||
*
|
||||
* hf_unisniff.conf sample file:
|
||||
*
|
||||
* hf_unisniff.conf sample file:
|
||||
* save=new
|
||||
* protocol=14a
|
||||
*
|
||||
* Upload it to the Proxmark3 spiffs.
|
||||
* mem spiffs upload -s hf_unisniff.conf -d hf_unisniff.conf
|
||||
*
|
||||
*
|
||||
* To use the mode:
|
||||
* Start mode by pressing the Proxmark3 button for 3 seconds. See ledshow as indicator its in standalone mode.
|
||||
* present proxmark3 and card to the reader.
|
||||
|
@ -159,7 +159,7 @@ void ModInfo(void) {
|
|||
DbpString(" HF UNISNIFF - multimode HF sniffer (hazardousvoltage)");
|
||||
Dbprintf(" Compile-time default protocol... %s", HF_UNISNIFF_PROTOCOL);
|
||||
#ifdef WITH_FLASH
|
||||
DbpString(" FLASH support................... yes");
|
||||
DbpString(" FLASH support................... yes");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -169,17 +169,17 @@ void RunMod(void) {
|
|||
|
||||
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
|
||||
const char *bb = (const char*)BigBuf_get_EM_addr();
|
||||
const char *bb = (const char *)BigBuf_get_EM_addr();
|
||||
uint8_t sniff_protocol;
|
||||
if (strlen(bb) > 0 ) {
|
||||
if (strlen(bb) > 0) {
|
||||
for (sniff_protocol = 0; sniff_protocol < ARRAYLEN(protocols); sniff_protocol++) {
|
||||
if (strcmp(protocols[sniff_protocol], bb) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (sniff_protocol = 0; sniff_protocol < ARRAYLEN(protocols); sniff_protocol++) {
|
||||
if (strcmp(protocols[sniff_protocol], HF_UNISNIFF_PROTOCOL) == 0) {
|
||||
|
@ -217,10 +217,10 @@ void RunMod(void) {
|
|||
char *d = &config_buffer[0];
|
||||
|
||||
rdv40_spiffs_read_as_filetype(HF_UNISNIFF_CONFIG
|
||||
, (uint8_t *)d
|
||||
, fsize
|
||||
, RDV40_SPIFFS_SAFETY_SAFE
|
||||
);
|
||||
, (uint8_t *)d
|
||||
, fsize
|
||||
, RDV40_SPIFFS_SAFETY_SAFE
|
||||
);
|
||||
|
||||
// This parser is terrible but I think fairly memory efficient? Maybe better to use JSON?
|
||||
char *x = d;
|
||||
|
@ -310,7 +310,7 @@ void RunMod(void) {
|
|||
|
||||
SpinDelay(100);
|
||||
Dbprintf("Selected protocol.... " _YELLOW_("%s"), protocols[sniff_protocol]);
|
||||
}
|
||||
}
|
||||
|
||||
if (button_pressed == BUTTON_HOLD) {
|
||||
Dbprintf("Executing protocol... " _YELLOW_("%s"), protocols[sniff_protocol]);
|
||||
|
@ -384,11 +384,11 @@ void RunMod(void) {
|
|||
}
|
||||
|
||||
sprintf(filename, "%s_%s-%03d%s"
|
||||
, HF_UNISNIFF_LOGFILE
|
||||
, protocols[sniff_protocol]
|
||||
, file_index
|
||||
, HF_UNISNIFF_LOGEXT
|
||||
);
|
||||
, HF_UNISNIFF_LOGFILE
|
||||
, protocols[sniff_protocol]
|
||||
, file_index
|
||||
, HF_UNISNIFF_LOGEXT
|
||||
);
|
||||
}
|
||||
|
||||
if (file_index > 999) {
|
||||
|
@ -397,7 +397,7 @@ void RunMod(void) {
|
|||
rdv40_spiffs_write(filename, trace_buffer, trace_len, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
Dbprintf("Wrote trace to " _YELLOW_("%s"), filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (save_mode == HF_UNISNIFF_SAVE_MODE_APPEND) {
|
||||
|
||||
|
|
|
@ -1150,13 +1150,13 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
|
|||
if ((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK) {
|
||||
|
||||
for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) {
|
||||
if (ar_nr_collected[i + mM] == 0 ||
|
||||
if (ar_nr_collected[i + mM] == 0 ||
|
||||
(
|
||||
(cardAUTHSC == ar_nr_resp[i + mM].sector) &&
|
||||
(cardAUTHKEY == ar_nr_resp[i + mM].keytype) &&
|
||||
(cardAUTHSC == ar_nr_resp[i + mM].sector) &&
|
||||
(cardAUTHKEY == ar_nr_resp[i + mM].keytype) &&
|
||||
(ar_nr_collected[i + mM] > 0)
|
||||
)
|
||||
) {
|
||||
) {
|
||||
// if first auth for sector, or matches sector and keytype of previous auth
|
||||
if (ar_nr_collected[i + mM] < 2) {
|
||||
// if we haven't already collected 2 nonces for this sector
|
||||
|
@ -1361,9 +1361,9 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
|
|||
for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) {
|
||||
if (ar_nr_collected[i] == 2) {
|
||||
Dbprintf("Collected two pairs of AR/NR which can be used to extract sector %d " _YELLOW_("%s")
|
||||
, ar_nr_resp[i].sector
|
||||
, (ar_nr_resp[i].keytype == AUTHKEYA) ? "key A" : "key B"
|
||||
);
|
||||
, ar_nr_resp[i].sector
|
||||
, (ar_nr_resp[i].keytype == AUTHKEYA) ? "key A" : "key B"
|
||||
);
|
||||
Dbprintf("../tools/mfkey/mfkey32 %08x %08x %08x %08x %08x %08x",
|
||||
ar_nr_resp[i].cuid, //UID
|
||||
ar_nr_resp[i].nonce, //NT
|
||||
|
@ -1380,9 +1380,9 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
|
|||
for (uint8_t i = ATTACK_KEY_COUNT; i < ATTACK_KEY_COUNT * 2; i++) {
|
||||
if (ar_nr_collected[i] == 2) {
|
||||
Dbprintf("Collected two pairs of AR/NR which can be used to extract sector %d " _YELLOW_("%s")
|
||||
, ar_nr_resp[i].sector
|
||||
, (ar_nr_resp[i].keytype == AUTHKEYB) ? "key A" : "key B"
|
||||
);
|
||||
, ar_nr_resp[i].sector
|
||||
, (ar_nr_resp[i].keytype == AUTHKEYB) ? "key A" : "key B"
|
||||
);
|
||||
Dbprintf("../tools/mfkey/mfkey32v2 %08x %08x %08x %08x %08x %08x %08x",
|
||||
ar_nr_resp[i].cuid, //UID
|
||||
ar_nr_resp[i].nonce, //NT
|
||||
|
|
|
@ -209,8 +209,8 @@ uint32_t usart_read_ng(uint8_t *data, size_t len) {
|
|||
|
||||
if (try++ == maxtry) {
|
||||
// Dbprintf_usb("Dbg USART TIMEOUT");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// highest_observed_try = MAX(highest_observed_try, try);
|
||||
// Dbprintf_usb("Dbg USART max observed try %i", highest_observed_try);
|
||||
|
|
|
@ -31,13 +31,13 @@
|
|||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#if defined(NDEBUG)
|
||||
#define ASSERT(x) ((void)0)
|
||||
#define ASSERT(x) ((void)0)
|
||||
#elif defined(ID48_NO_STDIO)
|
||||
#define ASSERT(x) ((void)0)
|
||||
#define ASSERT(x) ((void)0)
|
||||
#else // neither NDEBUG nor ID48_NO_STDIO defined
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#define ASSERT(x) assert((x))
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#define ASSERT(x) assert((x))
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -108,7 +108,7 @@ typedef struct _ID48LIB_FRN {
|
|||
/// Native format if viewed linearly from frn[0..6].
|
||||
/// Mapping to the indices used in the research paper,
|
||||
/// where ( O₂₈ .. O₅₅ ) :== output( s₃₅, k₀₄..k₀₀ (15x 0) ) == grn
|
||||
///
|
||||
///
|
||||
/// then:
|
||||
/// rn[ 0] :== O₂₈ .. O₃₅
|
||||
/// rn[ 1] :== O₃₆ .. O₄₃
|
||||
|
@ -128,15 +128,15 @@ typedef struct _ID48LIB_GRN {
|
|||
/// Note: In C++, each parameter would be a reference (not pointer).
|
||||
/// </remarks>
|
||||
void id48lib_generator(
|
||||
const ID48LIB_KEY* key_96bit,
|
||||
const ID48LIB_NONCE* nonce_56bit,
|
||||
ID48LIB_FRN* frn28_out,
|
||||
ID48LIB_GRN* grn20_out
|
||||
);
|
||||
const ID48LIB_KEY *key_96bit,
|
||||
const ID48LIB_NONCE *nonce_56bit,
|
||||
ID48LIB_FRN *frn28_out,
|
||||
ID48LIB_GRN *grn20_out
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes to allow iterative recovery
|
||||
/// of multiple potential keys. After calling
|
||||
/// of multiple potential keys. After calling
|
||||
/// this init() function, can repeatedly call
|
||||
/// the next() function until it returns false
|
||||
/// to obtain all potential keys.
|
||||
|
@ -165,10 +165,10 @@ void id48lib_generator(
|
|||
/// Note: In C++, each parameter would be a reference (not pointer).
|
||||
/// </remarks>
|
||||
void id48lib_key_recovery_init(
|
||||
const ID48LIB_KEY* input_partial_key,
|
||||
const ID48LIB_NONCE* input_nonce,
|
||||
const ID48LIB_FRN* input_frn,
|
||||
const ID48LIB_GRN* input_grn
|
||||
const ID48LIB_KEY *input_partial_key,
|
||||
const ID48LIB_NONCE *input_nonce,
|
||||
const ID48LIB_FRN *input_frn,
|
||||
const ID48LIB_GRN *input_grn
|
||||
);
|
||||
/// <summary>
|
||||
/// This can be repeated called (after calling init())
|
||||
|
@ -184,7 +184,7 @@ void id48lib_key_recovery_init(
|
|||
/// <param name="potential_key_output">
|
||||
/// When the function returns true, this caller-provided
|
||||
/// value will be filled with the 96-bit key that, when
|
||||
/// programmed to the tag, should authenticate against
|
||||
/// programmed to the tag, should authenticate against
|
||||
/// the nonce+frn values, with tag returning the grn value.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
|
@ -195,7 +195,7 @@ void id48lib_key_recovery_init(
|
|||
/// Note: In C++, each parameter would be a reference (not pointer).
|
||||
/// </remarks>
|
||||
bool id48lib_key_recovery_next(
|
||||
ID48LIB_KEY* potential_key_output
|
||||
ID48LIB_KEY *potential_key_output
|
||||
);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
|
|
@ -50,7 +50,7 @@ static const uint8_t small_lut_group4[4] = { // aka 32 bits
|
|||
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 uint8_t mask = 1u << (bit_idx % 8u);
|
||||
return (table_start[byte] & mask) != 0;
|
||||
|
@ -72,7 +72,7 @@ static inline bool get_bit(const uint8_t* table_start, uint32_t bit_idx) {
|
|||
// so long as the lookup tables are adjusted accordingly.
|
||||
//
|
||||
// Which bits are used for which small lookup table indixes?
|
||||
//
|
||||
//
|
||||
// Bit: ₆₃ ₆₂ ₆₁ ₆₀ ₅₉ ₅₈ ₅₇ ₅₆ ₅₅ ₅₄ ₅₃ ₅₂ ₅₁ ₅₀ ₄₉ ₄₈ ₄₇ ₄₆ ₄₅ ₄₄ ₄₃ ₄₂ ₄₁ ₄₀ ₃₉ ₃₈ ₃₇ ₃₆ ₃₅ ₃₄ ₃₃ ₃₂
|
||||
// Reg: i j r₀₆ r₀₅ r₀₄ r₀₃ r₀₂ r₀₁ r₀₀ m₀₆ m₀₅ m₀₄ m₀₃ m₀₂ m₀₁ m₀₀ l₀₆ l₀₅ l₀₄ l₀₃ l₀₂ l₀₁ l₀₀ g₂₂ g₂₁ g₂₀ g₁₉ g₁₈ g₁₇ g₁₆ g₁₅ g₁₄
|
||||
// i_v i_v i_v i_v i_v i_v i_v i_v
|
||||
|
@ -80,8 +80,8 @@ static inline bool get_bit(const uint8_t* table_start, uint32_t bit_idx) {
|
|||
// BBB BBB BBB BBB
|
||||
// CCC CCC CCC CCC
|
||||
// DDD DDD DDD DDD DDD
|
||||
//
|
||||
// Bit: ₃₁ ₃₀ ₂₉ ₂₈ ₂₇ ₂₆ ₂₅ ₂₄ ₂₃ ₂₂ ₂₁ ₂₀ ₁₉ ₁₈ ₁₇ ₁₆ ₁₅ ₁₄ ₁₃ ₁₂ ₁₁ ₁₀ ₀₉ ₀₈ ₀₇ ₀₆ ₀₅ ₀₄ ₀₃ ₀₂ ₀₁ ₀₀
|
||||
//
|
||||
// Bit: ₃₁ ₃₀ ₂₉ ₂₈ ₂₇ ₂₆ ₂₅ ₂₄ ₂₃ ₂₂ ₂₁ ₂₀ ₁₉ ₁₈ ₁₇ ₁₆ ₁₅ ₁₄ ₁₃ ₁₂ ₁₁ ₁₀ ₀₉ ₀₈ ₀₇ ₀₆ ₀₅ ₀₄ ₀₃ ₀₂ ₀₁ ₀₀
|
||||
// Reg: g₁₃ g₁₂ g₁₁ g₁₀ g₀₉ g₀₈ g₀₇ g₀₆ g₀₅ g₀₄ g₀₃ g₀₂ g₀₁ g₀₀ h₁₂ h₁₁ h₁₀ h₀₉ h₀₈ h₀₇ h₀₆ h₀₅ h₀₄ h₀₃ h₀₂ h₀₁ h₀₀ _ a b c 0
|
||||
// AAA BBB CCC
|
||||
//
|
||||
|
@ -105,7 +105,7 @@ static inline bool get_bit(const uint8_t* table_start, uint32_t bit_idx) {
|
|||
|
||||
static bool output_lookup_small_lut(uint32_t output_index) {
|
||||
if (output_index >= COUNT_OF_POTENTIAL_INPUTS) { return false; }
|
||||
// 1 1 1 1 1 1 1 1 1 1
|
||||
// 1 1 1 1 1 1 1 1 1 1
|
||||
// 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
// Fₒ( a b c l₀ l₂ l₃ l₄ l₅ l₆ m₀ m₁ m₃ m₅ r₀ r₁ r₂ r₃ r₄ r₅ r₆ )
|
||||
|
||||
|
|
|
@ -91,8 +91,8 @@ static inline uint64_t reverse_bits_64(uint64_t n) {
|
|||
#pragma region // id48lib state register
|
||||
// Bit: ₆₃ ₆₂ ₆₁ ₆₀ ₅₉ ₅₈ ₅₇ ₅₆ ₅₅ ₅₄ ₅₃ ₅₂ ₅₁ ₅₀ ₄₉ ₄₈ ₄₇ ₄₆ ₄₅ ₄₄ ₄₃ ₄₂ ₄₁ ₄₀ ₃₉ ₃₈ ₃₇ ₃₆ ₃₅ ₃₄ ₃₃ ₃₂
|
||||
// Reg: x x x r₀₆ r₀₅ r₀₄ r₀₃ r₀₂ r₀₁ r₀₀ m₀₆ m₀₅ m₀₄ m₀₃ m₀₂ m₀₁ m₀₀ l₀₆ l₀₅ l₀₄ l₀₃ l₀₂ l₀₁ l₀₀ g₂₂ g₂₁ g₂₀ g₁₉ g₁₈ g₁₇ g₁₆ g₁₅
|
||||
//
|
||||
// Bit: ₃₁ ₃₀ ₂₉ ₂₈ ₂₇ ₂₆ ₂₅ ₂₄ ₂₃ ₂₂ ₂₁ ₂₀ ₁₉ ₁₈ ₁₇ ₁₆ ₁₅ ₁₄ ₁₃ ₁₂ ₁₁ ₁₀ ₀₉ ₀₈ ₀₇ ₀₆ ₀₅ ₀₄ ₀₃ ₀₂ ₀₁ ₀₀
|
||||
//
|
||||
// Bit: ₃₁ ₃₀ ₂₉ ₂₈ ₂₇ ₂₆ ₂₅ ₂₄ ₂₃ ₂₂ ₂₁ ₂₀ ₁₉ ₁₈ ₁₇ ₁₆ ₁₅ ₁₄ ₁₃ ₁₂ ₁₁ ₁₀ ₀₉ ₀₈ ₀₇ ₀₆ ₀₅ ₀₄ ₀₃ ₀₂ ₀₁ ₀₀
|
||||
// Reg: g₁₄ g₁₃ g₁₂ g₁₁ g₁₀ g₀₉ g₀₈ g₀₇ g₀₆ g₀₅ g₀₄ g₀₃ g₀₂ g₀₁ g₀₀ h₁₂ h₁₁ h₁₀ h₀₉ h₀₈ h₀₇ h₀₆ h₀₅ h₀₄ h₀₃ h₀₂ h₀₁ h₀₀ x x x 1
|
||||
#pragma endregion // id48lib state register
|
||||
#pragma region // bit definitions for the (stable) id48lib state register
|
||||
|
@ -164,8 +164,8 @@ static inline uint64_t reverse_bits_64(uint64_t n) {
|
|||
#pragma region // Unstable (during calculations) id48lib state register
|
||||
// Bit: ₆₃ ₆₂ ₆₁ ₆₀ ₅₉ ₅₈ ₅₇ ₅₆ ₅₅ ₅₄ ₅₃ ₅₂ ₅₁ ₅₀ ₄₉ ₄₈ ₄₇ ₄₆ ₄₅ ₄₄ ₄₃ ₄₂ ₄₁ ₄₀ ₃₉ ₃₈ ₃₇ ₃₆ ₃₅ ₃₄ ₃₃ ₃₂
|
||||
// Reg: i j r₀₆ r₀₅ r₀₄ r₀₃ r₀₂ r₀₁ r₀₀ m₀₆ m₀₅ m₀₄ m₀₃ m₀₂ m₀₁ m₀₀ l₀₆ l₀₅ l₀₄ l₀₃ l₀₂ l₀₁ l₀₀ g₂₂ g₂₁ g₂₀ g₁₉ g₁₈ g₁₇ g₁₆ g₁₅ g₁₄
|
||||
//
|
||||
// Bit: ₃₁ ₃₀ ₂₉ ₂₈ ₂₇ ₂₆ ₂₅ ₂₄ ₂₃ ₂₂ ₂₁ ₂₀ ₁₉ ₁₈ ₁₇ ₁₆ ₁₅ ₁₄ ₁₃ ₁₂ ₁₁ ₁₀ ₀₉ ₀₈ ₀₇ ₀₆ ₀₅ ₀₄ ₀₃ ₀₂ ₀₁ ₀₀
|
||||
//
|
||||
// Bit: ₃₁ ₃₀ ₂₉ ₂₈ ₂₇ ₂₆ ₂₅ ₂₄ ₂₃ ₂₂ ₂₁ ₂₀ ₁₉ ₁₈ ₁₇ ₁₆ ₁₅ ₁₄ ₁₃ ₁₂ ₁₁ ₁₀ ₀₉ ₀₈ ₀₇ ₀₆ ₀₅ ₀₄ ₀₃ ₀₂ ₀₁ ₀₀
|
||||
// Reg: g₁₃ g₁₂ g₁₁ g₁₀ g₀₉ g₀₈ g₀₇ g₀₆ g₀₅ g₀₄ g₀₃ g₀₂ g₀₁ g₀₀ h₁₂ h₁₁ h₁₀ h₀₉ h₀₈ h₀₇ h₀₆ h₀₅ h₀₄ h₀₃ h₀₂ h₀₁ h₀₀ _ a b c 0
|
||||
#pragma endregion // Unstable (during calculations) id48lib state register
|
||||
//
|
||||
|
@ -242,34 +242,33 @@ static inline uint64_t reverse_bits_64(uint64_t n) {
|
|||
// 0 // == 0 value defines as unstable state
|
||||
#pragma endregion // bit definitions for the (stable) id48lib state register
|
||||
#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 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 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 assign_single_ssr_bit ( ID48LIBX_STATE_REGISTERS* ssr, size_t bit_index, bool value) {
|
||||
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 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 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) {
|
||||
ASSERT(ssr != nullptr);
|
||||
ASSERT(bit_index < (sizeof(uint64_t) * 8));
|
||||
if (value) {
|
||||
set_single_ssr_bit(ssr, bit_index);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
clear_single_ssr_bit(ssr, bit_index);
|
||||
}
|
||||
}
|
||||
#pragma endregion // single bit test/set/clear/flip/assign
|
||||
#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_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_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_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_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_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_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_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_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_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_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 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_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 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_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 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 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_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_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_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_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_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_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)
|
||||
|
||||
/// <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="n56">nonce in pm3 order</param>
|
||||
/// <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,
|
||||
// perform the addition, and then reverse bits again to return to
|
||||
// native bit order (subscript is same as bit position).
|
||||
|
@ -334,7 +333,7 @@ static inline uint64_t calculate__p55_p00(const ID48LIB_KEY* k96, const ID48LIB_
|
|||
ASSERT(n56 != nullptr);
|
||||
uint64_t k40_k95 = 0;
|
||||
uint64_t n00_n55 = 0;
|
||||
//
|
||||
//
|
||||
// k [ 6] :== K₄₇..K₄₀
|
||||
// ...
|
||||
// k [ 0] :== K₉₅..K₈₈
|
||||
|
@ -367,7 +366,7 @@ static inline uint64_t calculate__p55_p00(const ID48LIB_KEY* k96, const ID48LIB_
|
|||
/// </summary>
|
||||
/// <param name="p55_p00">56 bit value: p₅₅..p₀₀</param>
|
||||
/// <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);
|
||||
static const uint64_t C_BITMASK44 = (1ull << 44) - 1u;
|
||||
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).
|
||||
/// May modify G00, G03, G04, G05, G06, G13, G16
|
||||
/// </summary>
|
||||
static inline void g_successor(ID48LIBX_STATE_REGISTERS* ssr) {
|
||||
static inline void g_successor(ID48LIBX_STATE_REGISTERS *ssr) {
|
||||
ASSERT(ssr != nullptr);
|
||||
ASSERT(!is_ssr_state_stable(ssr));
|
||||
assign_single_ssr_bit(ssr, SSR_BIT_G00, test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_j));
|
||||
|
@ -403,25 +402,26 @@ 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(n56 != nullptr);
|
||||
ID48LIBX_STATE_REGISTERS result; result.Raw = 0;
|
||||
ID48LIBX_STATE_REGISTERS* const ssr = &result; // the pointer is constant ... not the value it points to
|
||||
ID48LIBX_STATE_REGISTERS result;
|
||||
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);
|
||||
// p55_p00 is used to set initial value of register l
|
||||
if (true) {
|
||||
static const uint8_t C_BITMASK7 = ((1u << 7) - 1u);
|
||||
const uint8_t l = (
|
||||
((uint8_t)(p55_p00 >> 55)) ^ // 0 0 0 0 0 0 p55
|
||||
((uint8_t)(p55_p00 >> 51)) ^ // 0 0 p55 p54 p53 p52 p51
|
||||
((uint8_t)(p55_p00 >> 45)) // p51 p50 p49 p48 p47 p46 p45
|
||||
) & C_BITMASK7;
|
||||
((uint8_t)(p55_p00 >> 55)) ^ // 0 0 0 0 0 0 p55
|
||||
((uint8_t)(p55_p00 >> 51)) ^ // 0 0 p55 p54 p53 p52 p51
|
||||
((uint8_t)(p55_p00 >> 45)) // p51 p50 p49 p48 p47 p46 p45
|
||||
) & C_BITMASK7;
|
||||
set_register_l(ssr, l);
|
||||
ASSERT(l == get_register_l(ssr));
|
||||
}
|
||||
|
||||
|
||||
// p is used to calculate q
|
||||
const uint64_t q43_q00 = calculate__q43_q00(&p55_p00);
|
||||
|
||||
|
@ -429,7 +429,7 @@ static inline ID48LIBX_STATE_REGISTERS init_id48libx_state_register(const ID48LI
|
|||
// ===> G(q₂₀..q₄₂, 0, q₀₀..q₁₉)
|
||||
// ===> g₀₀..g₂₂ :=== q₂₀..q₄₂
|
||||
// and j₀₀..j₁₉ :=== q₀₀..q₁₉
|
||||
//
|
||||
//
|
||||
// But, since I'm storing the register with g₀₀ as lsb:
|
||||
// ===> g₂₂..g₀₀ :=== q₄₂..q₂₀
|
||||
if (true) {
|
||||
|
@ -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
|
||||
// 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)
|
||||
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;
|
||||
ssr->Raw |= 1u;
|
||||
|
||||
// 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));
|
||||
ssr->Raw <<= 1; // starts the process ... it's now an unstable value
|
||||
ASSERT(!is_ssr_state_stable(ssr));
|
||||
|
@ -478,27 +477,27 @@ static inline ID48LIBX_STATE_REGISTERS init_id48libx_state_register(const ID48LI
|
|||
|
||||
/// <summary>
|
||||
/// H(h) matches the research paper, definition 3.3
|
||||
///
|
||||
///
|
||||
/// Reads bits H01, H08, H09, H11, H12.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If ssr is in unstable state, caller is responsible for ensuring
|
||||
/// the values have not changed.
|
||||
/// </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);
|
||||
// ( h₀₁ && h₀₈ ) || ( h₀₉ && h₁₁ ) || (!h₁₂ )
|
||||
// \____ a1 ____/ \____ a2 ____/ \____ a3 ____/
|
||||
// result == xor(a1,a2,a3)
|
||||
bool a1 = is_ssr_state_stable(ssr) ?
|
||||
test_single_ssr_bit(ssr, SSR_BIT_H01) && test_single_ssr_bit(ssr, SSR_BIT_H08) :
|
||||
test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_H01) && test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_H08);
|
||||
test_single_ssr_bit(ssr, SSR_BIT_H01) && test_single_ssr_bit(ssr, SSR_BIT_H08) :
|
||||
test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_H01) && test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_H08);
|
||||
bool a2 = is_ssr_state_stable(ssr) ?
|
||||
test_single_ssr_bit(ssr, SSR_BIT_H09) && test_single_ssr_bit(ssr, SSR_BIT_H11) :
|
||||
test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_H09) && test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_H11);
|
||||
test_single_ssr_bit(ssr, SSR_BIT_H09) && test_single_ssr_bit(ssr, SSR_BIT_H11) :
|
||||
test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_H09) && test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_H11);
|
||||
bool a3 = is_ssr_state_stable(ssr) ?
|
||||
!test_single_ssr_bit(ssr, SSR_BIT_H12) :
|
||||
!test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_H12);
|
||||
!test_single_ssr_bit(ssr, SSR_BIT_H12) :
|
||||
!test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_H12);
|
||||
bool result = false;
|
||||
if (a1) result = !result;
|
||||
if (a2) result = !result;
|
||||
|
@ -510,7 +509,7 @@ static inline bool calculate_feedback_h(const ID48LIBX_STATE_REGISTERS* ssr) {
|
|||
/// fₗ(...) matches the research paper, definition 3.4
|
||||
/// hard-coded to use bits for calculation of 'a'
|
||||
/// </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);
|
||||
// a = fₗ( g00 g04 g06 g13 g18 h03 ) ⊕ g22 ⊕ r02 ⊕ r06
|
||||
// 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
|
||||
/// hard-coded to use bits for calculation of 'b'
|
||||
/// </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);
|
||||
// b = fₘ( g01 g05 g10 g15 h00 h07 ) ⊕ l00 ⊕ l03 ⊕ l06
|
||||
// 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
|
||||
/// hard-coded to use bits for calculation of 'c'
|
||||
/// </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(!is_ssr_state_stable(ssr));
|
||||
// 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
|
||||
/// See also Definition 3.2, defining that parameter as `j`.
|
||||
/// </summary>
|
||||
static inline bool calculate_j(const ID48LIBX_STATE_REGISTERS* ssr) {
|
||||
static inline bool calculate_j(const ID48LIBX_STATE_REGISTERS *ssr) {
|
||||
ASSERT(ssr != nullptr);
|
||||
// g′ := G(g, i, l₀₁ ⊕ m₀₆ ⊕ h₀₂ ⊕ h₀₈ ⊕ h₁₂)
|
||||
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^------ calculates `j`
|
||||
|
@ -602,22 +601,22 @@ static inline bool calculate_j(const ID48LIBX_STATE_REGISTERS* ssr) {
|
|||
/// Calculates a, b, c, j and new value for H₀₀.
|
||||
/// These are the only bits changed by this function.
|
||||
/// </summary>
|
||||
static inline void calculate_temporaries(ID48LIBX_STATE_REGISTERS* ssr) {
|
||||
static inline void calculate_temporaries(ID48LIBX_STATE_REGISTERS *ssr) {
|
||||
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 =
|
||||
~(
|
||||
(1ull << SSR_UNSTABLE_BIT_a) |
|
||||
(1ull << SSR_UNSTABLE_BIT_b) |
|
||||
(1ull << SSR_UNSTABLE_BIT_c) |
|
||||
(1ull << SSR_UNSTABLE_BIT_j) |
|
||||
(1ull << SSR_UNSTABLE_NEW_BIT_H00)
|
||||
~(
|
||||
(1ull << SSR_UNSTABLE_BIT_a) |
|
||||
(1ull << SSR_UNSTABLE_BIT_b) |
|
||||
(1ull << SSR_UNSTABLE_BIT_c) |
|
||||
(1ull << SSR_UNSTABLE_BIT_j) |
|
||||
(1ull << SSR_UNSTABLE_NEW_BIT_H00)
|
||||
);
|
||||
|
||||
const uint64_t backup = ssr->Raw & bits_must_remain_same_mask;
|
||||
(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
|
||||
|
||||
ASSERT(!is_ssr_state_stable(ssr)); // assigning temp values directly in ssr, so...
|
||||
|
@ -643,29 +642,30 @@ 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_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;
|
||||
(void)chk; // to avoid warning about unused variable
|
||||
ASSERT(chk == backup);
|
||||
#pragma endregion // to be removed after all is validated
|
||||
#pragma endregion // to be removed after all is validated
|
||||
|
||||
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₆ )
|
||||
// msb 19 ---^ lsb 00 ---^^
|
||||
ASSERT(ssr != nullptr);
|
||||
ASSERT(!is_ssr_state_stable(ssr));
|
||||
OUTPUT_INDEX2 result; result.Raw = 0;
|
||||
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_a )) result.Raw |= (1u << 19);
|
||||
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);
|
||||
OUTPUT_INDEX2 result;
|
||||
result.Raw = 0;
|
||||
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_a)) result.Raw |= (1u << 19);
|
||||
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);
|
||||
//if (test_single_ssr_bit(ssr, SSR_UNSTABLE_BIT_i) ) bit17 = !bit17;
|
||||
//if (bit17 ) result.Raw |= (1u << 17);
|
||||
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_L00)) result.Raw |= (1u << 16);
|
||||
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_L00)) result.Raw |= (1u << 16);
|
||||
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_L02)) result.Raw |= (1u << 15);
|
||||
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_L03)) result.Raw |= (1u << 14);
|
||||
if (test_single_ssr_bit(ssr, SSR_UNSTABLE_OLD_BIT_L04)) result.Raw |= (1u << 13);
|
||||
|
@ -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
|
||||
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(is_ssr_state_stable(ssr));
|
||||
|
||||
|
@ -718,7 +718,7 @@ static inline bool calculate_successor_state(ID48LIBX_STATE_REGISTERS* ssr, bool
|
|||
// 4. calculate and save output index
|
||||
OUTPUT_INDEX2 output_index = calculate_output_index(ssr); // note: does *NOT* rely on new H00 value
|
||||
bool output_result = id48libx_output_lookup(output_index.Raw);
|
||||
|
||||
|
||||
// 5. g --> g', aka G(g, i, j)
|
||||
g_successor(ssr);
|
||||
|
||||
|
@ -735,7 +735,7 @@ static inline bool calculate_successor_state(ID48LIBX_STATE_REGISTERS* ssr, bool
|
|||
|
||||
// Keep only the registers (no temporaries)
|
||||
ssr->Raw &= SSR_BITMASK_REG_ALL;
|
||||
|
||||
|
||||
// Mark as stable view of the SSR
|
||||
ssr->Raw |= 1u;
|
||||
|
||||
|
@ -748,14 +748,15 @@ static inline bool calculate_successor_state(ID48LIBX_STATE_REGISTERS* ssr, bool
|
|||
/// by one bit each iteration (allowing least significant bit
|
||||
/// to always be the input bit).
|
||||
/// </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);
|
||||
|
||||
// Per research paper, key bit 39 is used first.
|
||||
// So, what should end up in result is: 0²⁴ k₀₀..K₃₉
|
||||
// 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₈₈
|
||||
// ...
|
||||
|
@ -775,19 +776,19 @@ static inline INPUT_BITS2 get_key_input_bits(const ID48LIB_KEY* k) {
|
|||
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);
|
||||
bool result = inputs->Raw & 1ull;
|
||||
inputs->Raw >>= 1;
|
||||
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);
|
||||
outputs->Raw <<= 1;
|
||||
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(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[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(grn20_out != nullptr);
|
||||
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(
|
||||
const ID48LIB_KEY* k,
|
||||
const ID48LIB_NONCE* n,
|
||||
ID48LIB_FRN* frn28_out,
|
||||
ID48LIB_GRN* grn20_out
|
||||
)
|
||||
{
|
||||
const ID48LIB_KEY *k,
|
||||
const ID48LIB_NONCE *n,
|
||||
ID48LIB_FRN *frn28_out,
|
||||
ID48LIB_GRN *grn20_out
|
||||
) {
|
||||
ASSERT(k != nullptr);
|
||||
ASSERT(n != nullptr);
|
||||
ASSERT(frn28_out != nullptr);
|
||||
|
@ -834,7 +834,8 @@ static void retro_generator_impl(
|
|||
|
||||
// get 55-bit successor state input
|
||||
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++) {
|
||||
ASSERT(is_ssr_state_stable(&ssr));
|
||||
|
||||
|
@ -865,9 +866,10 @@ static void retro_generator_impl(
|
|||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 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);
|
||||
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;
|
||||
bool output_bit = calculate_successor_state(&s, !!input_bit);
|
||||
r.state.Raw = s.Raw;
|
||||
|
@ -875,23 +877,23 @@ ID48LIBX_SUCCESSOR_RESULT id48libx_retro003_successor(const ID48LIBX_STATE_REGIS
|
|||
return r;
|
||||
}
|
||||
// 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(nonce != nullptr);
|
||||
|
||||
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;
|
||||
return result;
|
||||
}
|
||||
|
||||
// public API
|
||||
void id48lib_generator(
|
||||
const ID48LIB_KEY* k,
|
||||
const ID48LIB_NONCE* n,
|
||||
ID48LIB_FRN* frn28_out,
|
||||
ID48LIB_GRN* grn20_out
|
||||
)
|
||||
{
|
||||
const ID48LIB_KEY *k,
|
||||
const ID48LIB_NONCE *n,
|
||||
ID48LIB_FRN *frn28_out,
|
||||
ID48LIB_GRN *grn20_out
|
||||
) {
|
||||
retro_generator_impl(k, n, frn28_out, grn20_out);
|
||||
}
|
||||
|
|
|
@ -45,8 +45,8 @@ typedef struct _ID48LIBX_SUCCESSOR_RESULT {
|
|||
} ID48LIBX_SUCCESSOR_RESULT;
|
||||
|
||||
// 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_STATE_REGISTERS id48libx_retro003_init (const ID48LIB_KEY* key, const ID48LIB_NONCE* nonce);
|
||||
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);
|
||||
|
||||
bool id48libx_output_lookup(uint32_t output_index);
|
||||
|
||||
|
|
|
@ -116,8 +116,8 @@ typedef struct _RECOVERY_STATE {
|
|||
} RECOVERY_STATE;
|
||||
|
||||
// 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_STATE_REGISTERS(*ID48LIB_INIT_FN )(const ID48LIB_KEY* key, const ID48LIB_NONCE* nonce);
|
||||
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);
|
||||
|
||||
static const ID48LIB_INIT_FN init_fn = id48libx_retro003_init;
|
||||
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="more_bits">0 K₃₃..K₄₇ (to support simple incrementing input)</param>
|
||||
/// <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;
|
||||
result.k[ 0] = input_partial_key->k[0]; // k[ 0] :== 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_grn">PM3 compatible input for grn</param>
|
||||
/// <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:
|
||||
// frn[ 0] :== 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[ 1] :== O₃₆ .. O₄₃
|
||||
// grn[ 2] :== O₄₄..O₄₇ 0000
|
||||
EXPECTED_OUTPUT_BITS result; result.Raw = 0u;
|
||||
result.Raw <<= 4; 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₂₈
|
||||
EXPECTED_OUTPUT_BITS result;
|
||||
result.Raw = 0u;
|
||||
result.Raw <<= 4;
|
||||
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 <<= 8; 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₀₀
|
||||
result.Raw <<= 4;
|
||||
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[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;
|
||||
}
|
||||
/// <summary>
|
||||
|
@ -180,7 +188,7 @@ static EXPECTED_OUTPUT_BITS create_expected_output_bits(const ID48LIB_FRN* input
|
|||
/// </summary>
|
||||
/// <param name="recovery_state">A value in the range [0,55]</param>
|
||||
/// <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(current_state_index >= 7);
|
||||
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
|
||||
}
|
||||
|
||||
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(k_low != nullptr);
|
||||
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));
|
||||
}
|
||||
|
||||
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;
|
||||
for (uint8_t i = 0; all_still_match && i < 15; 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);
|
||||
bool expected_result = get_expected_output_bit(s, src_idx);
|
||||
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 };
|
||||
|
||||
static void init(
|
||||
const ID48LIB_KEY * input_partial_key,
|
||||
const ID48LIB_NONCE * input_nonce,
|
||||
const ID48LIB_FRN * input_frn,
|
||||
const ID48LIB_GRN * input_grn
|
||||
)
|
||||
{
|
||||
const ID48LIB_KEY *input_partial_key,
|
||||
const ID48LIB_NONCE *input_nonce,
|
||||
const ID48LIB_FRN *input_frn,
|
||||
const ID48LIB_GRN *input_grn
|
||||
) {
|
||||
memset(&g_S, 0, sizeof(RECOVERY_STATE));
|
||||
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];
|
||||
|
@ -240,7 +247,7 @@ static void init(
|
|||
g_S.is_fresh_initialization = true;
|
||||
}
|
||||
static bool get_next_potential_key(
|
||||
ID48LIB_KEY* potential_key_output
|
||||
ID48LIB_KEY *potential_key_output
|
||||
) {
|
||||
memset(potential_key_output, 0, sizeof(ID48LIB_KEY));
|
||||
|
||||
|
@ -271,8 +278,7 @@ static bool get_next_potential_key(
|
|||
g_S.is_fresh_initialization = false;
|
||||
k_low.Raw = 0ull;
|
||||
current_key_bit_shift = 47;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// by definition, a returned potential key had all the bits defined
|
||||
current_key_bit_shift = 0;
|
||||
k_low = g_S.last_returned_potential_key;
|
||||
|
@ -417,16 +423,15 @@ static bool get_next_potential_key(
|
|||
|
||||
|
||||
void id48lib_key_recovery_init(
|
||||
const ID48LIB_KEY * input_partial_key,
|
||||
const ID48LIB_NONCE * input_nonce,
|
||||
const ID48LIB_FRN * input_frn,
|
||||
const ID48LIB_GRN * input_grn
|
||||
)
|
||||
{
|
||||
const ID48LIB_KEY *input_partial_key,
|
||||
const ID48LIB_NONCE *input_nonce,
|
||||
const ID48LIB_FRN *input_frn,
|
||||
const ID48LIB_GRN *input_grn
|
||||
) {
|
||||
init(input_partial_key, input_nonce, input_frn, input_grn);
|
||||
}
|
||||
bool id48lib_key_recovery_next(
|
||||
ID48LIB_KEY* potential_key_output
|
||||
ID48LIB_KEY *potential_key_output
|
||||
) {
|
||||
return get_next_potential_key(potential_key_output);
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ end
|
|||
local function wupc()
|
||||
return{
|
||||
[0] = 'hf 14a raw -akb 7 40',
|
||||
[1] = 'hf 14a raw -k 43',
|
||||
[1] = 'hf 14a raw -k 43',
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -152,7 +152,7 @@ local function BlockParser(data, block)
|
|||
print("["..ansicolors.yellow.."="..ansicolors.reset.."] "..string.format("%02d", block).." | "..ansicolors.red..string.sub(data,1,2).." "..string.sub(data,3,4).." "..string.sub(data,5,6).." "..string.sub(data,7,8).." "..string.sub(data,9,10).." "..string.sub(data,11,12).." "..string.sub(data,13,14).." "..string.sub(data,15,16).." "..string.sub(data,17,18).." "..string.sub(data,19,20).." "..string.sub(data,21,22).." "..string.sub(data,23,24).." "..string.sub(data,25,26).." "..string.sub(data,27,28).." "..string.sub(data,29,30).." "..string.sub(data,31,32)..ansicolors.reset)
|
||||
elseif (block+1)%4 == 0 then -- for ST
|
||||
print("["..ansicolors.yellow.."="..ansicolors.reset.."] "..string.format("%02d", block).." | "..ansicolors.yellow..string.sub(data,1,2).." "..string.sub(data,3,4).." "..string.sub(data,5,6).." "..string.sub(data,7,8).." "..string.sub(data,9,10).." "..string.sub(data,11,12).." "..ansicolors.magenta..string.sub(data,13,14).." "..string.sub(data,15,16).." "..string.sub(data,17,18).." "..ansicolors.reset..string.sub(data,19,20).." "..ansicolors.yellow..string.sub(data,21,22).." "..string.sub(data,23,24).." "..string.sub(data,25,26).." "..string.sub(data,27,28).." "..string.sub(data,29,30).." "..string.sub(data,31,32)..ansicolors.reset)
|
||||
else
|
||||
else
|
||||
print("["..ansicolors.yellow.."="..ansicolors.reset.."] "..string.format("%02d", block).." | "..string.sub(data,1,2).." "..string.sub(data,3,4).." "..string.sub(data,5,6).." "..string.sub(data,7,8).." "..string.sub(data,9,10).." "..string.sub(data,11,12).." "..string.sub(data,13,14).." "..string.sub(data,15,16).." "..string.sub(data,17,18).." "..string.sub(data,19,20).." "..string.sub(data,21,22).." "..string.sub(data,23,24).." "..string.sub(data,25,26).." "..string.sub(data,27,28).." "..string.sub(data,29,30).." "..string.sub(data,31,32)) end
|
||||
end
|
||||
local function sendRaw(rawdata, keep)
|
||||
|
@ -177,7 +177,7 @@ end
|
|||
-- Functions to work with configuration data (E000, E100 cmds)
|
||||
local function readconf()
|
||||
configbuffer = sendRaw("E000", true)
|
||||
if string.len(configbuffer) ~= 36 then
|
||||
if string.len(configbuffer) ~= 36 then
|
||||
oops("Tag sent wrong length of config!")
|
||||
lib14a.disconnect()
|
||||
return 1 end
|
||||
|
@ -186,9 +186,9 @@ end
|
|||
local function writeconf(configbuffer)
|
||||
configbuffer=utils.ConvertBytesToHex(configbuffer)
|
||||
print(ansicolors.yellow.."[|]".. ansicolors.reset .." The new config is: "..configbuffer)
|
||||
if sendRaw("E100", true) == "0A" then
|
||||
if sendRaw(configbuffer, true) == "0A" then
|
||||
print(ansicolors.yellow.."[/]".. ansicolors.reset .." Config updated successfully")
|
||||
if sendRaw("E100", true) == "0A" then
|
||||
if sendRaw(configbuffer, true) == "0A" then
|
||||
print(ansicolors.yellow.."[/]".. ansicolors.reset .." Config updated successfully")
|
||||
else
|
||||
oops("Tag did not ACK config update!")
|
||||
lib14a.disconnect()
|
||||
|
@ -211,7 +211,7 @@ function main(args)
|
|||
local f3perso = false
|
||||
local signature = nil
|
||||
local wipe = false
|
||||
|
||||
|
||||
local targetblk = nil
|
||||
local targetbblk = nil
|
||||
local targetbsec = nil
|
||||
|
@ -226,7 +226,7 @@ function main(args)
|
|||
local magicauth = nil
|
||||
local statenc = nil
|
||||
local sigsec = nil
|
||||
|
||||
|
||||
local configwrite = nil
|
||||
-- End of ConfigStar
|
||||
-- Parse arguments
|
||||
|
@ -255,7 +255,7 @@ function main(args)
|
|||
if o == 'r' then if a == "1" then sigsec = true elseif a == "0" then sigsec= false end end
|
||||
end
|
||||
if gen1 ~= nil or gen1com~= nil or keyblock~= nil or cuid~= nil or cl2mode~= nil or shadowmode~= nil or magicauth~= nil or statenc~= nil or sigsec~= nil then configwrite = true end
|
||||
|
||||
|
||||
if targetbblk then if tonumber(targetbblk)>63 then oops("Block is above 63") return 1 end end
|
||||
if targetblk then if tonumber(targetblk)>63 then oops("Block is above 63") return 1 end end
|
||||
if targetsec then if tonumber(targetsec)>15 then oops("Sector is above 15") return 1 end end
|
||||
|
@ -336,7 +336,7 @@ function main(args)
|
|||
-- Now, let's write! 1. We wake up the tag in magic mode.
|
||||
-- 2. We will deal with the "easier" 7 byte UID stuff
|
||||
if uid then
|
||||
if string.len(uid) == 14 then
|
||||
if string.len(uid) == 14 then
|
||||
wakeupmagic(writetype)
|
||||
if f3perso == true then print("[?] WARNING: F3 perso write is set, but 7 byte UID is passed. Ignoring -3 argument") end
|
||||
local configdata = readconf()
|
||||
|
@ -347,20 +347,20 @@ function main(args)
|
|||
configdata[10]=0x5A
|
||||
writeconf(configdata)
|
||||
end
|
||||
if sendRaw("A800", true) ~= "0A" then
|
||||
oops("Tag did not ACK `A800` command!")
|
||||
if sendRaw("A800", true) ~= "0A" then
|
||||
oops("Tag did not ACK `A800` command!")
|
||||
lib14a.disconnect()
|
||||
return 1 end
|
||||
print("[?] WARNING: nUID should be updated with this value:")
|
||||
print(makenuid(uid))
|
||||
print(ansicolors.yellow.."[/]".. ansicolors.reset .." Use `--f3d` to update nUID for Perso F3 only.")
|
||||
if sendRaw(payload, true) ~= "0A" then
|
||||
oops("Tag did not ACK data to write!")
|
||||
if sendRaw(payload, true) ~= "0A" then
|
||||
oops("Tag did not ACK data to write!")
|
||||
lib14a.disconnect()
|
||||
return 1 end
|
||||
print(ansicolors.yellow.."[-]".. ansicolors.reset .." Updating real block 0")
|
||||
if sendRaw("A000", true) ~= "0A" then
|
||||
oops("Tag did not ACK `A000` command!")
|
||||
if sendRaw("A000", true) ~= "0A" then
|
||||
oops("Tag did not ACK `A000` command!")
|
||||
lib14a.disconnect()
|
||||
return 1 end
|
||||
if sendRaw(cltwo_block0(uid), false) ~="0A" then oops("Tag did not ACK data to write!") end
|
||||
|
@ -370,8 +370,8 @@ function main(args)
|
|||
local configdata = readconf()
|
||||
if configdata[10] == 0x69 or f3perso == true then -- If we have Perso: F3, then write backdoor blk 1
|
||||
if f3perso == true then print ("[?] WARNING: F3 flag enabled. Updating UID used for F3 perso") end
|
||||
if sendRaw("A801", true) ~= "0A" then
|
||||
oops("Tag did not ACK `A801` command!")
|
||||
if sendRaw("A801", true) ~= "0A" then
|
||||
oops("Tag did not ACK `A801` command!")
|
||||
lib14a.disconnect()
|
||||
return 1 end
|
||||
else -- Otherwise write real block 0.
|
||||
|
@ -382,8 +382,8 @@ function main(args)
|
|||
configdata[10]=0x00
|
||||
writeconf(configdata)
|
||||
end
|
||||
if sendRaw("A000", true) ~= "0A" then
|
||||
oops("Tag did not ACK `A000` command!")
|
||||
if sendRaw("A000", true) ~= "0A" then
|
||||
oops("Tag did not ACK `A000` command!")
|
||||
lib14a.disconnect()
|
||||
return 1 end
|
||||
end
|
||||
|
@ -400,20 +400,20 @@ function main(args)
|
|||
configdata[14] = 0x5A
|
||||
writeconf(configdata)
|
||||
end
|
||||
if sendRaw("A805", true) ~= "0A" then
|
||||
oops("Tag did not ACK `A805` command!")
|
||||
if sendRaw("A805", true) ~= "0A" then
|
||||
oops("Tag did not ACK `A805` command!")
|
||||
lib14a.disconnect()
|
||||
return 1 end
|
||||
if sendRaw(string.sub(signature,1,32), true) ~= "0A" then
|
||||
oops("Tag did not ACK data 1 to write!")
|
||||
if sendRaw(string.sub(signature,1,32), true) ~= "0A" then
|
||||
oops("Tag did not ACK data 1 to write!")
|
||||
lib14a.disconnect()
|
||||
return 1 end
|
||||
if sendRaw("A806", true) ~= "0A" then
|
||||
oops("Tag did not ACK `A806` command!")
|
||||
if sendRaw("A806", true) ~= "0A" then
|
||||
oops("Tag did not ACK `A806` command!")
|
||||
lib14a.disconnect()
|
||||
return 1 end
|
||||
if sendRaw(string.sub(signature,33,64), false) ~= "0A" then
|
||||
oops("Tag did not ACK data 2 to write!")
|
||||
oops("Tag did not ACK data 2 to write!")
|
||||
lib14a.disconnect()
|
||||
return 1 end
|
||||
end
|
||||
|
@ -422,7 +422,7 @@ function main(args)
|
|||
wakeupmagic(writetype)
|
||||
config=readconf()
|
||||
if (gen1 == false and magicauth == false) or ((config[1]==0x85 and config[2] == 0x00) and magicauth==false) or ((config[12]==0x00) and gen1 == false) then
|
||||
oops("What you are about to do is potentially dangerous. \n If you really want to continue (potentially leaving your tag in an unusable state), enter this line as given, without quotation marks:\n \"Yes, do as I say!\"")
|
||||
oops("What you are about to do is potentially dangerous. \n If you really want to continue (potentially leaving your tag in an unusable state), enter this line as given, without quotation marks:\n \"Yes, do as I say!\"")
|
||||
local ans=io.read()
|
||||
if ans ~="Yes, do as I say!" then
|
||||
lib14a.disconnect()
|
||||
|
@ -483,4 +483,4 @@ function main(args)
|
|||
lib14a.disconnect()
|
||||
end
|
||||
end
|
||||
main(args)
|
||||
main(args)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
|
@ -32,7 +32,7 @@ class BitMe:
|
|||
|
||||
def addBytes(self, bytes):
|
||||
self.data.frombytes(bytes)
|
||||
|
||||
|
||||
def nom_bits(self, cb):
|
||||
ret = self.data[self.idx:self.idx + cb]
|
||||
self.idx += cb
|
||||
|
@ -40,10 +40,10 @@ class BitMe:
|
|||
|
||||
def nom(self, cb):
|
||||
return ba2int(self.nom_bits(cb))
|
||||
|
||||
|
||||
def nom_bits_left(self):
|
||||
return self.data[self.idx:None]
|
||||
|
||||
|
||||
def isEmpty(self):
|
||||
return (len(self.data) == 0)
|
||||
|
||||
|
@ -103,11 +103,11 @@ def main():
|
|||
|
||||
print('Basic script to try to interpret Intertic data on ST25TB / SRT512 in french transports')
|
||||
print('--------------------------------------------------------------------------------------\n')
|
||||
|
||||
|
||||
if(len(sys.argv) != 2):
|
||||
print('\tUsage : {0} <dumpfile.bin>\n\tExample: {0} hf-14b-D00233787DFBB4D5-dump.bin\n'.format(sys.argv[0]))
|
||||
return 1
|
||||
|
||||
|
||||
binaryDumpFileName = sys.argv[1]
|
||||
|
||||
data = BitMe()
|
||||
|
@ -122,7 +122,7 @@ def main():
|
|||
if (size != 68):
|
||||
print('\'{}\' file size is not 68 bytes'.format(binaryDumpFileName))
|
||||
return 2
|
||||
|
||||
|
||||
while True:
|
||||
chunk = file.read(4)
|
||||
if not chunk:
|
||||
|
@ -154,7 +154,7 @@ def main():
|
|||
print('KeyId :', hex(KeyId));
|
||||
|
||||
match PID:
|
||||
|
||||
|
||||
case 0x02:
|
||||
Distribution_Data.addBits(data.nom_bits(3 * 32))
|
||||
Usage_Data_End = data.nom_bits(30)
|
||||
|
@ -167,7 +167,7 @@ def main():
|
|||
Usage_Sta_E.addBits(data.nom_bits(2))
|
||||
Usage_Cer.addBits(data.nom_bits(16))
|
||||
Distribution_Cer.addBits(data.nom_bits(32))
|
||||
|
||||
|
||||
case 0x06:
|
||||
Distribution_Data.addBits(data.nom_bits(4 * 32))
|
||||
C1.addBits(data.nom_bits(32))
|
||||
|
@ -182,7 +182,7 @@ def main():
|
|||
Usage_Sta_E.addBits(data.nom_bits(2))
|
||||
Usage_Cer.addBits(data.nom_bits(16))
|
||||
Distribution_Cer.addBits(data.nom_bits(32))
|
||||
|
||||
|
||||
case 0x07:
|
||||
Distribution_Data.addBits(data.nom_bits(4 * 32))
|
||||
C1.addBits(data.nom_bits(32))
|
||||
|
@ -197,7 +197,7 @@ def main():
|
|||
Usage_Sta_E.addBits(data.nom_bits(2))
|
||||
Usage_Cer.addBits(data.nom_bits(16))
|
||||
Distribution_Cer.addBits(data.nom_bits(32))
|
||||
|
||||
|
||||
case 0x0a:
|
||||
Distribution_Data.addBits(data.nom_bits(4 * 32))
|
||||
C1.addBits(data.nom_bits(32))
|
||||
|
@ -206,7 +206,7 @@ def main():
|
|||
Distribution_Data.addBits(Distribution_Data_End)
|
||||
Distribution_Cer.addBits(data.nom_bits(32))
|
||||
# No USAGE for 0x0a
|
||||
|
||||
|
||||
case 0x0b: # Not in the draft :(
|
||||
Distribution_Data.addBits(data.nom_bits(4 * 32))
|
||||
C1.addBits(data.nom_bits(32))
|
||||
|
@ -214,7 +214,7 @@ def main():
|
|||
Distribution_Data.addBits(data.nom_bits(8 * 32))
|
||||
Distribution_Data.addBits(Distribution_Data_End)
|
||||
Distribution_Cer.addBits(data.nom_bits(32))
|
||||
|
||||
|
||||
case _:
|
||||
print('PID not (yet?) supported')
|
||||
return 3
|
||||
|
@ -278,8 +278,8 @@ def main():
|
|||
|
||||
print(' left... :', Usage_left);
|
||||
print(' [CER] Usage : {:04x}'.format(Usage_Cer.nom(16)))
|
||||
|
||||
return 0
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -63,7 +63,7 @@ static const uint8_t KMAC_type[4] = {0x00, 0x00, 0x00, 0x02};
|
|||
* SAC = Suppliment Access Control
|
||||
|
||||
File structures
|
||||
----------------
|
||||
----------------
|
||||
Mastefile MF
|
||||
-- EF.ATR/INFO (01)
|
||||
-- EF.DIR (1E)
|
||||
|
@ -91,7 +91,7 @@ File names and what they contain
|
|||
EG.DG1 = MRZ data
|
||||
EG.DG2 = Biometric template, Photo
|
||||
EG.DG3 = Biometric template, Fingerprint (EAC / AA)
|
||||
EG.DG4 = Biometric template, Iris (EAC / AA)
|
||||
EG.DG4 = Biometric template, Iris (EAC / AA)
|
||||
EG.DG5 = Image template
|
||||
EG.DG6 = Image template
|
||||
EG.DG7 = Image template (Signature?)
|
||||
|
@ -1884,7 +1884,7 @@ static int emrtd_print_ef_sod_info(uint8_t *dg_hashes_calc, uint8_t *dg_hashes_s
|
|||
if (calc_all_zero == true && sod_all_zero == true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// silly padding thingy
|
||||
int n = 40 - strlen(dg_table[i].desc);
|
||||
|
||||
|
|
|
@ -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);
|
||||
PrintAndLogEx(INPLACE, "Sector... " _YELLOW_("%2d") " block..." _YELLOW_("%2d") " ( " _GREEN_("ok") " )", sectorNo, blockNo);
|
||||
} else {
|
||||
PrintAndLogEx(FAILED, "\nSector... %2d Block... %2d ( " _RED_("fail") " )" , sectorNo, blockNo);
|
||||
PrintAndLogEx(FAILED, "\nSector... %2d Block... %2d ( " _RED_("fail") " )", sectorNo, blockNo);
|
||||
}
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "Timeout reading sector... %2d block... %2d", sectorNo, blockNo);
|
||||
|
@ -8464,11 +8464,11 @@ static void parse_gdm_cfg(const uint8_t *d) {
|
|||
PrintAndLogEx(SUCCESS, "------------------- " _CYAN_("GDM Configuration") " -----------------------------------------");
|
||||
PrintAndLogEx(SUCCESS, _YELLOW_("%s"), sprint_hex_inrow(d, MFBLOCK_SIZE));
|
||||
PrintAndLogEx(SUCCESS, _YELLOW_("%02X%02X") "............................ %s %s"
|
||||
, d[0]
|
||||
, d[1]
|
||||
, (d[0] == 0x85 && d[1] == 0x00) ? "Magic wakeup disabled" : _GREEN_("Magic wakeup enabled")
|
||||
, (d[0] == 0x85 && d[1] == 0x00) ? "" : ((d[0] == 0x7A && d[1] == 0xFF) ? _GREEN_("with GDM cfg block access") : _RED_(", no GDM cfg block access"))
|
||||
);
|
||||
, d[0]
|
||||
, d[1]
|
||||
, (d[0] == 0x85 && d[1] == 0x00) ? "Magic wakeup disabled" : _GREEN_("Magic wakeup enabled")
|
||||
, (d[0] == 0x85 && d[1] == 0x00) ? "" : ((d[0] == 0x7A && d[1] == 0xFF) ? _GREEN_("with GDM cfg block access") : _RED_(", no GDM cfg block access"))
|
||||
);
|
||||
PrintAndLogEx(SUCCESS, "...." _YELLOW_("%02X") ".......................... Magic wakeup style %s", d[2], ((d[2] == 0x85) ? "GDM 20(7)/23" : "Gen1a 40(7)/43"));
|
||||
PrintAndLogEx(SUCCESS, "......" _YELLOW_("%02X%02X%02X") ".................... n/a", d[3], d[4], d[5]);
|
||||
PrintAndLogEx(SUCCESS, "............" _YELLOW_("%02X") ".................. %s", d[6], (d[6] == 0x5A) ? "Key B use blocked when readable by ACL" : "Key B use allowed when readable by ACL");
|
||||
|
|
|
@ -2565,7 +2565,7 @@ static int CmdHF14AMfUWrBl(const char *Cmd) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
//
|
||||
|
@ -5348,10 +5348,10 @@ static int CmdHF14AMfuWipe(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, "Start wiping...");
|
||||
PrintAndLogEx(INFO, "-----+-----------------------------");
|
||||
// time to wipe card
|
||||
// We skip the first four blocks.
|
||||
// We skip the first four blocks.
|
||||
// block 0,1 - UID
|
||||
// block 2 - lock
|
||||
// block 3 - OTP
|
||||
// block 2 - lock
|
||||
// block 3 - OTP
|
||||
for (uint8_t i = 4; i < card_mem_size; i++) {
|
||||
|
||||
if (kbd_enter_pressed()) {
|
||||
|
@ -5361,23 +5361,23 @@ static int CmdHF14AMfuWipe(const char *Cmd) {
|
|||
|
||||
uint8_t data[MFU_BLOCK_SIZE];
|
||||
memset(data, 0x00, sizeof(data));
|
||||
|
||||
|
||||
// UL_C specific
|
||||
if ((tagtype & MFU_TT_UL_C)) {
|
||||
// Set DES key.. Skipping for now.
|
||||
}
|
||||
|
||||
// UL_AES specific
|
||||
if ((tagtype & MFU_TT_UL_AES)) {
|
||||
if ((tagtype & MFU_TT_UL_AES)) {
|
||||
// Set AES key.. Skipping for now since no access to such card.
|
||||
}
|
||||
|
||||
// UL / NTAG with PWD/PACK
|
||||
if ((tagtype & (MFU_TT_UL_EV1_48 | MFU_TT_UL_EV1_128 | MFU_TT_UL_EV1 | MFU_TT_UL_NANO_40 |
|
||||
MFU_TT_NTAG_210u | MFU_TT_NTAG_213 | MFU_TT_NTAG_213_F | MFU_TT_NTAG_213_C |
|
||||
MFU_TT_NTAG_213_TT | MFU_TT_NTAG_215 | MFU_TT_NTAG_216 | MFU_TT_NTAG_216_F |
|
||||
MFU_TT_NTAG_I2C_1K | MFU_TT_NTAG_I2C_2K | MFU_TT_NTAG_I2C_1K_PLUS | MFU_TT_NTAG_I2C_2K_PLUS
|
||||
))) {
|
||||
MFU_TT_NTAG_210u | MFU_TT_NTAG_213 | MFU_TT_NTAG_213_F | MFU_TT_NTAG_213_C |
|
||||
MFU_TT_NTAG_213_TT | MFU_TT_NTAG_215 | MFU_TT_NTAG_216 | MFU_TT_NTAG_216_F |
|
||||
MFU_TT_NTAG_I2C_1K | MFU_TT_NTAG_I2C_2K | MFU_TT_NTAG_I2C_1K_PLUS | MFU_TT_NTAG_I2C_2K_PLUS
|
||||
))) {
|
||||
|
||||
|
||||
// cfg 1
|
||||
|
@ -5405,8 +5405,8 @@ static int CmdHF14AMfuWipe(const char *Cmd) {
|
|||
memset(data, 0xFF, sizeof(data));
|
||||
}
|
||||
|
||||
// Since we changed PWD before, we need to use new PWD to set PACK
|
||||
// Pack will be all zeros,
|
||||
// Since we changed PWD before, we need to use new PWD to set PACK
|
||||
// Pack will be all zeros,
|
||||
if (i == card_mem_size - 1) {
|
||||
memset(auth_key_ptr, 0xFF, ak_len);
|
||||
}
|
||||
|
|
|
@ -880,7 +880,7 @@ static int CmdStandalone(const char *Cmd) {
|
|||
}
|
||||
CLIParserFree(ctx);
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_STANDALONE, (uint8_t *)&packet, sizeof(struct p));
|
||||
SendCommandNG(CMD_STANDALONE, (uint8_t *)&packet, sizeof(struct p));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -423,6 +423,7 @@ const static vocabulary_t vocabulary[] = {
|
|||
{ 0, "hf mfu restore" },
|
||||
{ 0, "hf mfu tamper" },
|
||||
{ 1, "hf mfu view" },
|
||||
{ 0, "hf mfu wipe" },
|
||||
{ 0, "hf mfu wrbl" },
|
||||
{ 0, "hf mfu eload" },
|
||||
{ 0, "hf mfu esave" },
|
||||
|
@ -512,6 +513,8 @@ const static vocabulary_t vocabulary[] = {
|
|||
{ 1, "hf vas help" },
|
||||
{ 0, "hf vas reader" },
|
||||
{ 1, "hf vas decrypt" },
|
||||
{ 1, "hf waveshare help" },
|
||||
{ 1, "hf waveshare load" },
|
||||
{ 1, "hf xerox help" },
|
||||
{ 1, "hf xerox list" },
|
||||
{ 0, "hf xerox info" },
|
||||
|
|
|
@ -3061,7 +3061,7 @@
|
|||
},
|
||||
"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": [
|
||||
"hf list --frame -> show frame delay times",
|
||||
"hf list -1 -> use trace buffer"
|
||||
|
@ -7084,6 +7084,20 @@
|
|||
],
|
||||
"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": {
|
||||
"command": "hf mfu wrbl",
|
||||
"description": "Write a block. It autodetects card type.",
|
||||
|
@ -7722,6 +7736,28 @@
|
|||
],
|
||||
"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": {
|
||||
"command": "hf xerox dump",
|
||||
"description": "Dump all memory from a Fuji/Xerox tag ISO/IEC 14443 type B based communications",
|
||||
|
@ -8039,9 +8075,10 @@
|
|||
"offline": false,
|
||||
"options": [
|
||||
"-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": {
|
||||
"command": "hw status",
|
||||
|
@ -8889,7 +8926,7 @@
|
|||
},
|
||||
"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": [
|
||||
"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 A090A0A02080 --rnd 3FFE1FB6CC513F --frn F355F1A0 --grn 609D60 (research paper key)"
|
||||
],
|
||||
"offline": false,
|
||||
"offline": true,
|
||||
"options": [
|
||||
"-h, --help This help",
|
||||
"--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>"
|
||||
},
|
||||
"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": {
|
||||
"command": "lf em 4x70 unlock",
|
||||
"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>"
|
||||
},
|
||||
"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": {
|
||||
"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",
|
||||
|
@ -12529,8 +12566,8 @@
|
|||
}
|
||||
},
|
||||
"metadata": {
|
||||
"commands_extracted": 723,
|
||||
"commands_extracted": 725,
|
||||
"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 tamper `|N |`NTAG 213TT - Configure the tamper feature`
|
||||
|`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 eload `|N |`Upload file into emulator memory`
|
||||
|`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 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
|
||||
|
||||
{ Fuji/Xerox cartridge RFIDs... }
|
||||
|
@ -960,8 +971,8 @@ Check column "offline" for their availability.
|
|||
|`lf em 4x70 write `|N |`Write EM4x70`
|
||||
|`lf em 4x70 unlock `|N |`Unlock EM4x70 for writing`
|
||||
|`lf em 4x70 auth `|N |`Authenticate EM4x70`
|
||||
|`lf em 4x70 setpin `|N |`Write new PIN`
|
||||
|`lf em 4x70 setkey `|N |`Write new key`
|
||||
|`lf em 4x70 setpin `|N |`Write PIN`
|
||||
|`lf em 4x70 setkey `|N |`Write key`
|
||||
|`lf em 4x70 recover `|Y |`Recover remaining key from partial key`
|
||||
|`lf em 4x70 autorecover `|N |`Recover entire key from writable tag`
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue