Sync crapto1 files with official crapto1 3.2

This commit is contained in:
romuald@libnfc.org
2012-09-26 19:14:01 +00:00
parent 7fe60310b0
commit bb64564cad
2 changed files with 487 additions and 491 deletions

View File

@@ -57,8 +57,7 @@ static void quicksort(uint32_t* const start, uint32_t* const stop)
/** binsearch /** binsearch
* Binary search for the first occurence of *stop's MSB in sorted [start,stop] * Binary search for the first occurence of *stop's MSB in sorted [start,stop]
*/ */
static inline uint32_t* static inline uint32_t* binsearch(uint32_t *start, uint32_t *stop)
binsearch(uint32_t *start, uint32_t *stop)
{ {
uint32_t mid, val = *stop & 0xff000000; uint32_t mid, val = *stop & 0xff000000;
while(start != stop) while(start != stop)
@@ -108,8 +107,7 @@ extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in
/** extend_table_simple /** extend_table_simple
* using a bit of the keystream extend the table of possible lfsr states * using a bit of the keystream extend the table of possible lfsr states
*/ */
static inline void static inline void extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)
extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)
{ {
for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1) for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)
if(filter(*tbl) ^ filter(*tbl | 1)) { if(filter(*tbl) ^ filter(*tbl | 1)) {
@@ -143,13 +141,16 @@ recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
} }
for(i = 0; i < 4 && rem--; i++) { for(i = 0; i < 4 && rem--; i++) {
extend_table(o_head, &o_tail, (oks >>= 1) & 1, oks >>= 1;
LF_POLY_EVEN << 1 | 1, LF_POLY_ODD << 1, 0); eks >>= 1;
in >>= 2;
extend_table(o_head, &o_tail, oks & 1, LF_POLY_EVEN << 1 | 1,
LF_POLY_ODD << 1, 0);
if(o_head > o_tail) if(o_head > o_tail)
return sl; return sl;
extend_table(e_head, &e_tail, (eks >>= 1) & 1, extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD,
LF_POLY_ODD, LF_POLY_EVEN << 1 | 1, (in >>= 2) & 3); LF_POLY_EVEN << 1 | 1, in & 3);
if(e_head > e_tail) if(e_head > e_tail)
return sl; return sl;
} }
@@ -186,13 +187,16 @@ struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)
for(i = 31; i >= 0; i -= 2) for(i = 31; i >= 0; i -= 2)
oks = oks << 1 | BEBIT(ks2, i); oks = oks << 1 | BEBIT(ks2, i);
for(i = 30; i >= 0; i -= 2) for(i = 30; i >= 0; i -= 2)
eks = eks << 1 | BEBIT(ks2, i); eks = eks << 1 | BEBIT(ks2, i);
odd_head = odd_tail = malloc(sizeof(uint32_t) << 21); odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);
even_head = even_tail = malloc(sizeof(uint32_t) << 21); even_head = even_tail = malloc(sizeof(uint32_t) << 21);
statelist = malloc(sizeof(struct Crypto1State) << 18); statelist = malloc(sizeof(struct Crypto1State) << 18);
if(!odd_tail-- || !even_tail-- || !statelist) if(!odd_tail-- || !even_tail-- || !statelist) {
free(statelist);
statelist = 0;
goto out; goto out;
}
statelist->odd = statelist->even = 0; statelist->odd = statelist->even = 0;
@@ -255,12 +259,12 @@ struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3)
sl->odd = sl->even = 0; sl->odd = sl->even = 0;
for(i = 30; i >= 0; i -= 2) { for(i = 30; i >= 0; i -= 2) {
oks[i >> 1] = BIT(ks2, i ^ 24); oks[i >> 1] = BEBIT(ks2, i);
oks[16 + (i >> 1)] = BIT(ks3, i ^ 24); oks[16 + (i >> 1)] = BEBIT(ks3, i);
} }
for(i = 31; i >= 0; i -= 2) { for(i = 31; i >= 0; i -= 2) {
eks[i >> 1] = BIT(ks2, i ^ 24); eks[i >> 1] = BEBIT(ks2, i);
eks[16 + (i >> 1)] = BIT(ks3, i ^ 24); eks[16 + (i >> 1)] = BEBIT(ks3, i);
} }
for(i = 0xfffff; i >= 0; --i) { for(i = 0xfffff; i >= 0; --i) {
@@ -333,8 +337,7 @@ uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb)
*/ */
uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb) uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb)
{ {
int i; int i, ret = 0;
uint8_t ret = 0;
for (i = 7; i >= 0; --i) for (i = 7; i >= 0; --i)
ret |= lfsr_rollback_bit(s, BIT(in, i), fb) << i; ret |= lfsr_rollback_bit(s, BIT(in, i), fb) << i;
return ret; return ret;
@@ -382,30 +385,28 @@ static uint32_t fastfwd[2][8] = {
* Described in the "dark side" paper. It returns an -1 terminated array * Described in the "dark side" paper. It returns an -1 terminated array
* of possible partial(21 bit) secret state. * of possible partial(21 bit) secret state.
* The required keystream(ks) needs to contain the keystream that was used to * The required keystream(ks) needs to contain the keystream that was used to
* encrypt the NACK which is observed when varying only the 4 last bits of Nr * encrypt the NACK which is observed when varying only the 3 last bits of Nr
* only correct iff [NR_3] ^ NR_3 does not depend on Nr_3 * only correct iff [NR_3] ^ NR_3 does not depend on Nr_3
*/ */
uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd) uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd)
{ {
uint32_t c, entry, *candidates = malloc(4 << 21); uint32_t c, entry, *candidates = malloc(4 << 10);
int i, size = (1 << 21) - 1; int i, size = 0, good;
if(!candidates) if(!candidates)
return 0; return 0;
for(i = 0; i <= size; ++i) for(i = 0; i < 1 << 21; ++i) {
candidates[i] = i; for(c = 0, good = 1; good && c < 8; ++c) {
entry = i ^ fastfwd[isodd][c];
for(c = 0; c < 8; ++c) good &= (BIT(ks[c], isodd) == filter(entry >> 1));
for(i = 0;i <= size; ++i) { good &= (BIT(ks[c], isodd + 2) == filter(entry));
entry = candidates[i] ^ fastfwd[isodd][c];
if(filter(entry >> 1) != BIT(ks[c], isodd) ||
filter(entry) != BIT(ks[c], isodd + 2))
candidates[i--] = candidates[size--];
} }
if(good)
candidates[size++] = i;
}
candidates[size + 1] = -1; candidates[size] = -1;
return candidates; return candidates;
} }
@@ -446,12 +447,6 @@ check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8],
/** lfsr_common_prefix /** lfsr_common_prefix
* Implentation of the common prefix attack. * Implentation of the common prefix attack.
* Requires the 29 bit constant prefix used as reader nonce (pfx)
* The reader response used (rr)
* The keystream used to encrypt the observed NACK's (ks)
* The parity bits (par)
* It returns a zero terminated list of possible cipher states after the
* tag nonce was fed in
*/ */
struct Crypto1State* struct Crypto1State*
lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8]) lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8])
@@ -464,10 +459,9 @@ lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8])
s = statelist = malloc((sizeof *statelist) << 20); s = statelist = malloc((sizeof *statelist) << 20);
if(!s || !odd || !even) { if(!s || !odd || !even) {
free(odd);
free(even);
free(statelist); free(statelist);
return 0; statelist = 0;
goto out;
} }
for(o = odd; *o + 1; ++o) for(o = odd; *o + 1; ++o)
@@ -479,9 +473,8 @@ lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8])
} }
s->odd = s->even = 0; s->odd = s->even = 0;
out:
free(odd); free(odd);
free(even); free(even);
return statelist; return statelist;
} }

View File

@@ -15,7 +15,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, US$ MA 02110-1301, US$
Copyright (C) 2008-2009 bla <blapost@gmail.com> Copyright (C) 2008-2008 bla <blapost@gmail.com>
*/ */
#ifndef CRAPTO1_INCLUDED #ifndef CRAPTO1_INCLUDED
#define CRAPTO1_INCLUDED #define CRAPTO1_INCLUDED
@@ -35,8 +35,13 @@ uint32_t prng_successor(uint32_t x, uint32_t n);
struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in); struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in);
struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3); struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3);
uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd);
struct Crypto1State*
lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8]);
void lfsr_rollback(struct Crypto1State* s, uint32_t in, int fb); uint8_t lfsr_rollback_bit(struct Crypto1State* s, uint32_t in, int fb);
uint8_t lfsr_rollback_byte(struct Crypto1State* s, uint32_t in, int fb);
uint32_t lfsr_rollback_word(struct Crypto1State* s, uint32_t in, int fb);
int nonce_distance(uint32_t from, uint32_t to); int nonce_distance(uint32_t from, uint32_t to);
#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\ #define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\
uint32_t __n = 0,__M = 0, N = 0;\ uint32_t __n = 0,__M = 0, N = 0;\
@@ -61,15 +66,13 @@ static inline int parity(uint32_t x)
x ^= x >> 4; x ^= x >> 4;
return BIT(0x6996, x & 0xf); return BIT(0x6996, x & 0xf);
#else #else
__asm__( asm( "movl %1, %%eax\n"
"movl %1, %%eax\n"
"mov %%ax, %%cx\n" "mov %%ax, %%cx\n"
"shrl $0x10, %%eax\n" "shrl $0x10, %%eax\n"
"xor %%ax, %%cx\n" "xor %%ax, %%cx\n"
"xor %%ch, %%cl\n" "xor %%ch, %%cl\n"
"setpo %%al\n" "setpo %%al\n"
"movzx %%al, %0\n": "=r"(x) : "r"(x): "eax","ecx" "movzx %%al, %0\n": "=r"(x) : "r"(x): "eax","ecx");
);
return x; return x;
#endif #endif
} }