]> cvs.zerfleddert.de Git - proxmark3-svn/blame - client/nonce2key/crapto1.c
ADD: added @marshmellow42 's print statement for "lf viking clone".
[proxmark3-svn] / client / nonce2key / crapto1.c
CommitLineData
f89c7050
M
1/* crapto1.c\r
2\r
3 This program is free software; you can redistribute it and/or\r
4 modify it under the terms of the GNU General Public License\r
5 as published by the Free Software Foundation; either version 2\r
6 of the License, or (at your option) any later version.\r
7\r
8 This program is distributed in the hope that it will be useful,\r
9 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
11 GNU General Public License for more details.\r
12\r
13 You should have received a copy of the GNU General Public License\r
14 along with this program; if not, write to the Free Software\r
15 Foundation, Inc., 51 Franklin Street, Fifth Floor,\r
16 Boston, MA 02110-1301, US$\r
17\r
a0f33b66 18 Copyright (C) 2008-2014 bla <blapost@gmail.com>\r
f89c7050
M
19*/\r
20#include "crapto1.h"\r
21#include <stdlib.h>\r
22\r
23#if !defined LOWMEM && defined __GNUC__\r
a0f33b66 24static uint8_t filterlut[1 << 20];\r
f89c7050
M
25static void __attribute__((constructor)) fill_lut()\r
26{\r
66afab80 27 uint32_t i;\r
28 for(i = 0; i < 1 << 20; ++i)\r
29 filterlut[i] = filter(i);\r
f89c7050 30}\r
a0f33b66 31#define filter(x) (filterlut[(x) & 0xfffff])\r
f89c7050
M
32#endif\r
33\r
66afab80 34\r
35\r
36typedef struct bucket {\r
37 uint32_t *head;\r
38 uint32_t *bp;\r
39} bucket_t;\r
40\r
41typedef bucket_t bucket_array_t[2][0x100];\r
42\r
43typedef struct bucket_info {\r
44 struct {\r
45 uint32_t *head, *tail;\r
46 } bucket_info[2][0x100];\r
47 uint32_t numbuckets;\r
48 } bucket_info_t;\r
49\r
50\r
51static void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop,\r
52 uint32_t* const ostart, uint32_t* const ostop,\r
53 bucket_info_t *bucket_info, bucket_array_t bucket)\r
9492e0b0 54{\r
66afab80 55 uint32_t *p1, *p2;\r
56 uint32_t *start[2];\r
57 uint32_t *stop[2];\r
9cefee6f 58\r
66afab80 59 start[0] = estart;\r
60 stop[0] = estop;\r
61 start[1] = ostart;\r
62 stop[1] = ostop;\r
9492e0b0 63\r
66afab80 64 // init buckets to be empty\r
65 for (uint32_t i = 0; i < 2; i++) {\r
66 for (uint32_t j = 0x00; j <= 0xff; j++) {\r
67 bucket[i][j].bp = bucket[i][j].head;\r
68 }\r
69 }\r
70\r
71 // sort the lists into the buckets based on the MSB (contribution bits)\r
72 for (uint32_t i = 0; i < 2; i++) {\r
73 for (p1 = start[i]; p1 <= stop[i]; p1++) {\r
74 uint32_t bucket_index = (*p1 & 0xff000000) >> 24;\r
75 *(bucket[i][bucket_index].bp++) = *p1;\r
76 }\r
77 }\r
9cefee6f 78\r
9492e0b0 79\r
66afab80 80 // write back intersecting buckets as sorted list.\r
81 // fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets.\r
82 uint32_t nonempty_bucket;\r
83 for (uint32_t i = 0; i < 2; i++) {\r
84 p1 = start[i];\r
85 nonempty_bucket = 0;\r
86 for (uint32_t j = 0x00; j <= 0xff; j++) {\r
87 if (bucket[0][j].bp != bucket[0][j].head && bucket[1][j].bp != bucket[1][j].head) { // non-empty intersecting buckets only\r
88 bucket_info->bucket_info[i][nonempty_bucket].head = p1;\r
89 for (p2 = bucket[i][j].head; p2 < bucket[i][j].bp; *p1++ = *p2++);\r
90 bucket_info->bucket_info[i][nonempty_bucket].tail = p1 - 1;\r
91 nonempty_bucket++;\r
92 }\r
93 }\r
94 bucket_info->numbuckets = nonempty_bucket;\r
95 }\r
a0f33b66 96}\r
66afab80 97\r
f89c7050
M
98/** binsearch\r
99 * Binary search for the first occurence of *stop's MSB in sorted [start,stop]\r
100 */\r
a0f33b66 101static inline uint32_t* binsearch(uint32_t *start, uint32_t *stop)\r
f89c7050
M
102{\r
103 uint32_t mid, val = *stop & 0xff000000;\r
104 while(start != stop)\r
105 if(start[mid = (stop - start) >> 1] > val)\r
106 stop = &start[mid];\r
107 else\r
108 start += mid + 1;\r
109\r
110 return start;\r
111}\r
112\r
113/** update_contribution\r
114 * helper, calculates the partial linear feedback contributions and puts in MSB\r
115 */\r
116static inline void\r
117update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2)\r
118{\r
119 uint32_t p = *item >> 25;\r
120\r
121 p = p << 1 | parity(*item & mask1);\r
122 p = p << 1 | parity(*item & mask2);\r
123 *item = p << 24 | (*item & 0xffffff);\r
124}\r
125\r
126/** extend_table\r
127 * using a bit of the keystream extend the table of possible lfsr states\r
128 */\r
129static inline void\r
130extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in)\r
131{\r
132 in <<= 24;\r
a0f33b66 133 for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)\r
134 if(filter(*tbl) ^ filter(*tbl | 1)) {\r
135 *tbl |= filter(*tbl) ^ bit;\r
136 update_contribution(tbl, m1, m2);\r
137 *tbl ^= in;\r
138 } else if(filter(*tbl) == bit) {\r
139 *++*end = tbl[1];\r
140 tbl[1] = tbl[0] | 1;\r
141 update_contribution(tbl, m1, m2);\r
142 *tbl++ ^= in;\r
143 update_contribution(tbl, m1, m2);\r
144 *tbl ^= in;\r
145 } else\r
146 *tbl-- = *(*end)--;\r
f89c7050
M
147}\r
148/** extend_table_simple\r
149 * using a bit of the keystream extend the table of possible lfsr states\r
150 */\r
a0f33b66 151static inline void extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)\r
f89c7050 152{\r
9cefee6f 153 for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)\r
9492e0b0 154 if(filter(*tbl) ^ filter(*tbl | 1)) { // replace\r
f89c7050 155 *tbl |= filter(*tbl) ^ bit;\r
9492e0b0 156 } else if(filter(*tbl) == bit) { // insert\r
f89c7050
M
157 *++*end = *++tbl;\r
158 *tbl = tbl[-1] | 1;\r
9492e0b0 159 } else // drop\r
f89c7050
M
160 *tbl-- = *(*end)--;\r
161}\r
162/** recover\r
163 * recursively narrow down the search space, 4 bits of keystream at a time\r
164 */\r
165static struct Crypto1State*\r
166recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,\r
167 uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem,\r
66afab80 168 struct Crypto1State *sl, uint32_t in, bucket_array_t bucket)\r
f89c7050 169{\r
66afab80 170 uint32_t *o, *e;\r
171 bucket_info_t bucket_info;\r
f89c7050
M
172\r
173 if(rem == -1) {\r
174 for(e = e_head; e <= e_tail; ++e) {\r
175 *e = *e << 1 ^ parity(*e & LF_POLY_EVEN) ^ !!(in & 4);\r
176 for(o = o_head; o <= o_tail; ++o, ++sl) {\r
177 sl->even = *o;\r
178 sl->odd = *e ^ parity(*o & LF_POLY_ODD);\r
a0f33b66 179 sl[1].odd = sl[1].even = 0;\r
f89c7050
M
180 }\r
181 }\r
182 return sl;\r
183 }\r
184\r
66afab80 185 for(uint32_t i = 0; i < 4 && rem--; i++) {\r
a0f33b66 186 oks >>= 1;\r
187 eks >>= 1;\r
188 in >>= 2;\r
189 extend_table(o_head, &o_tail, oks & 1, LF_POLY_EVEN << 1 | 1,\r
190 LF_POLY_ODD << 1, 0);\r
f89c7050
M
191 if(o_head > o_tail)\r
192 return sl;\r
193\r
a0f33b66 194 extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD,\r
195 LF_POLY_EVEN << 1 | 1, in & 3);\r
f89c7050
M
196 if(e_head > e_tail)\r
197 return sl;\r
198 }\r
199\r
66afab80 200 bucket_sort_intersect(e_head, e_tail, o_head, o_tail, &bucket_info, bucket);\r
9cefee6f 201\r
66afab80 202 for (int i = bucket_info.numbuckets - 1; i >= 0; i--) {\r
203 sl = recover(bucket_info.bucket_info[1][i].head, bucket_info.bucket_info[1][i].tail, oks,\r
204 bucket_info.bucket_info[0][i].head, bucket_info.bucket_info[0][i].tail, eks,\r
205 rem, sl, in, bucket);\r
9492e0b0 206 }\r
9cefee6f 207\r
f89c7050
M
208 return sl;\r
209}\r
210/** lfsr_recovery\r
211 * recover the state of the lfsr given 32 bits of the keystream\r
212 * additionally you can use the in parameter to specify the value\r
213 * that was fed into the lfsr at the time the keystream was generated\r
214 */\r
215struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)\r
216{\r
217 struct Crypto1State *statelist;\r
218 uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;\r
219 uint32_t *even_head = 0, *even_tail = 0, eks = 0;\r
220 int i;\r
221\r
9492e0b0 222 // split the keystream into an odd and even part\r
f89c7050
M
223 for(i = 31; i >= 0; i -= 2)\r
224 oks = oks << 1 | BEBIT(ks2, i);\r
225 for(i = 30; i >= 0; i -= 2)\r
226 eks = eks << 1 | BEBIT(ks2, i);\r
227\r
228 odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);\r
229 even_head = even_tail = malloc(sizeof(uint32_t) << 21);\r
230 statelist = malloc(sizeof(struct Crypto1State) << 18);\r
9492e0b0 231 if(!odd_tail-- || !even_tail-- || !statelist) {\r
a0f33b66 232 free(statelist);\r
233 statelist = 0;\r
f89c7050 234 goto out;\r
9492e0b0 235 }\r
f89c7050 236\r
a0f33b66 237 statelist->odd = statelist->even = 0;\r
9492e0b0 238\r
66afab80 239 // allocate memory for out of place bucket_sort\r
240 bucket_array_t bucket;\r
241 for (uint32_t i = 0; i < 2; i++)\r
242 for (uint32_t j = 0; j <= 0xff; j++) {\r
243 bucket[i][j].head = malloc(sizeof(uint32_t)<<14);\r
244 if (!bucket[i][j].head) {\r
245 goto out;\r
246 }\r
247 }\r
248\r
249\r
9492e0b0 250 // initialize statelists: add all possible states which would result into the rightmost 2 bits of the keystream\r
f89c7050
M
251 for(i = 1 << 20; i >= 0; --i) {\r
252 if(filter(i) == (oks & 1))\r
253 *++odd_tail = i;\r
254 if(filter(i) == (eks & 1))\r
255 *++even_tail = i;\r
256 }\r
257\r
9492e0b0 258 // extend the statelists. Look at the next 8 Bits of the keystream (4 Bit each odd and even):\r
f89c7050
M
259 for(i = 0; i < 4; i++) {\r
260 extend_table_simple(odd_head, &odd_tail, (oks >>= 1) & 1);\r
261 extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1);\r
262 }\r
263\r
9492e0b0 264 // the statelists now contain all states which could have generated the last 10 Bits of the keystream.\r
265 // 22 bits to go to recover 32 bits in total. From now on, we need to take the "in"\r
266 // parameter into account.\r
66afab80 267 in = (in >> 16 & 0xff) | (in << 16) | (in & 0xff00); // Byte swapping\r
a0f33b66 268 recover(odd_head, odd_tail, oks,\r
66afab80 269 even_head, even_tail, eks, 11, statelist, in << 1, bucket);\r
270\r
f89c7050
M
271\r
272out:\r
273 free(odd_head);\r
274 free(even_head);\r
66afab80 275 for (uint32_t i = 0; i < 2; i++)\r
276 for (uint32_t j = 0; j <= 0xff; j++)\r
277 free(bucket[i][j].head);\r
278\r
f89c7050
M
279 return statelist;\r
280}\r
281\r
282static const uint32_t S1[] = { 0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214,\r
283 0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83,\r
284 0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA};\r
285static const uint32_t S2[] = { 0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60,\r
286 0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8,\r
287 0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20,\r
288 0x7EC7EE90, 0x7F63F748, 0x79117020};\r
289static const uint32_t T1[] = {\r
290 0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66,\r
291 0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B,\r
292 0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615,\r
293 0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C};\r
294static const uint32_t T2[] = { 0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0,\r
295 0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268,\r
296 0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0,\r
297 0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0,\r
298 0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950,\r
299 0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0};\r
300static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD};\r
301static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0};\r
302/** Reverse 64 bits of keystream into possible cipher states\r
303 * Variation mentioned in the paper. Somewhat optimized version\r
304 */\r
305struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3)\r
306{\r
307 struct Crypto1State *statelist, *sl;\r
308 uint8_t oks[32], eks[32], hi[32];\r
309 uint32_t low = 0, win = 0;\r
310 uint32_t *tail, table[1 << 16];\r
311 int i, j;\r
312\r
313 sl = statelist = malloc(sizeof(struct Crypto1State) << 4);\r
314 if(!sl)\r
315 return 0;\r
316 sl->odd = sl->even = 0;\r
317\r
318 for(i = 30; i >= 0; i -= 2) {\r
a0f33b66 319 oks[i >> 1] = BEBIT(ks2, i);\r
320 oks[16 + (i >> 1)] = BEBIT(ks3, i);\r
f89c7050
M
321 }\r
322 for(i = 31; i >= 0; i -= 2) {\r
a0f33b66 323 eks[i >> 1] = BEBIT(ks2, i);\r
324 eks[16 + (i >> 1)] = BEBIT(ks3, i);\r
f89c7050
M
325 }\r
326\r
327 for(i = 0xfffff; i >= 0; --i) {\r
328 if (filter(i) != oks[0])\r
329 continue;\r
330\r
331 *(tail = table) = i;\r
332 for(j = 1; tail >= table && j < 29; ++j)\r
333 extend_table_simple(table, &tail, oks[j]);\r
334\r
335 if(tail < table)\r
336 continue;\r
337\r
338 for(j = 0; j < 19; ++j)\r
339 low = low << 1 | parity(i & S1[j]);\r
340 for(j = 0; j < 32; ++j)\r
341 hi[j] = parity(i & T1[j]);\r
342\r
343 for(; tail >= table; --tail) {\r
344 for(j = 0; j < 3; ++j) {\r
345 *tail = *tail << 1;\r
346 *tail |= parity((i & C1[j]) ^ (*tail & C2[j]));\r
347 if(filter(*tail) != oks[29 + j])\r
348 goto continue2;\r
349 }\r
350\r
351 for(j = 0; j < 19; ++j)\r
352 win = win << 1 | parity(*tail & S2[j]);\r
353\r
354 win ^= low;\r
355 for(j = 0; j < 32; ++j) {\r
356 win = win << 1 ^ hi[j] ^ parity(*tail & T2[j]);\r
357 if(filter(win) != eks[j])\r
358 goto continue2;\r
359 }\r
360\r
361 *tail = *tail << 1 | parity(LF_POLY_EVEN & *tail);\r
362 sl->odd = *tail ^ parity(LF_POLY_ODD & win);\r
363 sl->even = win;\r
364 ++sl;\r
365 sl->odd = sl->even = 0;\r
366 continue2:;\r
367 }\r
368 }\r
369 return statelist;\r
370}\r
371\r
372/** lfsr_rollback_bit\r
373 * Rollback the shift register in order to get previous states\r
374 */\r
a0f33b66 375uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb)\r
f89c7050
M
376{\r
377 int out;\r
a0f33b66 378 uint8_t ret;\r
379 uint32_t t;\r
f89c7050
M
380\r
381 s->odd &= 0xffffff;\r
a0f33b66 382 t = s->odd, s->odd = s->even, s->even = t;\r
f89c7050
M
383\r
384 out = s->even & 1;\r
385 out ^= LF_POLY_EVEN & (s->even >>= 1);\r
386 out ^= LF_POLY_ODD & s->odd;\r
387 out ^= !!in;\r
a0f33b66 388 out ^= (ret = filter(s->odd)) & !!fb;\r
f89c7050
M
389\r
390 s->even |= parity(out) << 23;\r
a0f33b66 391 return ret;\r
f89c7050
M
392}\r
393/** lfsr_rollback_byte\r
394 * Rollback the shift register in order to get previous states\r
395 */\r
a0f33b66 396uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb)\r
f89c7050 397{\r
a0f33b66 398 /*\r
399 int i, ret = 0;\r
f89c7050 400 for (i = 7; i >= 0; --i)\r
a0f33b66 401 ret |= lfsr_rollback_bit(s, BIT(in, i), fb) << i;\r
738eeccd 402*/\r
403// unfold loop 20160112\r
a0f33b66 404 uint8_t ret = 0;\r
405 ret |= lfsr_rollback_bit(s, BIT(in, 7), fb) << 7;\r
406 ret |= lfsr_rollback_bit(s, BIT(in, 6), fb) << 6;\r
407 ret |= lfsr_rollback_bit(s, BIT(in, 5), fb) << 5;\r
408 ret |= lfsr_rollback_bit(s, BIT(in, 4), fb) << 4;\r
409 ret |= lfsr_rollback_bit(s, BIT(in, 3), fb) << 3;\r
410 ret |= lfsr_rollback_bit(s, BIT(in, 2), fb) << 2;\r
411 ret |= lfsr_rollback_bit(s, BIT(in, 1), fb) << 1;\r
412 ret |= lfsr_rollback_bit(s, BIT(in, 0), fb) << 0;\r
413 return ret;\r
f89c7050
M
414}\r
415/** lfsr_rollback_word\r
416 * Rollback the shift register in order to get previous states\r
417 */\r
a0f33b66 418uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb)\r
f89c7050 419{\r
a0f33b66 420 /*\r
f89c7050 421 int i;\r
a0f33b66 422 uint32_t ret = 0;\r
f89c7050 423 for (i = 31; i >= 0; --i)\r
a0f33b66 424 ret |= lfsr_rollback_bit(s, BEBIT(in, i), fb) << (i ^ 24);\r
738eeccd 425*/\r
426// unfold loop 20160112\r
a0f33b66 427 uint32_t ret = 0;\r
428 ret |= lfsr_rollback_bit(s, BEBIT(in, 31), fb) << (31 ^ 24);\r
429 ret |= lfsr_rollback_bit(s, BEBIT(in, 30), fb) << (30 ^ 24);\r
430 ret |= lfsr_rollback_bit(s, BEBIT(in, 29), fb) << (29 ^ 24);\r
431 ret |= lfsr_rollback_bit(s, BEBIT(in, 28), fb) << (28 ^ 24);\r
432 ret |= lfsr_rollback_bit(s, BEBIT(in, 27), fb) << (27 ^ 24);\r
433 ret |= lfsr_rollback_bit(s, BEBIT(in, 26), fb) << (26 ^ 24);\r
434 ret |= lfsr_rollback_bit(s, BEBIT(in, 25), fb) << (25 ^ 24);\r
435 ret |= lfsr_rollback_bit(s, BEBIT(in, 24), fb) << (24 ^ 24);\r
436\r
437 ret |= lfsr_rollback_bit(s, BEBIT(in, 23), fb) << (23 ^ 24);\r
438 ret |= lfsr_rollback_bit(s, BEBIT(in, 22), fb) << (22 ^ 24);\r
439 ret |= lfsr_rollback_bit(s, BEBIT(in, 21), fb) << (21 ^ 24);\r
440 ret |= lfsr_rollback_bit(s, BEBIT(in, 20), fb) << (20 ^ 24);\r
441 ret |= lfsr_rollback_bit(s, BEBIT(in, 19), fb) << (19 ^ 24);\r
442 ret |= lfsr_rollback_bit(s, BEBIT(in, 18), fb) << (18 ^ 24);\r
443 ret |= lfsr_rollback_bit(s, BEBIT(in, 17), fb) << (17 ^ 24);\r
444 ret |= lfsr_rollback_bit(s, BEBIT(in, 16), fb) << (16 ^ 24);\r
445 \r
446 ret |= lfsr_rollback_bit(s, BEBIT(in, 15), fb) << (15 ^ 24);\r
447 ret |= lfsr_rollback_bit(s, BEBIT(in, 14), fb) << (14 ^ 24);\r
448 ret |= lfsr_rollback_bit(s, BEBIT(in, 13), fb) << (13 ^ 24);\r
449 ret |= lfsr_rollback_bit(s, BEBIT(in, 12), fb) << (12 ^ 24);\r
450 ret |= lfsr_rollback_bit(s, BEBIT(in, 11), fb) << (11 ^ 24);\r
451 ret |= lfsr_rollback_bit(s, BEBIT(in, 10), fb) << (10 ^ 24);\r
452 ret |= lfsr_rollback_bit(s, BEBIT(in, 9), fb) << (9 ^ 24);\r
453 ret |= lfsr_rollback_bit(s, BEBIT(in, 8), fb) << (8 ^ 24);\r
454 \r
455 ret |= lfsr_rollback_bit(s, BEBIT(in, 7), fb) << (7 ^ 24);\r
456 ret |= lfsr_rollback_bit(s, BEBIT(in, 6), fb) << (6 ^ 24);\r
457 ret |= lfsr_rollback_bit(s, BEBIT(in, 5), fb) << (5 ^ 24);\r
458 ret |= lfsr_rollback_bit(s, BEBIT(in, 4), fb) << (4 ^ 24);\r
459 ret |= lfsr_rollback_bit(s, BEBIT(in, 3), fb) << (3 ^ 24);\r
460 ret |= lfsr_rollback_bit(s, BEBIT(in, 2), fb) << (2 ^ 24);\r
461 ret |= lfsr_rollback_bit(s, BEBIT(in, 1), fb) << (1 ^ 24);\r
462 ret |= lfsr_rollback_bit(s, BEBIT(in, 0), fb) << (0 ^ 24);\r
463 return ret;\r
f89c7050
M
464}\r
465\r
466/** nonce_distance\r
467 * x,y valid tag nonces, then prng_successor(x, nonce_distance(x, y)) = y\r
468 */\r
469static uint16_t *dist = 0;\r
470int nonce_distance(uint32_t from, uint32_t to)\r
471{\r
472 uint16_t x, i;\r
473 if(!dist) {\r
474 dist = malloc(2 << 16);\r
475 if(!dist)\r
476 return -1;\r
477 for (x = i = 1; i; ++i) {\r
478 dist[(x & 0xff) << 8 | x >> 8] = i;\r
479 x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;\r
480 }\r
481 }\r
482 return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535;\r
483}\r
484\r
485\r
486static uint32_t fastfwd[2][8] = {\r
487 { 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},\r
488 { 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}};\r
489\r
490\r
491/** lfsr_prefix_ks\r
492 *\r
493 * Is an exported helper function from the common prefix attack\r
494 * Described in the "dark side" paper. It returns an -1 terminated array\r
495 * of possible partial(21 bit) secret state.\r
496 * The required keystream(ks) needs to contain the keystream that was used to\r
a0f33b66 497 * encrypt the NACK which is observed when varying only the 3 last bits of Nr\r
f89c7050
M
498 * only correct iff [NR_3] ^ NR_3 does not depend on Nr_3\r
499 */\r
500uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd)\r
501{\r
a0f33b66 502 uint32_t *candidates = malloc(4 << 10);\r
503 if(!candidates) return 0;\r
504 \r
f89c7050 505 uint32_t c, entry;\r
a0f33b66 506 int size = 0, i, good;\r
f89c7050 507\r
a0f33b66 508 for(i = 0; i < 1 << 21; ++i) {\r
509 for(c = 0, good = 1; good && c < 8; ++c) {\r
510 entry = i ^ fastfwd[isodd][c];\r
511 good &= (BIT(ks[c], isodd) == filter(entry >> 1));\r
512 good &= (BIT(ks[c], isodd + 2) == filter(entry));\r
f89c7050 513 }\r
a0f33b66 514 if(good)\r
515 candidates[size++] = i;\r
516 }\r
f89c7050 517\r
a0f33b66 518 candidates[size] = -1;\r
f89c7050
M
519\r
520 return candidates;\r
521}\r
522\r
a0f33b66 523/** check_pfx_parity\r
f89c7050
M
524 * helper function which eliminates possible secret states using parity bits\r
525 */\r
a0f33b66 526static struct Crypto1State* check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8], uint32_t odd, uint32_t even, struct Crypto1State* sl)\r
f89c7050 527{\r
a0f33b66 528 uint32_t ks1, nr, ks2, rr, ks3, c, good = 1;\r
f89c7050 529\r
a0f33b66 530 for(c = 0; good && c < 8; ++c) {\r
531 sl->odd = odd ^ fastfwd[1][c];\r
532 sl->even = even ^ fastfwd[0][c];\r
9cefee6f 533\r
a0f33b66 534 lfsr_rollback_bit(sl, 0, 0);\r
535 lfsr_rollback_bit(sl, 0, 0);\r
9cefee6f 536\r
a0f33b66 537 ks3 = lfsr_rollback_bit(sl, 0, 0);\r
538 ks2 = lfsr_rollback_word(sl, 0, 0);\r
539 ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1);\r
9cefee6f 540\r
f89c7050
M
541 nr = ks1 ^ (prefix | c << 5);\r
542 rr = ks2 ^ rresp;\r
543\r
f89c7050
M
544 good &= parity(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);\r
545 good &= parity(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);\r
546 good &= parity(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2, 8);\r
547 good &= parity(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2, 0);\r
a0f33b66 548 good &= parity(rr & 0x000000ff) ^ parities[c][7] ^ ks3;\r
f89c7050
M
549 }\r
550\r
a0f33b66 551 return sl + good;\r
9cefee6f 552}\r
f89c7050 553\r
f89c7050
M
554/** lfsr_common_prefix\r
555 * Implentation of the common prefix attack.\r
556 * Requires the 28 bit constant prefix used as reader nonce (pfx)\r
557 * The reader response used (rr)\r
558 * The keystream used to encrypt the observed NACK's (ks)\r
559 * The parity bits (par)\r
560 * It returns a zero terminated list of possible cipher states after the\r
561 * tag nonce was fed in\r
562 */\r
a0f33b66 563\r
564struct Crypto1State* lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8])\r
f89c7050
M
565{\r
566 struct Crypto1State *statelist, *s;\r
567 uint32_t *odd, *even, *o, *e, top;\r
568\r
569 odd = lfsr_prefix_ks(ks, 1);\r
570 even = lfsr_prefix_ks(ks, 0);\r
571\r
8130eba4 572 s = statelist = malloc((sizeof *statelist) << 21);\r
a0f33b66 573 if(!s || !odd || !even) {\r
bcf61bd3 574 free(statelist);\r
575 free(odd);\r
576 free(even);\r
577 return 0;\r
a61b4976 578 }\r
f89c7050 579\r
a0f33b66 580 for(o = odd; *o + 1; ++o)\r
581 for(e = even; *e + 1; ++e)\r
f89c7050 582 for(top = 0; top < 64; ++top) {\r
a0f33b66 583 *o += 1 << 21;\r
584 *e += (!(top & 7) + 1) << 21;\r
585 s = check_pfx_parity(pfx, rr, par, *o, *e, s);\r
f89c7050
M
586 }\r
587\r
a0f33b66 588 s->odd = s->even = 0;\r
f89c7050
M
589\r
590 free(odd);\r
591 free(even);\r
f89c7050 592 return statelist;\r
a0f33b66 593}
Impressum, Datenschutz