See ChangeLog: Wed Apr 7 20:51:39 CEST 1999 Werner Koch
authorWerner Koch <wk@gnupg.org>
Wed, 7 Apr 1999 18:58:32 +0000 (18:58 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 7 Apr 1999 18:58:32 +0000 (18:58 +0000)
ChangeLog
Makefile.am
cipher/ChangeLog
cipher/Makefile.am
cipher/blowfish.h
cipher/cipher.c
cipher/twofish.c
configure.in
mpi/ChangeLog
mpi/Makefile.am

index d1f3ec1..4fb2bee 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Apr  7 20:51:39 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * Makefile.am (g10defs.h): Removed.
+       * configure.in (AC_OUTPUT_COMMANDS): Create g10defs.h
+
 Sat Mar 20 12:55:33 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
 
        * VERSION: Now 0.9.5
index b06903c..1651d0a 100644 (file)
@@ -3,24 +3,6 @@
 SUBDIRS = intl zlib util mpi cipher tools g10 po doc checks
 EXTRA_DIST = VERSION  PROJECTS BUGS
 
-all-am: g10defs.h
-all-recursive-am: g10defs.h
-
-
-g10defs.h : config.h
-       @( set -e; \
-       echo "/* Generated automatically by Makefile */" ; \
-       echo "#ifdef HAVE_DRIVE_LETTERS"; \
-       echo "#define G10_LOCALEDIR \"c:/lib/gnupg/locale\""; \
-       echo "#define GNUPG_LIBDIR \"c:/lib/gnupg\""; \
-       echo "#define GNUPG_DATADIR \"c:/lib/gnupg\""; \
-       echo "#else";\
-       echo "#define G10_LOCALEDIR \"$(prefix)/$(DATADIRNAME)/locale\""; \
-       echo "#define GNUPG_LIBDIR \"$(libdir)/gnupg\""; \
-       echo "#define GNUPG_DATADIR \"$(datadir)/gnupg\""; \
-       echo "#endif";\
-       ) >g10defs.h
-
 
 dist-hook:
        @set -e; \
@@ -40,11 +22,11 @@ dist-hook:
 # maintainer only
 cvs-get:
        rsync -Cavuzb  --exclude scratch --exclude .deps \
-                     koch@ftp.guug.de:work/gnupg .
+                     wkoch@sigtrap.guug.de:work/gnupg .
 
 cvs-put:
        rsync -Cavuzb --exclude .deps --exclude scratch \
-                     . koch@ftp.guug.de:work/gnupg
+                     . wkoch@sigtrap.guug.de:work/gnupg
 
 cvs-sync: cvs-get cvs-put
 
index b1000c8..4ecdbc4 100644 (file)
@@ -1,3 +1,12 @@
+Wed Apr  7 20:51:39 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * random.c (get_random_bits): Can now handle requests > POOLSIZE
+
+       * cipher.c (cipher_open): Now uses standard CFB for automode if
+       the blocksize is gt 8 (according to rfc2440).
+
+       * twofish.c: Applied Matthew Skala's patches for 256 bit key.
+
 Tue Apr  6 19:58:12 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
 
        * random.c (get_random_bits): Can now handle requests > POOLSIZE
index ba237bf..f42d682 100644 (file)
@@ -12,10 +12,8 @@ noinst_LIBRARIES = libcipher.a
 # might also list programs which are not modules)
 # MODULES: rndunix rndlinux rndegd
 # MODULES: sha1 rmd160 md5 tiger
-# MODULES: twofish
 EXTRA_PROGRAMS = rndunix rndlinux rndegd  \
-                sha1 rmd160 md5 tiger  \
-                twofish
+                sha1 rmd160 md5 tiger
 
 EXTRA_rndlinux_SOURCES = rndlinux.c
 EXTRA_rndunix_SOURCES = rndunix.c
@@ -24,7 +22,6 @@ EXTRA_md5_SOURCES = md5.c
 EXTRA_rmd160_SOURCES = rmd160.c
 EXTRA_sha1_SOURCES = sha1.c
 EXTRA_tiger_SOURCES = tiger.c
-EXTRA_twofish_SOURCES = twofish.c
 
 
 if ENABLE_GNUPG_EXTENSIONS
@@ -43,6 +40,8 @@ libcipher_a_SOURCES = cipher.c        \
                 dynload.h      \
                 des.c          \
                 des.h          \
+                twofish.c      \
+                twofish.h      \
                 blowfish.c     \
                 blowfish.h     \
                 cast5.c        \
@@ -76,14 +75,14 @@ tiger: $(srcdir)/tiger.c
            sed -e 's/-O[2-9]*/-O1/g' `
 
 tiger.o: $(srcdir)/tiger.c
-       `echo $(COMPILE) $(srcdir)/tiger.c | sed -e 's/-O[2-9]*/-O1/g' `
+       `echo $(COMPILE) -c $(srcdir)/tiger.c | sed -e 's/-O[2-9]*/-O1/g' `
 
 twofish: $(srcdir)/twofish.c
        `echo $(COMPILE) $(DYNLINK_MOD_CFLAGS) -o twofish $(srcdir)/twofish.c | \
            sed -e 's/-O[0-9]*/  /g' `
 
 twofish.o: $(srcdir)/twofish.c
-       `echo $(COMPILE) $(srcdir)/twofish.c | sed -e 's/-O[0-9]*/  /g' `
+       `echo $(COMPILE) -c $(srcdir)/twofish.c | sed -e 's/-O[0-9]*/  /g' `
 
 
 rndunix: $(srcdir)/rndunix.c
index 827baa1..7c34bab 100644 (file)
@@ -31,4 +31,14 @@ blowfish_get_info( int algo, size_t *keylen,
                   void (**decryptf)( void *c, byte *outbuf, byte *inbuf )
                 );
 
+/* this is just a kludge for the time we have not yet chnaged the cipher
+ * stuff to the scheme we use for random and digests */
+const char *
+twofish_get_info( int algo, size_t *keylen,
+                  size_t *blocksize, size_t *contextsize,
+                  int  (**setkeyf)( void *c, byte *key, unsigned keylen ),
+                  void (**encryptf)( void *c, byte *outbuf, byte *inbuf ),
+                  void (**decryptf)( void *c, byte *outbuf, byte *inbuf )
+                );
+
 #endif /*G10_BLOWFISH_H*/
index 338b2b9..0306c37 100644 (file)
@@ -83,6 +83,17 @@ setup_cipher_table(void)
     int i;
 
     i = 0;
+    cipher_table[i].algo = CIPHER_ALGO_TWOFISH;
+    cipher_table[i].name = twofish_get_info( cipher_table[i].algo,
+                                        &cipher_table[i].keylen,
+                                        &cipher_table[i].blocksize,
+                                        &cipher_table[i].contextsize,
+                                        &cipher_table[i].setkey,
+                                        &cipher_table[i].encrypt,
+                                        &cipher_table[i].decrypt     );
+    if( !cipher_table[i].name )
+       BUG();
+    i++;
     cipher_table[i].algo = CIPHER_ALGO_BLOWFISH;
     cipher_table[i].name = blowfish_get_info( cipher_table[i].algo,
                                         &cipher_table[i].keylen,
@@ -127,6 +138,17 @@ setup_cipher_table(void)
     if( !cipher_table[i].name )
        BUG();
     i++;
+    cipher_table[i].algo = CIPHER_ALGO_TWOFISH_OLD;
+    cipher_table[i].name = twofish_get_info( cipher_table[i].algo,
+                                        &cipher_table[i].keylen,
+                                        &cipher_table[i].blocksize,
+                                        &cipher_table[i].contextsize,
+                                        &cipher_table[i].setkey,
+                                        &cipher_table[i].encrypt,
+                                        &cipher_table[i].decrypt     );
+    if( !cipher_table[i].name )
+       BUG();
+    i++;
     cipher_table[i].algo = CIPHER_ALGO_DUMMY;
     cipher_table[i].name = "DUMMY";
     cipher_table[i].blocksize = 8;
index d1e171b..94a31de 100644 (file)
@@ -1,5 +1,6 @@
 /* Twofish for GPG
  * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
+ * 256-bit key length added March 20, 1999
  *
  * This code is a "clean room" implementation, written from the paper
  * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
@@ -11,7 +12,7 @@
  * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
  * Third Edition.
  *
- * Only the 128-bit block size is supported at present.  This code is intended
+ * Only the 128- and 256-bit key sizes are supported.  This code is intended
  * for GNU C on a 32-bit system, but it should work almost anywhere.  Loops
  * are unrolled, precomputation tables are used, etc., for maximum speed at
  * some cost in memory consumption. */
@@ -402,13 +403,13 @@ static const byte exp_to_poly[492] = {
       (d) ^= exp_to_poly[tmp + (z)]; \
    }
 
-/* Macros to calculate the key-dependent S-boxes using the S vector from
- * CALC_S.  CALC_SB_2 computes a single entry in all four S-boxes, where i
- * is the index of the entry to compute, and a and b are the index numbers
- * preprocessed through the q0 and q1 tables respectively.  CALC_SB is
- * simply a convenience to make the code shorter; it calls CALC_SB_2 four
- * times with consecutive indices from i to i+3, using the remaining
- * parameters two by two. */
+/* Macros to calculate the key-dependent S-boxes for a 128-bit key using
+ * the S vector from CALC_S.  CALC_SB_2 computes a single entry in all
+ * four S-boxes, where i is the index of the entry to compute, and a and b
+ * are the index numbers preprocessed through the q0 and q1 tables
+ * respectively.  CALC_SB is simply a convenience to make the code shorter;
+ * it calls CALC_SB_2 four times with consecutive indices from i to i+3,
+ * using the remaining parameters two by two. */
 
 #define CALC_SB_2(i, a, b) \
    ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
@@ -420,30 +421,63 @@ static const byte exp_to_poly[492] = {
    CALC_SB_2 (i, a, b); CALC_SB_2 ((i)+1, c, d); \
    CALC_SB_2 ((i)+2, e, f); CALC_SB_2 ((i)+3, g, h)
 
+/* Macros exactly like CALC_SB and CALC_SB_2, but for 256-bit keys. */
+
+#define CALC_SB256_2(i, a, b) \
+   ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
+   ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
+   ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
+   ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
+
+#define CALC_SB256(i, a, b, c, d, e, f, g, h) \
+   CALC_SB256_2 (i, a, b); CALC_SB256_2 ((i)+1, c, d); \
+   CALC_SB256_2 ((i)+2, e, f); CALC_SB256_2 ((i)+3, g, h)
+
 /* Macros to calculate the whitening and round subkeys.  CALC_K_2 computes the
- * h() function for a given index (either 2i or 2i+1). a and b are the index
- * preprocessed through q0 and q1 respectively; j is the index of the first
- * key byte to use.  CALC_K computes a pair of subkeys by calling CALC_K_2
+ * last two stages of the h() function for a given index (either 2i or 2i+1).
+ * a, b, c, and d are the four bytes going into the last two stages.  For
+ * 128-bit keys, this is the entire h() function and a and c are the index
+ * preprocessed through q0 and q1 respectively; for longer keys they are the
+ * output of previous stages.  j is the index of the first key byte to use.
+ * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
  * twice, doing the Psuedo-Hadamard Transform, and doing the necessary
  * rotations.  Its parameters are: a, the array to write the results into,
  * j, the index of the first output entry, k and l, the preprocessed indices
- * for index 2i, and m and n, the preprocessed indices for index 2i+1. */
+ * for index 2i, and m and n, the preprocessed indices for index 2i+1.
+ * CALC_K256_2 expands CALC_K_2 to handle 256-bit keys, by doing two
+ * additional lookup-and-XOR stages.  The parameters a and b are the index
+ * preprocessed through q0 and q1 respectively; j is the index of the first
+ * key byte to use.  CALC_K256 is identical to CALC_K but for using the
+ * CALC_K256_2 macro instead of CALC_K_2. */
 
-#define CALC_K_2(a, b, j) \
+#define CALC_K_2(a, b, c, d, j) \
      mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \
    ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \
-   ^ mds[2][q1[a ^ key[(j) + 10]] ^ key[(j) + 2]] \
-   ^ mds[3][q1[b ^ key[(j) + 11]] ^ key[(j) + 3]]
+   ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
+   ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
 
 #define CALC_K(a, j, k, l, m, n) \
-   x = CALC_K_2 (k, l, 0); \
-   y = CALC_K_2 (m, n, 4); \
+   x = CALC_K_2 (k, l, k, l, 0); \
+   y = CALC_K_2 (m, n, m, n, 4); \
+   y = (y << 8) + (y >> 24); \
+   x += y; y += x; ctx->a[j] = x; \
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K256_2(a, b, j) \
+   CALC_K_2 (q0[q1[b ^ key[(j) + 24]] ^ key[(j) + 16]], \
+            q1[q1[a ^ key[(j) + 25]] ^ key[(j) + 17]], \
+            q0[q0[a ^ key[(j) + 26]] ^ key[(j) + 18]], \
+            q1[q0[b ^ key[(j) + 27]] ^ key[(j) + 19]], j)
+
+#define CALC_K256(a, j, k, l, m, n) \
+   x = CALC_K256_2 (k, l, 0); \
+   y = CALC_K256_2 (m, n, 4); \
    y = (y << 8) + (y >> 24); \
    x += y; y += x; ctx->a[j] = x; \
-   ctx->a[(j) + 1] = (y << 9) + ( y >> 23)
+   ctx->a[(j) + 1] = (y << 9) + (y >> 23)
 \f
-/* Perform the key setup.  Note that this works *only* with 128-bit keys,
- * despite the API that makes it look like it might support other sizes. */
+/* Perform the key setup.  Note that this works only with 128- and 256-bit
+ * keys, despite the API that looks like it might support other sizes. */
 
 static int
 twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
@@ -451,9 +485,10 @@ twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
    /* Temporaries for CALC_K. */
    u32 x, y;
 
-   /* The S vector used to key the S-boxes, split up into individual
-    * bytes. */
+   /* The S vector used to key the S-boxes, split up into individual bytes.
+    * 128-bit keys use only sa through sh; 256-bit use all of them. */
    byte sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
+   byte si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
 
    /* Temporary for CALC_S. */
    byte tmp;
@@ -463,7 +498,7 @@ twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
    static const char *selftest_failed=0;
 
    /* Check key length. */
-   if( keylen != 16 )  /* enhance this code for 256 bit keys */
+   if( ( ( keylen - 16 ) | 16 ) != 16 )
        return G10ERR_WRONG_KEYLEN;
 
    /* Do self-test if necessary. */
@@ -476,9 +511,10 @@ twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
    if( selftest_failed )
       return G10ERR_SELFTEST_FAILED;
 
-   /* Compute the S vector.  The magic numbers are the entries of the RS
-    * matrix, preprocessed through poly_to_exp.  The numbers in the comments
-    * are the original (polynomial form) matrix entries. */
+   /* Compute the first two words of the S vector.  The magic numbers are
+    * the entries of the RS matrix, preprocessed through poly_to_exp.  The
+    * numbers in the comments are the original (polynomial form) matrix
+    * entries. */
    CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
    CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
    CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
@@ -496,95 +532,208 @@ twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
    CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
    CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
 
-   /* Compute the S-boxes.  The constants are indices of
-    * S-box entries, preprocessed through q0 and q1. */
-   CALC_SB (0, 0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4);
-   CALC_SB (4, 0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8);
-   CALC_SB (8, 0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B);
-   CALC_SB (12, 0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B);
-   CALC_SB (16, 0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD);
-   CALC_SB (20, 0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1);
-   CALC_SB (24, 0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B);
-   CALC_SB (28, 0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F);
-   CALC_SB (32, 0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B);
-   CALC_SB (36, 0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D);
-   CALC_SB (40, 0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E);
-   CALC_SB (44, 0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5);
-   CALC_SB (48, 0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14);
-   CALC_SB (52, 0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3);
-   CALC_SB (56, 0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54);
-   CALC_SB (60, 0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51);
-   CALC_SB (64, 0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A);
-   CALC_SB (68, 0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96);
-   CALC_SB (72, 0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10);
-   CALC_SB (76, 0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C);
-   CALC_SB (80, 0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7);
-   CALC_SB (84, 0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70);
-   CALC_SB (88, 0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB);
-   CALC_SB (92, 0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8);
-   CALC_SB (96, 0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF);
-   CALC_SB (100, 0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC);
-   CALC_SB (104, 0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF);
-   CALC_SB (108, 0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2);
-   CALC_SB (112, 0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82);
-   CALC_SB (116, 0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9);
-   CALC_SB (120, 0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97);
-   CALC_SB (124, 0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17);
-   CALC_SB (128, 0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D);
-   CALC_SB (132, 0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3);
-   CALC_SB (136, 0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C);
-   CALC_SB (140, 0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E);
-   CALC_SB (144, 0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F);
-   CALC_SB (148, 0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49);
-   CALC_SB (152, 0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21);
-   CALC_SB (156, 0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9);
-   CALC_SB (160, 0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD);
-   CALC_SB (164, 0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01);
-   CALC_SB (168, 0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F);
-   CALC_SB (172, 0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48);
-   CALC_SB (176, 0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E);
-   CALC_SB (180, 0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19);
-   CALC_SB (184, 0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57);
-   CALC_SB (188, 0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64);
-   CALC_SB (192, 0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE);
-   CALC_SB (196, 0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5);
-   CALC_SB (200, 0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44);
-   CALC_SB (204, 0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69);
-   CALC_SB (208, 0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15);
-   CALC_SB (212, 0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E);
-   CALC_SB (216, 0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34);
-   CALC_SB (220, 0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC);
-   CALC_SB (224, 0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B);
-   CALC_SB (228, 0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB);
-   CALC_SB (232, 0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52);
-   CALC_SB (236, 0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9);
-   CALC_SB (240, 0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4);
-   CALC_SB (244, 0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2);
-   CALC_SB (248, 0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56);
-   CALC_SB (252, 0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91);
-
-   /* Calculate whitening and round subkeys.  The constants are
-    * indices of subkeys, preprocessed through q0 and q1. */
-   CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
-   CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
-   CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
-   CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
-   CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
-   CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
-   CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
-   CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
-   CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
-   CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
-   CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
-   CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
-   CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
-   CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
-   CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
-   CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
-   CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
-   CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
-   CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
-   CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+   if (keylen == 32) { /* 256-bit key */
+
+      /* Calculate the remaining two words of the S vector */
+      CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+      CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+      CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+      CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+      CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+      CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+      CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+      CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+      CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+      CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+      CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+      CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+      CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+      CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+      CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+      CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+      /* Compute the S-boxes.  The constants are indices of
+       * S-box entries, preprocessed through q0 and q1. */
+      CALC_SB256 (0, 0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4);
+      CALC_SB256 (4, 0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8);
+      CALC_SB256 (8, 0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B);
+      CALC_SB256 (12, 0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B);
+      CALC_SB256 (16, 0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD);
+      CALC_SB256 (20, 0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1);
+      CALC_SB256 (24, 0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B);
+      CALC_SB256 (28, 0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F);
+      CALC_SB256 (32, 0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B);
+      CALC_SB256 (36, 0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D);
+      CALC_SB256 (40, 0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E);
+      CALC_SB256 (44, 0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5);
+      CALC_SB256 (48, 0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14);
+      CALC_SB256 (52, 0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3);
+      CALC_SB256 (56, 0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54);
+      CALC_SB256 (60, 0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51);
+      CALC_SB256 (64, 0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A);
+      CALC_SB256 (68, 0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96);
+      CALC_SB256 (72, 0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10);
+      CALC_SB256 (76, 0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C);
+      CALC_SB256 (80, 0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7);
+      CALC_SB256 (84, 0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70);
+      CALC_SB256 (88, 0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB);
+      CALC_SB256 (92, 0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8);
+      CALC_SB256 (96, 0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF);
+      CALC_SB256 (100, 0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC);
+      CALC_SB256 (104, 0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF);
+      CALC_SB256 (108, 0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2);
+      CALC_SB256 (112, 0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82);
+      CALC_SB256 (116, 0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9);
+      CALC_SB256 (120, 0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97);
+      CALC_SB256 (124, 0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17);
+      CALC_SB256 (128, 0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D);
+      CALC_SB256 (132, 0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3);
+      CALC_SB256 (136, 0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C);
+      CALC_SB256 (140, 0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E);
+      CALC_SB256 (144, 0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F);
+      CALC_SB256 (148, 0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49);
+      CALC_SB256 (152, 0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21);
+      CALC_SB256 (156, 0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9);
+      CALC_SB256 (160, 0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD);
+      CALC_SB256 (164, 0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01);
+      CALC_SB256 (168, 0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F);
+      CALC_SB256 (172, 0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48);
+      CALC_SB256 (176, 0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E);
+      CALC_SB256 (180, 0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19);
+      CALC_SB256 (184, 0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57);
+      CALC_SB256 (188, 0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64);
+      CALC_SB256 (192, 0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE);
+      CALC_SB256 (196, 0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5);
+      CALC_SB256 (200, 0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44);
+      CALC_SB256 (204, 0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69);
+      CALC_SB256 (208, 0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15);
+      CALC_SB256 (212, 0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E);
+      CALC_SB256 (216, 0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34);
+      CALC_SB256 (220, 0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC);
+      CALC_SB256 (224, 0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B);
+      CALC_SB256 (228, 0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB);
+      CALC_SB256 (232, 0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52);
+      CALC_SB256 (236, 0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9);
+      CALC_SB256 (240, 0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4);
+      CALC_SB256 (244, 0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2);
+      CALC_SB256 (248, 0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56);
+      CALC_SB256 (252, 0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91);
+
+      /* Calculate whitening and round subkeys.  The constants are
+       * indices of subkeys, preprocessed through q0 and q1. */
+      CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+      CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+      CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+      CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+      CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+      CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+      CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+      CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+      CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+      CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+      CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
+      CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+      CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
+      CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+      CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+      CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
+      CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+      CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+      CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
+      CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+
+   } else { /* 128-bit key */
+
+      /* Compute the S-boxes.  The constants are indices of
+       * S-box entries, preprocessed through q0 and q1. */
+      CALC_SB (0, 0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4);
+      CALC_SB (4, 0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8);
+      CALC_SB (8, 0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B);
+      CALC_SB (12, 0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B);
+      CALC_SB (16, 0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD);
+      CALC_SB (20, 0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1);
+      CALC_SB (24, 0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B);
+      CALC_SB (28, 0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F);
+      CALC_SB (32, 0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B);
+      CALC_SB (36, 0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D);
+      CALC_SB (40, 0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E);
+      CALC_SB (44, 0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5);
+      CALC_SB (48, 0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14);
+      CALC_SB (52, 0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3);
+      CALC_SB (56, 0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54);
+      CALC_SB (60, 0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51);
+      CALC_SB (64, 0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A);
+      CALC_SB (68, 0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96);
+      CALC_SB (72, 0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10);
+      CALC_SB (76, 0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C);
+      CALC_SB (80, 0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7);
+      CALC_SB (84, 0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70);
+      CALC_SB (88, 0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB);
+      CALC_SB (92, 0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8);
+      CALC_SB (96, 0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF);
+      CALC_SB (100, 0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC);
+      CALC_SB (104, 0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF);
+      CALC_SB (108, 0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2);
+      CALC_SB (112, 0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82);
+      CALC_SB (116, 0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9);
+      CALC_SB (120, 0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97);
+      CALC_SB (124, 0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17);
+      CALC_SB (128, 0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D);
+      CALC_SB (132, 0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3);
+      CALC_SB (136, 0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C);
+      CALC_SB (140, 0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E);
+      CALC_SB (144, 0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F);
+      CALC_SB (148, 0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49);
+      CALC_SB (152, 0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21);
+      CALC_SB (156, 0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9);
+      CALC_SB (160, 0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD);
+      CALC_SB (164, 0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01);
+      CALC_SB (168, 0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F);
+      CALC_SB (172, 0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48);
+      CALC_SB (176, 0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E);
+      CALC_SB (180, 0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19);
+      CALC_SB (184, 0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57);
+      CALC_SB (188, 0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64);
+      CALC_SB (192, 0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE);
+      CALC_SB (196, 0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5);
+      CALC_SB (200, 0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44);
+      CALC_SB (204, 0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69);
+      CALC_SB (208, 0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15);
+      CALC_SB (212, 0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E);
+      CALC_SB (216, 0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34);
+      CALC_SB (220, 0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC);
+      CALC_SB (224, 0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B);
+      CALC_SB (228, 0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB);
+      CALC_SB (232, 0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52);
+      CALC_SB (236, 0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9);
+      CALC_SB (240, 0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4);
+      CALC_SB (244, 0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2);
+      CALC_SB (248, 0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56);
+      CALC_SB (252, 0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91);
+
+      /* Calculate whitening and round subkeys.  The constants are
+       * indices of subkeys, preprocessed through q0 and q1. */
+      CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+      CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+      CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+      CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+      CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+      CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+      CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+      CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+      CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+      CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+      CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
+      CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+      CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
+      CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+      CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+      CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
+      CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+      CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+      CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
+      CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+   }
 
    return 0;
 }
@@ -715,7 +864,7 @@ twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
    OUTUNPACK (3, d, 3);
 }
 \f
-/* Test a single encryption and decryption, as a sanity check. */
+/* Test a single encryption and decryption with each key size. */
 
 static const char*
 selftest (void)
@@ -723,11 +872,11 @@ selftest (void)
    TWOFISH_context ctx; /* Expanded key. */
    byte scratch[16];   /* Encryption/decryption result buffer. */
 
-   /* Test vector for single encryption/decryption.  Note that I am using
-    * the vector from the Twofish paper's "known answer test", I=3, instead
-    * of the all-0 vector from the "intermediate value test", because an
-    * all-0 key would trigger all the special cases in the RS matrix multiply,
-    * leaving the actual math untested. */
+   /* Test vectors for single encryption/decryption.  Note that I am using
+    * the vectors from the Twofish paper's "known answer test", I=3 for
+    * 128-bit and I=4 for 256-bit, instead of the all-0 vectors from the
+    * "intermediate value test", because an all-0 key would trigger all the
+    * special cases in the RS matrix multiply, leaving the math untested. */
    static const byte plaintext[16] = {
       0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,
       0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19
@@ -740,23 +889,46 @@ selftest (void)
       0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,
       0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3
    };
+   static const byte plaintext_256[16] = {
+      0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
+      0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6
+   };
+   static const byte key_256[32] = {
+      0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
+      0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
+      0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
+      0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F
+   };
+   static const byte ciphertext_256[16] = {
+      0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97,
+      0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA
+   };
 
    twofish_setkey (&ctx, key, sizeof(key));
    twofish_encrypt (&ctx, scratch, plaintext);
    if (memcmp (scratch, ciphertext, sizeof (ciphertext)))
-     return "Twofish test encryption failed.";
+     return "Twofish-128 test encryption failed.";
    twofish_decrypt (&ctx, scratch, scratch);
    if (memcmp (scratch, plaintext, sizeof (plaintext)))
-     return "Twofish test decryption failed.";
+     return "Twofish-128 test decryption failed.";
+
+   twofish_setkey (&ctx, key_256, sizeof(key_256));
+   twofish_encrypt (&ctx, scratch, plaintext_256);
+   if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256)))
+     return "Twofish-256 test encryption failed.";
+   twofish_decrypt (&ctx, scratch, scratch);
+   if (memcmp (scratch, plaintext_256, sizeof (plaintext_256)))
+     return "Twofish-256 test decryption failed.";
+
    return NULL;
 }
 \f
-/* More complete test program. This does a thousand encryptions and
- * decryptions with each of five hundred keys using a feedback scheme similar
- * to a Feistel cipher, so as to be sure of testing all the table entries
- * pretty thoroughly.  We keep changing the keys so as to get a more
- * meaningful performance number, since the key setup is non-trivial for
- * Twofish. */
+/* More complete test program. This does 1000 encryptions and decryptions
+ * with each of 250 128-bit keys and 2000 encryptions and decryptions with
+ * each of 125 256-bit keys, using a feedback scheme similar to a Feistel
+ * cipher, so as to be sure of testing all the table entries pretty
+ * thoroughly. We keep changing the keys so as to get a more meaningful
+ * performance number, since the key setup is non-trivial for Twofish. */
 
 #ifdef TEST
 
@@ -769,56 +941,79 @@ main()
 {
    TWOFISH_context ctx;     /* Expanded key. */
    int i, j;               /* Loop counters. */
+
    const char *encrypt_msg; /* Message to print regarding encryption test;
                             * the printf is done outside the loop to avoid
                             * stuffing up the timing. */
    clock_t timer; /* For computing elapsed time. */
 
    /* Test buffer. */
-   byte buffer[2][16] = {
+   byte buffer[4][16] = {
       {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
       {0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A, 0x69, 0x78,
-       0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0}
+       0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0},
+      {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54 ,0x32, 0x10},
+      {0x01, 0x23, 0x45, 0x67, 0x76, 0x54 ,0x32, 0x10,
+       0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98}
    };
 
    /* Expected outputs for the million-operation test */
-   static const byte test_encrypt[2][16] = {
-      {0xD6, 0xD9, 0x74, 0x06, 0x93, 0x9C, 0x9A, 0x5E,
-       0xAA, 0x34, 0x18, 0x5B, 0xD3, 0x92, 0x5B, 0xC5},
-      {0x9C, 0xCD, 0x01, 0x30, 0xF9, 0x96, 0x00, 0x60,
-       0x49, 0x91, 0x73, 0x28, 0x9D, 0x8E, 0x8F, 0xC4}
+   static const byte test_encrypt[4][16] = {
+      {0xC8, 0x23, 0xB8, 0xB7, 0x6B, 0xFE, 0x91, 0x13,
+       0x2F, 0xA7, 0x5E, 0xE6, 0x94, 0x77, 0x6F, 0x6B},
+      {0x90, 0x36, 0xD8, 0x29, 0xD5, 0x96, 0xC2, 0x8E,
+       0xE4, 0xFF, 0x76, 0xBC, 0xE5, 0x77, 0x88, 0x27},
+      {0xB8, 0x78, 0x69, 0xAF, 0x42, 0x8B, 0x48, 0x64,
+       0xF7, 0xE9, 0xF3, 0x9C, 0x42, 0x18, 0x7B, 0x73},
+      {0x7A, 0x88, 0xFB, 0xEB, 0x90, 0xA4, 0xB4, 0xA8,
+       0x43, 0xA3, 0x1D, 0xF1, 0x26, 0xC4, 0x53, 0x57}
    };
-   static const byte test_decrypt[2][16] = {
+   static const byte test_decrypt[4][16] = {
       {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
        0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
       {0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A, 0x69, 0x78,
-       0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0}
+       0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0},
+      {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+       0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54 ,0x32, 0x10},
+      {0x01, 0x23, 0x45, 0x67, 0x76, 0x54 ,0x32, 0x10,
+       0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98}
    };
 
    /* Start the timer ticking. */
    timer = clock ();
 
    /* Encryption test. */
-   for (i = 0; i < 250; i++) {
+   for (i = 0; i < 125; i++) {
       twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]));
       for (j = 0; j < 1000; j++)
-       twofish_encrypt (&ctx, buffer[1], buffer[1]);
+       twofish_encrypt (&ctx, buffer[2], buffer[2]);
       twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]));
       for (j = 0; j < 1000; j++)
+       twofish_encrypt (&ctx, buffer[3], buffer[3]);
+      twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2);
+      for (j = 0; j < 1000; j++) {
        twofish_encrypt (&ctx, buffer[0], buffer[0]);
+       twofish_encrypt (&ctx, buffer[1], buffer[1]);
+      }
    }
    encrypt_msg = memcmp (buffer, test_encrypt, sizeof (test_encrypt)) ?
                 "encryption failure!\n" : "encryption OK!\n";
 
    /* Decryption test. */
-   for (i = 0; i < 250; i++) {
+   for (i = 0; i < 125; i++) {
+      twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2);
+      for (j = 0; j < 1000; j++) {
+       twofish_decrypt (&ctx, buffer[0], buffer[0]);
+       twofish_decrypt (&ctx, buffer[1], buffer[1]);
+      }
       twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]));
       for (j = 0; j < 1000; j++)
-       twofish_decrypt (&ctx, buffer[0], buffer[0]);
+       twofish_decrypt (&ctx, buffer[3], buffer[3]);
       twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]));
       for (j = 0; j < 1000; j++)
-       twofish_decrypt (&ctx, buffer[1], buffer[1]);
+       twofish_decrypt (&ctx, buffer[2], buffer[2]);
    }
 
    /* Stop the timer, and print results. */
@@ -833,7 +1028,10 @@ main()
 
 #endif /* TEST */
 \f
-static const char *
+#ifdef IS_MODULE
+static
+#endif
+       const char *
 twofish_get_info (int algo, size_t *keylen,
                  size_t *blocksize, size_t *contextsize,
                  int  (**r_setkey) (void *c, byte *key, unsigned keylen),
@@ -873,7 +1071,7 @@ static struct {
 
 
 /****************
- * Enumerate the names of the functions together with informations about
+ * Enumerate the names of the functions together with information about
  * this function. Set sequence to an integer with a initial value of 0 and
  * do not change it.
  * If what is 0 all kind of functions are returned.
index e4760fb..a792ec0 100644 (file)
@@ -50,7 +50,7 @@ case "$use_static_rnd" in
 esac
 
 dnl
-dnl See whether the user wants to disable checking for 7dev/random
+dnl See whether the user wants to disable checking for /dev/random
 
 AC_MSG_CHECKING([whether use of /dev/random is requested])
 AC_ARG_ENABLE(dev-random,
@@ -392,17 +392,17 @@ dnl And build the constructor file
 dnl
 
 test -d cipher || mkdir cipher
-cat <<EOF >cipher/construct.c
+cat <<G10EOF >cipher/construct.c
 /* automatically generated by configure - do not edit */
 
-EOF
+G10EOF
 GNUPG_MSG_PRINT([statically linked cipher modules:])
 for name in $STATIC_CIPHER_NAMES; do
     echo "void ${name}_constructor(void);" >>cipher/construct.c
     GNUPG_MSG_PRINT([$name])
 done
 AC_MSG_RESULT()
-cat <<EOF >>cipher/construct.c
+cat <<G10EOF >>cipher/construct.c
 
 void
 cipher_modules_constructor(void)
@@ -412,7 +412,7 @@ cipher_modules_constructor(void)
         return;
     done = 1;
 
-EOF
+G10EOF
 for name in $STATIC_CIPHER_NAMES; do
     echo "   ${name}_constructor();" >>cipher/construct.c
 done
@@ -483,6 +483,36 @@ fi
 GNUPG_DO_LINK_FILES
 
 
+AC_OUTPUT_COMMANDS([
+cat >g10defs.tmp <<G10EOF
+/* Generated automatically by configure */
+#ifdef HAVE_DRIVE_LETTERS
+  #define G10_LOCALEDIR "c:/lib/gnupg/locale"
+  #define GNUPG_LIBDIR  "c:/lib/gnupg"
+  #define GNUPG_DATADIR "c:/lib/gnupg"
+#else
+  #define G10_LOCALEDIR "${prefix}/${DATADIRNAME}/locale"
+  #define GNUPG_LIBDIR  "${libdir}/gnupg"
+  #define GNUPG_DATADIR "${datadir}/gnupg"
+#endif
+G10EOF
+if cmp -s g10defs.h g10defs.tmp 2>/dev/null; then
+    echo "g10defs.h is unchanged"
+    rm -f g10defs.tmp
+else
+    rm -f g10defs.h
+    mv g10defs.tmp g10defs.h
+    echo "g10defs.h created"
+fi
+],[
+prefix=$prefix
+exec_prefix=$exec_prefix
+libdir=$libdir
+datadir=$datadir
+DATADIRNAME=$DATADIRNAME
+])
+
+
 AC_OUTPUT([
 Makefile
 intl/Makefile
index 71fedb1..c4e214e 100644 (file)
@@ -1,3 +1,7 @@
+Wed Apr  7 20:51:39 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * Makefile.am: Explicit rules to invoke cpp on *.S
+
 Mon Mar  8 20:47:17 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
 
        * config.links: Take advantage of the with_symbol_underscore macro.
index 6fb7add..2f74309 100644 (file)
@@ -4,18 +4,16 @@ INCLUDES =  -I$(top_srcdir)/include
 CFLAGS = @CFLAGS@ @MPI_OPT_FLAGS@
 SFLAGS = @MPI_SFLAGS@
 
-SUFFIXES = .S .s
-
 EXTRA_DIST = config.links
 DISTCLEANFILES = mpih-add1.S mpih-mul1.S mpih-mul2.S mpih-mul3.S  \
                 mpih-lshift.S mpih-rshift.S mpih-sub1.S asm-syntax.h sysdep.h
+CLEANFILES = tmp-*.s
 
 
 noinst_LIBRARIES = libmpi.a
 # noinst_HEADERS   =
 
 
-
 libmpi_a_SOURCES = longlong.h    \
              mpi-add.c      \
              mpi-bit.c      \
@@ -51,3 +49,11 @@ common_asm_objects = mpih-mul1.o    \
 libmpi_a_DEPENDENCIES = $(common_asm_objects) @MPI_EXTRA_ASM_OBJS@
 libmpi_a_LIBADD = $(common_asm_objects) @MPI_EXTRA_ASM_OBJS@
 
+SUFFIXES = .S
+
+.S.o:
+       $(CPP) $(INCLUDES) $(DEFS) $< | grep -v '^#' >tmp-$*.s
+       $(CC) $(CFLAGS) $(SFLAGS) -c tmp-$*.s
+       mv tmp-$*.o $@
+       rm -f tmp-$*.s
+