1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 20:49:49 +04:00
This commit is contained in:
MX
2025-09-09 15:34:19 +03:00
parent ffb8eb7cff
commit 40c6c8b59c
3 changed files with 1269 additions and 1512 deletions

View File

@@ -6,202 +6,185 @@
#include <nfc/helpers/nfc_util.h> #include <nfc/helpers/nfc_util.h>
#include <nfc/protocols/mf_classic/mf_classic.h> #include <nfc/protocols/mf_classic/mf_classic.h>
#define LF_POLY_ODD (0x29CE5C) #define LF_POLY_ODD (0x29CE5C)
#define LF_POLY_EVEN (0x870804) #define LF_POLY_EVEN (0x870804)
#define BIT(x, n) ((x) >> (n) & 1) #define BIT(x, n) ((x) >> (n) & 1)
#define BEBIT(x, n) BIT(x, (n) ^ 24) #define BEBIT(x, n) BIT(x, (n) ^ 24)
#define SWAPENDIAN(x) \ #define SWAPENDIAN(x) \
((x) = ((x) >> 8 & 0xff00ff) | ((x) & 0xff00ff) << 8, (x) = (x) >> 16 | (x) << 16) ((x) = ((x) >> 8 & 0xff00ff) | ((x) & 0xff00ff) << 8, (x) = (x) >> 16 | (x) << 16)
static inline uint32_t prng_successor(uint32_t x, uint32_t n); static inline uint32_t prng_successor(uint32_t x, uint32_t n);
static inline int filter(uint32_t const x); static inline int filter(uint32_t const x);
static inline uint8_t evenparity32(uint32_t x); static inline uint8_t evenparity32(uint32_t x);
static inline void update_contribution(unsigned int data[], int item, int mask1, int mask2); static inline void update_contribution(unsigned int data[], int item, int mask1, int mask2);
void crypto1_get_lfsr(struct Crypto1State *state, MfClassicKey *lfsr); void crypto1_get_lfsr(struct Crypto1State* state, MfClassicKey* lfsr);
static inline uint32_t crypt_word(struct Crypto1State *s); static inline uint32_t crypt_word(struct Crypto1State* s);
static inline void crypt_word_noret(struct Crypto1State *s, uint32_t in, int x); static inline void crypt_word_noret(struct Crypto1State* s, uint32_t in, int x);
static inline uint32_t crypt_word_ret(struct Crypto1State *s, uint32_t in, int x); static inline uint32_t crypt_word_ret(struct Crypto1State* s, uint32_t in, int x);
static uint32_t crypt_word_par( static uint32_t crypt_word_par(
struct Crypto1State *s, struct Crypto1State* s,
uint32_t in, uint32_t in,
int is_encrypted, int is_encrypted,
uint32_t nt_plain, uint32_t nt_plain,
uint8_t *parity_keystream_bits); uint8_t* parity_keystream_bits);
static inline void rollback_word_noret(struct Crypto1State *s, uint32_t in, int x); static inline void rollback_word_noret(struct Crypto1State* s, uint32_t in, int x);
static inline uint8_t napi_lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb); static inline uint8_t napi_lfsr_rollback_bit(struct Crypto1State* s, uint32_t in, int fb);
static inline uint32_t napi_lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb); static inline uint32_t napi_lfsr_rollback_word(struct Crypto1State* s, uint32_t in, int fb);
static const uint8_t lookup1[256] = { static const uint8_t lookup1[256] = {
0, 0, 16, 16, 0, 16, 0, 0, 0, 16, 0, 0, 16, 16, 16, 16, 0, 0, 16, 16, 0, 16, 0, 0, 0, 0, 16, 16, 0, 16, 0, 0, 0, 16, 0, 0, 16, 16, 16, 16, 0, 0, 16, 16, 0, 16, 0, 0,
0, 16, 0, 0, 16, 16, 16, 16, 0, 0, 16, 16, 0, 16, 0, 0, 0, 16, 0, 0, 16, 16, 16, 16, 0, 16, 0, 0, 16, 16, 16, 16, 0, 0, 16, 16, 0, 16, 0, 0, 0, 16, 0, 0, 16, 16, 16, 16,
8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24, 8, 8, 24, 24, 8, 24, 8, 8, 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24, 8, 8, 24, 24, 8, 24, 8, 8,
8, 24, 8, 8, 24, 24, 24, 24, 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24, 8, 24, 8, 8, 24, 24, 24, 24, 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24,
0, 0, 16, 16, 0, 16, 0, 0, 0, 16, 0, 0, 16, 16, 16, 16, 0, 0, 16, 16, 0, 16, 0, 0, 0, 0, 16, 16, 0, 16, 0, 0, 0, 16, 0, 0, 16, 16, 16, 16, 0, 0, 16, 16, 0, 16, 0, 0,
0, 16, 0, 0, 16, 16, 16, 16, 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24, 0, 16, 0, 0, 16, 16, 16, 16, 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24,
0, 0, 16, 16, 0, 16, 0, 0, 0, 16, 0, 0, 16, 16, 16, 16, 0, 0, 16, 16, 0, 16, 0, 0, 0, 0, 16, 16, 0, 16, 0, 0, 0, 16, 0, 0, 16, 16, 16, 16, 0, 0, 16, 16, 0, 16, 0, 0,
0, 16, 0, 0, 16, 16, 16, 16, 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24, 0, 16, 0, 0, 16, 16, 16, 16, 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24,
8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24, 0, 0, 16, 16, 0, 16, 0, 0, 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24, 0, 0, 16, 16, 0, 16, 0, 0,
0, 16, 0, 0, 16, 16, 16, 16, 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24, 0, 16, 0, 0, 16, 16, 16, 16, 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24,
8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24}; 8, 8, 24, 24, 8, 24, 8, 8, 8, 24, 8, 8, 24, 24, 24, 24};
static const uint8_t lookup2[256] = { static const uint8_t lookup2[256] = {
0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4,
4, 4, 4, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 2, 2, 6, 6, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 4, 4, 4, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 2, 2, 6, 6, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6,
2, 2, 6, 6, 6, 6, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 6, 6, 6, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 2, 2, 6, 6, 2, 6, 2,
2, 2, 6, 2, 2, 6, 6, 6, 6, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 0, 0, 4, 4, 2, 2, 6, 2, 2, 6, 6, 6, 6, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 0, 0, 4, 4,
0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 2, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 2,
2, 6, 6, 2, 6, 2, 2, 2, 6, 2, 2, 6, 6, 6, 6, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 2, 6, 6, 2, 6, 2, 2, 2, 6, 2, 2, 6, 6, 6, 6, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4,
4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 2, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4, 4, 4, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 2,
2, 6, 6, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 2, 2, 6, 6, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 6, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 2, 2, 6, 6, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2,
2, 6, 2, 2, 6, 6, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 2, 2, 6, 6, 6, 6}; 2, 6, 2, 2, 6, 6, 6, 6, 2, 2, 6, 6, 2, 6, 2, 2, 2, 6, 2, 2, 6, 6, 6, 6};
static inline int filter(uint32_t const x) static inline int filter(uint32_t const x) {
{ uint32_t f;
uint32_t f; f = lookup1[x & 0xff] | lookup2[(x >> 8) & 0xff];
f = lookup1[x & 0xff] | lookup2[(x >> 8) & 0xff]; f |= 0x0d938 >> (x >> 16 & 0xf) & 1;
f |= 0x0d938 >> (x >> 16 & 0xf) & 1; return BIT(0xEC57E80A, f);
return BIT(0xEC57E80A, f);
} }
#ifdef __ARM_ARCH_7EM__ #ifdef __ARM_ARCH_7EM__
static inline uint8_t evenparity32(uint32_t x) static inline uint8_t evenparity32(uint32_t x) {
{ // fold 32 bits -> 16 -> 8 -> 4
// fold 32 bits -> 16 -> 8 -> 4 x ^= x >> 16;
x ^= x >> 16; x ^= x >> 8;
x ^= x >> 8; x ^= x >> 4;
x ^= x >> 4; // magic 0x6996: bit i tells you parity of i (0 ≤ i < 16)
// magic 0x6996: bit i tells you parity of i (0 ≤ i < 16) return (uint8_t)((0x6996u >> (x & 0xF)) & 1);
return (uint8_t)((0x6996u >> (x & 0xF)) & 1);
} }
#endif #endif
static inline void update_contribution(unsigned int data[], int item, int mask1, int mask2) static inline void update_contribution(unsigned int data[], int item, int mask1, int mask2) {
{ int p = data[item] >> 25;
int p = data[item] >> 25; p = p << 1 | evenparity32(data[item] & mask1);
p = p << 1 | evenparity32(data[item] & mask1); p = p << 1 | evenparity32(data[item] & mask2);
p = p << 1 | evenparity32(data[item] & mask2); data[item] = p << 24 | (data[item] & 0xffffff);
data[item] = p << 24 | (data[item] & 0xffffff);
} }
static inline uint32_t crypt_word(struct Crypto1State *s) static inline uint32_t crypt_word(struct Crypto1State* s) {
{ // "in" and "x" are always 0 (last iteration)
// "in" and "x" are always 0 (last iteration) uint32_t res_ret = 0;
uint32_t res_ret = 0; uint32_t feedin, t;
uint32_t feedin, t; for(int i = 0; i <= 31; i++) {
for (int i = 0; i <= 31; i++) res_ret |= (filter(s->odd) << (24 ^ i)); //-V629
{ feedin = LF_POLY_EVEN & s->even;
res_ret |= (filter(s->odd) << (24 ^ i)); //-V629 feedin ^= LF_POLY_ODD & s->odd;
feedin = LF_POLY_EVEN & s->even; s->even = s->even << 1 | (evenparity32(feedin));
feedin ^= LF_POLY_ODD & s->odd; t = s->odd, s->odd = s->even, s->even = t;
s->even = s->even << 1 | (evenparity32(feedin)); }
t = s->odd, s->odd = s->even, s->even = t; return res_ret;
}
return res_ret;
} }
static inline void crypt_word_noret(struct Crypto1State *s, uint32_t in, int x) static inline void crypt_word_noret(struct Crypto1State* s, uint32_t in, int x) {
{ uint8_t ret;
uint8_t ret; uint32_t feedin, t, next_in;
uint32_t feedin, t, next_in; for(int i = 0; i <= 31; i++) {
for (int i = 0; i <= 31; i++) next_in = BEBIT(in, i);
{ ret = filter(s->odd);
next_in = BEBIT(in, i); feedin = ret & (!!x);
ret = filter(s->odd); feedin ^= LF_POLY_EVEN & s->even;
feedin = ret & (!!x); feedin ^= LF_POLY_ODD & s->odd;
feedin ^= LF_POLY_EVEN & s->even; feedin ^= !!next_in;
feedin ^= LF_POLY_ODD & s->odd; s->even = s->even << 1 | (evenparity32(feedin));
feedin ^= !!next_in; t = s->odd, s->odd = s->even, s->even = t;
s->even = s->even << 1 | (evenparity32(feedin)); }
t = s->odd, s->odd = s->even, s->even = t; return;
}
return;
} }
static inline uint32_t crypt_word_ret(struct Crypto1State *s, uint32_t in, int x) static inline uint32_t crypt_word_ret(struct Crypto1State* s, uint32_t in, int x) {
{ uint32_t ret = 0;
uint32_t ret = 0; uint32_t feedin, t, next_in;
uint32_t feedin, t, next_in; uint8_t next_ret;
uint8_t next_ret; for(int i = 0; i <= 31; i++) {
for (int i = 0; i <= 31; i++) next_in = BEBIT(in, i);
{ next_ret = filter(s->odd);
next_in = BEBIT(in, i); feedin = next_ret & (!!x);
next_ret = filter(s->odd); feedin ^= LF_POLY_EVEN & s->even;
feedin = next_ret & (!!x); feedin ^= LF_POLY_ODD & s->odd;
feedin ^= LF_POLY_EVEN & s->even; feedin ^= !!next_in;
feedin ^= LF_POLY_ODD & s->odd; s->even = s->even << 1 | (evenparity32(feedin));
feedin ^= !!next_in; t = s->odd, s->odd = s->even, s->even = t;
s->even = s->even << 1 | (evenparity32(feedin)); ret |= next_ret << (24 ^ i);
t = s->odd, s->odd = s->even, s->even = t; }
ret |= next_ret << (24 ^ i); return ret;
}
return ret;
} }
static uint8_t get_nth_byte(uint32_t value, int n) static uint8_t get_nth_byte(uint32_t value, int n) {
{ if(n < 0 || n > 3) {
if (n < 0 || n > 3) // Handle invalid input
{ return 0;
// Handle invalid input }
return 0; return (value >> (8 * (3 - n))) & 0xFF;
}
return (value >> (8 * (3 - n))) & 0xFF;
} }
static uint8_t crypt_bit(struct Crypto1State *s, uint8_t in, int is_encrypted) static uint8_t crypt_bit(struct Crypto1State* s, uint8_t in, int is_encrypted) {
{ uint32_t feedin, t;
uint32_t feedin, t; uint8_t ret = filter(s->odd);
uint8_t ret = filter(s->odd); feedin = ret & !!is_encrypted;
feedin = ret & !!is_encrypted; feedin ^= !!in;
feedin ^= !!in; feedin ^= LF_POLY_ODD & s->odd;
feedin ^= LF_POLY_ODD & s->odd; feedin ^= LF_POLY_EVEN & s->even;
feedin ^= LF_POLY_EVEN & s->even; s->even = s->even << 1 | evenparity32(feedin);
s->even = s->even << 1 | evenparity32(feedin); t = s->odd, s->odd = s->even, s->even = t;
t = s->odd, s->odd = s->even, s->even = t; return ret;
return ret;
} }
static inline uint32_t crypt_word_par( static inline uint32_t crypt_word_par(
struct Crypto1State *s, struct Crypto1State* s,
uint32_t in, uint32_t in,
int is_encrypted, int is_encrypted,
uint32_t nt_plain, uint32_t nt_plain,
uint8_t *parity_keystream_bits) uint8_t* parity_keystream_bits) {
{ uint32_t ret = 0;
uint32_t ret = 0; *parity_keystream_bits = 0; // Reset parity keystream bits
*parity_keystream_bits = 0; // Reset parity keystream bits
for (int i = 0; i < 32; i++) for(int i = 0; i < 32; i++) {
{ uint8_t bit = crypt_bit(s, BEBIT(in, i), is_encrypted);
uint8_t bit = crypt_bit(s, BEBIT(in, i), is_encrypted); ret |= bit << (24 ^ i);
ret |= bit << (24 ^ i); // Save keystream parity bit
// Save keystream parity bit if((i + 1) % 8 == 0) {
if ((i + 1) % 8 == 0) *parity_keystream_bits |=
{ (filter(s->odd) ^ nfc_util_even_parity8(get_nth_byte(nt_plain, i / 8)))
*parity_keystream_bits |= << (3 - (i / 8));
(filter(s->odd) ^ nfc_util_even_parity8(get_nth_byte(nt_plain, i / 8))) }
<< (3 - (i / 8)); }
} return ret;
}
return ret;
} }
static inline void rollback_word_noret(struct Crypto1State *s, uint32_t in, int x) static inline void rollback_word_noret(struct Crypto1State* s, uint32_t in, int x) {
{ uint8_t ret;
uint8_t ret; uint32_t feedin, t, next_in;
uint32_t feedin, t, next_in; for(int i = 31; i >= 0; i--) {
for (int i = 31; i >= 0; i--) next_in = BEBIT(in, i);
{ s->odd &= 0xffffff;
next_in = BEBIT(in, i); t = s->odd, s->odd = s->even, s->even = t;
s->odd &= 0xffffff; ret = filter(s->odd);
t = s->odd, s->odd = s->even, s->even = t; feedin = ret & (!!x);
ret = filter(s->odd); feedin ^= s->even & 1;
feedin = ret & (!!x); feedin ^= LF_POLY_EVEN & (s->even >>= 1);
feedin ^= s->even & 1; feedin ^= LF_POLY_ODD & s->odd;
feedin ^= LF_POLY_EVEN & (s->even >>= 1); feedin ^= !!next_in;
feedin ^= LF_POLY_ODD & s->odd; s->even |= (evenparity32(feedin)) << 23;
feedin ^= !!next_in; }
s->even |= (evenparity32(feedin)) << 23; return;
}
return;
} }
// TODO: // TODO:
@@ -227,39 +210,36 @@ uint32_t rollback_word(struct Crypto1State *s, uint32_t in, int x) {
} }
*/ */
uint8_t napi_lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb) uint8_t napi_lfsr_rollback_bit(struct Crypto1State* s, uint32_t in, int fb) {
{ int out;
int out; uint8_t ret;
uint8_t ret; uint32_t t;
uint32_t t; s->odd &= 0xffffff;
s->odd &= 0xffffff; t = s->odd, s->odd = s->even, s->even = t;
t = s->odd, s->odd = s->even, s->even = t;
out = s->even & 1; out = s->even & 1;
out ^= LF_POLY_EVEN & (s->even >>= 1); out ^= LF_POLY_EVEN & (s->even >>= 1);
out ^= LF_POLY_ODD & s->odd; out ^= LF_POLY_ODD & s->odd;
out ^= !!in; out ^= !!in;
out ^= (ret = filter(s->odd)) & !!fb; out ^= (ret = filter(s->odd)) & !!fb;
s->even |= evenparity32(out) << 23; s->even |= evenparity32(out) << 23;
return ret; return ret;
} }
uint32_t napi_lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb) uint32_t napi_lfsr_rollback_word(struct Crypto1State* s, uint32_t in, int fb) {
{ int i;
int i; uint32_t ret = 0;
uint32_t ret = 0; for(i = 31; i >= 0; --i)
for (i = 31; i >= 0; --i) ret |= napi_lfsr_rollback_bit(s, BEBIT(in, i), fb) << (i ^ 24);
ret |= napi_lfsr_rollback_bit(s, BEBIT(in, i), fb) << (i ^ 24); return ret;
return ret;
} }
static inline uint32_t prng_successor(uint32_t x, uint32_t n) static inline uint32_t prng_successor(uint32_t x, uint32_t n) {
{ SWAPENDIAN(x);
SWAPENDIAN(x); while(n--)
while (n--) x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31; return SWAPENDIAN(x);
return SWAPENDIAN(x);
} }
#endif // CRYPTO1_H #endif // CRYPTO1_H

File diff suppressed because it is too large Load Diff

View File

@@ -9,115 +9,103 @@
#include <toolbox/stream/buffered_file_stream.h> #include <toolbox/stream/buffered_file_stream.h>
#include <nfc/protocols/mf_classic/mf_classic.h> #include <nfc/protocols/mf_classic/mf_classic.h>
struct Crypto1State struct Crypto1State {
{ uint32_t odd, even;
uint32_t odd, even;
}; };
struct Msb struct Msb {
{ int tail;
int tail; uint32_t states[768];
uint32_t states[768];
}; };
typedef enum typedef enum {
{ MissingNonces,
MissingNonces, ZeroNonces,
ZeroNonces, InsufficientRAM,
InsufficientRAM,
} MFKeyError; } MFKeyError;
typedef enum typedef enum {
{ Ready,
Ready, Initializing,
Initializing, DictionaryAttack,
DictionaryAttack, MFKeyAttack,
MFKeyAttack, Complete,
Complete, Error,
Error, Help,
Help,
} MFKeyState; } MFKeyState;
// TODO: Can we eliminate any of the members of this struct? // TODO: Can we eliminate any of the members of this struct?
typedef struct typedef struct {
{ FuriMutex* mutex;
FuriMutex *mutex; MFKeyError err;
MFKeyError err; MFKeyState mfkey_state;
MFKeyState mfkey_state; int cracked;
int cracked; int unique_cracked;
int unique_cracked; int num_completed;
int num_completed; int num_candidates;
int num_candidates; int total;
int total; int dict_count;
int dict_count; int search;
int search; int eta_timestamp;
int eta_timestamp; int eta_total;
int eta_total; int eta_round;
int eta_round; bool mfkey32_present;
bool mfkey32_present; bool nested_present;
bool nested_present; bool close_thread_please;
bool close_thread_please; FuriThread* mfkeythread;
FuriThread *mfkeythread; KeysDict* cuid_dict;
KeysDict *cuid_dict; MfClassicKey* key_buffer;
MfClassicKey *key_buffer; size_t key_buffer_size;
size_t key_buffer_size; size_t key_buffer_count;
size_t key_buffer_count;
} ProgramState; } ProgramState;
typedef enum typedef enum {
{ mfkey32,
mfkey32, static_nested,
static_nested, static_encrypted
static_encrypted
} AttackType; } AttackType;
typedef struct typedef struct {
{ AttackType attack;
AttackType attack; MfClassicKey key; // key
MfClassicKey key; // key uint32_t uid; // serial number
uint32_t uid; // serial number uint32_t nt0; // tag challenge first
uint32_t nt0; // tag challenge first uint32_t nt1; // tag challenge second
uint32_t nt1; // tag challenge second uint32_t uid_xor_nt0; // uid ^ nt0
uint32_t uid_xor_nt0; // uid ^ nt0 uint32_t uid_xor_nt1; // uid ^ nt1
uint32_t uid_xor_nt1; // uid ^ nt1 union {
union // Mfkey32
{ struct {
// Mfkey32 uint32_t p64; // 64th successor of nt0
struct uint32_t p64b; // 64th successor of nt1
{ uint32_t nr0_enc; // first encrypted reader challenge
uint32_t p64; // 64th successor of nt0 uint32_t ar0_enc; // first encrypted reader response
uint32_t p64b; // 64th successor of nt1 uint32_t nr1_enc; // second encrypted reader challenge
uint32_t nr0_enc; // first encrypted reader challenge uint32_t ar1_enc; // second encrypted reader response
uint32_t ar0_enc; // first encrypted reader response };
uint32_t nr1_enc; // second encrypted reader challenge // Nested
uint32_t ar1_enc; // second encrypted reader response struct {
}; uint32_t ks1_1_enc; // first encrypted keystream
// Nested uint32_t ks1_2_enc; // second encrypted keystream
struct char par_1_str[5]; // first parity bits (string representation)
{ char par_2_str[5]; // second parity bits (string representation)
uint32_t ks1_1_enc; // first encrypted keystream uint8_t par_1; // first parity bits
uint32_t ks1_2_enc; // second encrypted keystream uint8_t par_2; // second parity bits
char par_1_str[5]; // first parity bits (string representation) };
char par_2_str[5]; // second parity bits (string representation) };
uint8_t par_1; // first parity bits
uint8_t par_2; // second parity bits
};
};
} MfClassicNonce; } MfClassicNonce;
typedef struct typedef struct {
{ Stream* stream;
Stream *stream; uint32_t total_nonces;
uint32_t total_nonces; MfClassicNonce* remaining_nonce_array;
MfClassicNonce *remaining_nonce_array; size_t remaining_nonces;
size_t remaining_nonces;
} MfClassicNonceArray; } MfClassicNonceArray;
struct KeysDict struct KeysDict {
{ Stream* stream;
Stream *stream; size_t key_size;
size_t key_size; size_t key_size_symbols;
size_t key_size_symbols; size_t total_keys;
size_t total_keys;
}; };
#endif // MFKEY_H #endif // MFKEY_H