* Fixes/updates for skipjack/newdes (tea.c needs to receive some)
authorDavor Ocelic <docelic@sl1.spinlock.hr>
Tue, 13 Jan 2009 03:34:34 +0000 (04:34 +0100)
committerDavor Ocelic <docelic@sl1.spinlock.hr>
Tue, 13 Jan 2009 03:34:34 +0000 (04:34 +0100)
README
src/config.h
src/newdes-sk.c
src/newdes-sk.h
src/skipjack.c
src/skipjack.h
src/tea.c

diff --git a/README b/README
index 6f6a111..d5ce0f5 100644 (file)
--- a/README
+++ b/README
@@ -23,9 +23,9 @@ Compiling:
 
  cd src
  editor config.h   (enable/disable build options)
- editor Makefile   ($ARCH)
+ editor Makefile   (verify settings for $ARCH and $BOARD)
  editor eedata.S   (can change EEPROM data loaded on card, such as
-                   serial number, rng seed, keys or file permissions)
+                   serial number, RNG seed, keys or file permissions)
 
  make              (result are sosse.{bin,hex} and eedata.{bin,hex})
 
@@ -47,7 +47,7 @@ Loading onto smartcard:
   make verify (= verify-eeprom verify-flash)
 
 
-Installing smart card reader software:
+Installing smart card reader software (Towitoko reader example):
  apt-get install libtowitoko2 libtowitoko-dev
  apt-get install pcscd
 
@@ -70,21 +70,28 @@ Installing smart card reader software:
 
 Alternative build modes
 
-ATMOS can be compiled for the AVR target (standard makefile),
-as a binary running on your workstation (Makefile.emu) and
-as a CT-API driver implementing a virtual card in a virtual terminal.
+ATMOS can be compiled in few different modes:
 
-To invoke builds from other types, you need to specify 'make -f MAKEFILE',
-and you need to pay attention to always clean the build by invoking
-'make -f MAKEFILE clean' before switching targets, or you will get
-errors about wrong binary types etc.
+ - binary for the AVR-based smartcard (standard Makefile)
+ - binary running on your workstation (Makefile.emu)
+ - CT-API driver implementing a virtual card in a virtual terminal
+
+To invoke builds for the last two types, you need to specify
+'make -f MAKEFILE', and you need to pay attention to always clean the
+build by invoking 'make -f MAKEFILE clean' before switching targets,
+or you will mix binaries and get errors about wrong binary types etc.
 
 To ease this process, the default Makefile's clean action calls all
-three cleans (for the standard build, emulator and CT-API). Therefore,
-just 'make clean' will do what you need.
+three cleans. Therefore, just 'make clean' will always do what you need.
+
+Let's take a look at each build type:
+
+* Standard Makefile, AVR target:
 
+ Install gcc-avr and avr-libc
+ Compile with 'make'
 
-Compiling programs for emulation on PC
+* Emulation on a PC
 
  To ease debugging, you can compile the package for the usual
  desktop computer (no any smart card hardware necessary).
@@ -108,7 +115,7 @@ Compiling programs for emulation on PC
    Info: http://www.freshmeat.net/projects/scez
 
 
-Compiling CT-API driver emulating card in a terminal
+* CT-API driver emulating card in a terminal
 
  Add -I/tmp/scez-ng to cflags
 
@@ -116,13 +123,13 @@ Compiling CT-API driver emulating card in a terminal
 
 ------------------------------------------------------------------------
 
-ATMOS is based on 2003 SOSSE by Matthias Bruestle <m@mbsks.franken.de>:
-
-SOSSE is documented inside the source. Printable/browsable documentation
-is generated with doxygen. A "make" in the top level directory will
-also build the documentation. If you do not have doxygen installed and
-do not want to install it, you find the most important documentation in
-"src/main.h". You can also browse it online at:
+ATMOS is copyright 2008-2009 Davor Ocelic <docelic@spinlocksolutions.com>
 
-<http://www.mbsks.franken.de/sosse/>
+ATMOS is based on 2003 SOSSE by Matthias Bruestle <m@mbsks.franken.de>:
+  SOSSE is documented inside the source. Printable/browsable documentation
+  is generated with doxygen. A "make" in the top level directory will
+  also build the documentation. If you do not have doxygen installed and
+  do not want to install it, you find the most important documentation in
+  "src/main.h". You can also browse it online at:
+  <http://www.mbsks.franken.de/sosse/>
 
index 4a435f5..0ba8fa2 100644 (file)
@@ -89,7 +89,7 @@
        If set to 1, support for decryption side of the cryptographic algorithms
        are included.
 */
-#define CONF_WITH_DECRYPT              0
+#define CONF_WITH_DECRYPT              1
 
 /*! \brief En-/disables support for logging.
 
index c4d0152..b6e9bb0 100644 (file)
 /* $Id: newdes-sk.c,v 1.1 2003/03/30 12:42:21 m Exp $ */
 
 #include <config.h>
-#include <types.h>
+#include <newdes-sk.h>
+#ifdef DEBUG
+#include <stdio.h>
+#endif
 
 #if CONF_WITH_CRYPT_ALGO==2
 
@@ -111,6 +114,13 @@ void newdessk_enc( iu8* v, iu8* k )
        iu8 i;
        iu8 ex;
 
+#ifdef DEBUG
+  printf( "newdessk_enc( %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX, %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX )\n",
+               v[0],   v[1],   v[2],   v[3],   v[4],   v[5],   v[6],   v[7],
+               k[0], k[1],     k[2], k[3],     k[4], k[4],     k[6], k[7],
+               k[8], k[9],     k[10], k[11],   k[12], k[13],   k[14]);
+#endif
+
        ex = 0;
        i = 0;
 
@@ -123,13 +133,18 @@ void newdessk_enc( iu8* v, iu8* k )
                v[6] = v[6] ^ f[v[2] ^ k[i] ^ ex];
                if(++i==15) {i = 0;  ex = k[9];}
                v[7] = v[7] ^ f[v[3] ^ k[i] ^ ex];
-               if(++i==15) return;
+               if(++i==15) break;
 
                v[1] = v[1] ^ f[v[4] ^ k[i++] ^ ex];
                v[2] = v[2] ^ f[v[4] ^ v[5]];
                v[3] = v[3] ^ f[v[6] ^ k[i++] ^ ex];
                v[0] = v[0] ^ f[v[7] ^ k[i++] ^ ex];
        }
+
+#ifdef DEBUG
+       printf( "= %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX\n",
+       v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7] );
+#endif
 }
 
 #if CONF_WITH_DECRYPT==1
@@ -138,6 +153,13 @@ void newdessk_dec( iu8* v, iu8* k )
        iu8 i;
        iu8 ex;
 
+#ifdef DEBUG
+  printf( "newdessk_dec( %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX, %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX )\n",
+               v[0],   v[1],   v[2],   v[3],   v[4],   v[5],   v[6],   v[7],
+               k[0], k[1],     k[2], k[3],     k[4], k[4],     k[6], k[7],
+               k[8], k[9],     k[10], k[11],   k[12], k[13],   k[14]);
+#endif
+
        ex = k[9];
        i = 14;
 
@@ -161,6 +183,41 @@ void newdessk_dec( iu8* v, iu8* k )
 }
 #endif /* CONF_WITH_DECRYPT==1 */
 
+#ifdef TEST
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+int main() {
+       iu8 inp[8]      = { 0x33, 0x22, 0x11, 0x00, 0xdd, 0xcc, 0xbb, 0xaa };
+       iu8 key[15]     = { 0x00, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0x99, 0x88, 0x77, 0x66 };
+       iu8 enc[8], dec[8];
+       iu8 chk[8]      = { 0x5a, 0xc9, 0xed, 0x97, 0xae, 0x85, 0x5d, 0xbe };
+       iu8 tab[10][256];
+       long i;
+       clock_t elapsed;
+
+       memcpy( enc, inp, 8 );
+       newdessk_enc( enc, key );
+       printf((memcmp(enc, chk, 8) == 0) ? "encryption OK!\n" : "encryption failure!\n");
+#if CONF_WITH_DECRYPT==1
+       memcpy( dec, enc, 8 );
+       newdessk_dec( dec, key );
+       printf((memcmp(dec, inp, 8) == 0) ? "decryption OK!\n" : "decryption failure!\n");
+#endif
+
+#ifdef BENCHMARK
+       elapsed = -clock();
+       for (i = 0; i < 1000000L; i++) {
+               newdessk_enc( enc, key );
+       }
+       elapsed += clock();
+       printf ("elapsed time: %.1f s.\n", (float)elapsed/CLOCKS_PER_SEC);
+#endif
+       return 0;
+}
+#endif /* TEST */
+
 /* Notes:
 
      The original NEWDES algorithm was vulnerable to a related-key 
index 236451f..ec2e985 100644 (file)
@@ -9,8 +9,8 @@
 
 #include <types.h>
 
-#define NEWDESSK_KEY_LEN       15      //!< NEWDES-SK key size.
-#define NEWDESSK_BLOCK_LEN     8       //!< NEWDES-SK block length.
+#define NEWDESSK_KEY_LEN       15      //!< NEWDES-SK key size (bytes).
+#define NEWDESSK_BLOCK_LEN     8       //!< NEWDES-SK block length (bytes).
 
 /*!    \brief NEWDES-SK encryption function.
 
index 8b56217..1e4b2c6 100644 (file)
@@ -6,10 +6,16 @@
 
 #include <config.h>
 #include <skipjack.h>
-#include <types.h>
+#ifdef DEBUG
+#include <stdio.h>
+#endif
 
 #if CONF_WITH_CRYPT_ALGO==1
 
+// Currently decryption only works with SMALL_MEMORY=1. (Must be
+// an error somewhere in non-small code).
+#define CONF_SMALL_MEMORY 1
+
 #if CONF_SMALL_MEMORY==1
 #define INLINE
 #endif
@@ -118,6 +124,13 @@ void skipjack_enc( iu8* v, iu8* k )
        iu8 tmp;
 #endif
 
+#ifdef DEBUG
+  printf( "skipjack_enc( %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX, %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX )\n",
+    v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7],
+    k[0], k[1], k[2], k[3], k[4], k[4], k[6], k[7],
+    k[8], k[9]);
+#endif
+
        while( counter<9 ) {
                g( v, k, kidx );
                rule_a( v, counter );
@@ -157,6 +170,10 @@ void skipjack_enc( iu8* v, iu8* k )
 #endif
                counter++;
        }
+#ifdef DEBUG
+       printf( "= %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX\n",
+               v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7] );
+#endif
 }
 
 #if CONF_WITH_DECRYPT==1
@@ -235,6 +252,13 @@ void skipjack_dec( iu8* v, iu8* k )
        iu8 tmp;
 #endif
 
+#ifdef DEBUG
+  printf( "skipjack_dec( %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX, %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX %.2hX )\n",
+    v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7],
+    k[0], k[1], k[2], k[3], k[4], k[4], k[6], k[7],
+    k[8], k[9]);
+#endif
+
        while( counter>24 ) {
                ginv( v+2, k, kidx );
                rule_binv( v, counter );
@@ -294,16 +318,20 @@ int main() {
        memcpy( enc, inp, 8 );
        skipjack_enc( enc, key );
        printf((memcmp(enc, chk, 8) == 0) ? "encryption OK!\n" : "encryption failure!\n");
-       memcpy( dec, enc, 8 );
+#if CONF_WITH_DECRYPT==1
+       memcpy( dec, chk, 8 );
        skipjack_dec( dec, key );
        printf((memcmp(dec, inp, 8) == 0) ? "decryption OK!\n" : "decryption failure!\n");
+#endif
 
+#ifdef BENCHMARK
        elapsed = -clock();
        for (i = 0; i < 1000000L; i++) {
                skipjack_enc( enc, key );
        }
        elapsed += clock();
        printf ("elapsed time: %.1f s.\n", (float)elapsed/CLOCKS_PER_SEC);
+#endif
        return 0;
 }
 #endif /* TEST */
index 424ff0c..ece0e25 100644 (file)
@@ -12,8 +12,8 @@
 
 #include <types.h>
 
-#define SKIPJACK_KEY_LEN       10      //!< SKIPJACK key size.
-#define SKIPJACK_BLOCK_LEN     8       //!< SKIPJACK block length.
+#define SKIPJACK_KEY_LEN       10      //!< SKIPJACK key size (bytes).
+#define SKIPJACK_BLOCK_LEN     8       //!< SKIPJACK block length (bytes).
 
 /*! \brief Skipjack encryption function.
 
index 3e473da..4741a43 100644 (file)
--- a/src/tea.c
+++ b/src/tea.c
@@ -12,8 +12,9 @@ Notes:
 TEA is a Feistel cipher with XOR and and addition as the non-linear
 mixing functions.
 
-Takes 64 bits of data in v[0] and v[1].  Returns 64 bits of data in w[0]
-and w[1].  Takes 128 bits of key in k[0] - k[3].
+Takes 64 bits of data (1 block) in v[0] and v[1] (32b + 32b).
+Takes 128 bits of key in k[0] - k[3].
+Returns 64 bits of data in v[0] and v[1].
 
 TEA can be operated in any of the modes of DES. Cipher Block Chaining is,
 for example, simple to implement.
@@ -36,8 +37,6 @@ delta is chosen to be the real part of (the golden ratio Sqrt(5/4) -
        $Id: tea.c,v 1.6 2003/04/02 23:57:54 m Exp $
 */
 
-#define TEA_SMALL
-
 #include <config.h>
 #include <tea.h>
 #include <tools.h>
@@ -46,17 +45,10 @@ delta is chosen to be the real part of (the golden ratio Sqrt(5/4) -
 #endif
 
 #define hton_ul(x,y)
-//#include <log.h>
 
+// Tea is algorithm with ID 0 in our list
 #if CONF_WITH_CRYPT_ALGO==0
 
-#if defined(TEA_SMALL)
-iu32 tea_func( iu32 *in, iu32 *sum, iu32 *k )
-{
-       return ((*in<<4)+k[0]) ^ (*in+*sum) ^ ((*in>>5)+k[1]);
-}
-#endif
-
 void tea_enc( iu32 *v, iu32 *k )
 {
        iu32 y, z;
@@ -75,13 +67,8 @@ void tea_enc( iu32 *v, iu32 *k )
 
        while(n-->0) {
                sum += DELTA;
-#if defined(TEA_SMALL)
-               y += tea_func( &z, &sum, &(k[0]) );
-               z += tea_func( &y, &sum, &(k[2]) );
-#else
                y += ((z<<4)+k[0]) ^ (z+sum) ^ ((z>>5)+k[1]);
                z += ((y<<4)+k[2]) ^ (y+sum) ^ ((y>>5)+k[3]);
-#endif
        }
 
        v[0]=y; v[1]=z;
@@ -111,13 +98,8 @@ void tea_dec( iu32 *v, iu32 *k )
        y=v[0]; z=v[1];
 
        while(n-->0) {
-#if defined(TEA_SMALL)
-               z -= tea_func( &y, &sum, &(k[2]) );
-               y -= tea_func( &z, &sum, &(k[0]) );
-#else
                z -= ((y<<4)+k[2]) ^ (y+sum) ^ ((y>>5)+k[3]);
                y -= ((z<<4)+k[0]) ^ (z+sum) ^ ((z>>5)+k[1]);
-#endif
                sum -= DELTA;
        }
 
@@ -131,6 +113,37 @@ void tea_dec( iu32 *v, iu32 *k )
        hton_ul(v,2);
 }
 
-#endif /* CONF_WITH_CRYPT_ALGO==0 */
+#ifdef TEST
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+int main() {
+       iu32 inp[2]     = { 0x11111111, 0x22222222 };
+       iu32 key[4]     = { 0x11111111, 0x22222222, 0x33333333, 0x44444444 };
+       iu32 enc[2], dec[2];
+       //iu32 chk[8]   = { 0x25, 0x87, 0xca, 0xe2, 0x7a, 0x12, 0xd3, 0x00 };
+       long i;
+       clock_t elapsed;
+
+       memcpy( enc, inp, 64 );
+       tea_enc( enc, key );
+       //printf((memcmp(enc, chk, 8) == 0) ? "encryption OK!\n" : "encryption failure!\n");
+       memcpy( dec, enc, 64 );
+       tea_dec( dec, key );
+       printf((memcmp(dec, inp, 64) == 0) ? "decryption OK!\n" : "decryption failure!\n");
+
+#ifdef BENCHMARK
+       elapsed = -clock();
+       for (i = 0; i < 1000000L; i++) {
+               tea_enc( enc, key );
+       }
+       elapsed += clock();
+       printf ("elapsed time: %.1f s.\n", (float)elapsed/CLOCKS_PER_SEC);
+#endif
+       return 0;
+}
+#endif /* TEST */
 
+#endif /* CONF_WITH_CRYPT_ALGO==0 */