*** empty log message ***
authorWerner Koch <wk@gnupg.org>
Mon, 28 Sep 1998 19:25:17 +0000 (19:25 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 28 Sep 1998 19:25:17 +0000 (19:25 +0000)
13 files changed:
Makefile.am
README
THANKS
acconfig.h
acinclude.m4
cipher/ChangeLog
cipher/Makefile.am
cipher/des.c
cipher/md.c
cipher/pubkey.c
cipher/tiger.c
configure.in
doc/Makefile.am

index 0699aac..43e2a28 100644 (file)
@@ -1,7 +1,7 @@
 ## Process this file with automake to produce Makefile.in
 
 SUBDIRS =  intl po zlib util mpi cipher tools g10 doc checks
-EXTRA_DIST = VERSION
+EXTRA_DIST = VERSION  PROJECTS
 
 
 dist-hook:
diff --git a/README b/README
index 31cae55..216d84f 100644 (file)
--- a/README
+++ b/README
@@ -1,5 +1,3 @@
------BEGIN PGP SIGNED MESSAGE-----
-
                  GNUPG - The GNU Privacy Guard
                 -------------------------------
                          Version 0.4
@@ -49,7 +47,7 @@
     The default algorithms are now DSA and ELGamal.  ELGamal for signing
     is still available, but due to the larger size of such signatures it
     is depreciated (Please note that the GNUPG implementation of ElGamal
-    signatures is *not* insecure).  Symmetric algorithms are: Blowfish
+    signatures is *not* insecure).  Symmetric algorithms are: 3DES, Blowfish
     and CAST5, Digest algorithms are MD5, RIPEMD160, SHA1 and TIGER/192.
 
 
@@ -57,7 +55,9 @@
     Installation
     ------------
 
-    See the file INSTALL.  Here is a quick summary:
+    Please read the file INSTALL.
+
+    Here is a quick summary:
 
     1) "./configure"
 
     ugly data structures, weird usage of filenames and other things.
 
     The primary FTP site is "ftp://ftp.guug.de/pub/gcrypt/"
-    The primary WWW page is "http://www.d.shuttle.de/isil/crypt/gnupg.html"
+    The primary WWW page is "http://www.d.shuttle.de/isil/gnupg/"
 
     If you like, send your keys to <gnupg-keys@isil.d.shuttle.de>; use
     "gpg --export --armor | mail gnupg-keys@isil.d.shuttle.de" to do this.
     post them to the mailing list <g10@net.lut.ac.uk> (this is a closed list,
     please subscribe before posting).
 
------BEGIN PGP SIGNATURE-----
-Version: GNUPG v0.3.5a (GNU/Linux)
-Comment: Get GNUPG from ftp://ftp.guug.de/pub/gcrypt/
-
-iQB1AwUBNgJ6bB0Z9MEMmFelAQEBHgL+JhFVCrTAK2G3NVVVQBHXU5eucNx3tQQE3UucvSBA
-YaKfX8dC5QU7wfgv8nFBXMK2mnAcJhJzBT6mZwxpzTZZTh7IS4qu//R9Vgy3A06ZddxKFf2M
-YFelmgdpqTL6ntJC
-=JZ3m
------END PGP SIGNATURE-----
diff --git a/THANKS b/THANKS
index 67d97c9..000b24d 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -15,12 +15,17 @@ Detlef Lannert              lannert@lannert.rz.uni-duesseldorf.de
 Ed Boraas              ecxjo@esperanto.org
 Ernst Molitor          ernst.molitor@uni-bonn.de
 Frank Heckenbach       heckenb@mi.uni-erlangen.de
+Gaël Quéri             gqueri@mail.dotcom.fr
 Hendrik Buschkamp      buschkamp@rheumanet.org
+Holger Schurig         holger@d.om.org
+Hugh Daniel            hugh@toad.com
 Ian McKellar           imckellar@harvestroad.com.au
 James Troup            james@nocrew.org
 Jean-loup Gailly       gzip@prep.ai.mit.edu
 Jens Bachem            bachem@rrz.uni-koeln.de
 Jörg Schilling         schilling@fokus.gmd.de
+Karl Fogel             kfogel@guanabana.onshore.com
+Karsten Thygesen       karthy@kom.auc.dk
 Lars Kellogg-Stedman   lars@bu.edu
 Marco d'Itri            md@linux.it
 Mark Adler             madler@alumni.caltech.edu
@@ -37,9 +42,10 @@ Paul D. Smith                psmith@baynetworks.com
 Peter Gutmann          pgut001@cs.auckland.ac.nz
 QingLong               qinglong@bolizm.ihep.su
 Ralph Gillen           gillen@theochem.uni-duesseldorf.de
+Roland Rosenfeld       roland@spinnaker.rhein.de
 Serge Munhoven         munhoven@mema.ucl.ac.be
 Steffen Ullrich        ccrlphr@xensei.com
-Steffen Zahn           Steffen.Zahn@oen.siemens.de
+Steffen Zahn           zahn@berlin.snafu.de
 Thomas Roessler        roessler@guug.de
 Tom Spindler           dogcow@home.merit.edu
 Tom Zerucha            tzeruch@ceddec.com
index 1956d3c..7bd2614 100644 (file)
@@ -80,6 +80,7 @@
 
 #undef USE_SHM_COPROCESSING
 
+#undef IPC_HAVE_SHM_LOCK
 #undef IPC_RMID_DEFERRED_RELEASE
 
 @BOTTOM@
index b6c1f65..f540edc 100644 (file)
@@ -116,6 +116,7 @@ define(WK_CHECK_CACHE,
 
 ######################################################################
 # Check for SysV IPC  (from GIMP)
+#   And see whether we have a SHM_LOCK (FreeBSD does not have it).
 ######################################################################
 dnl WK_CHECK_IPC
 dnl
@@ -150,6 +151,15 @@ define(WK_CHECK_IPC,
        AC_MSG_RESULT(yes),
        AC_MSG_RESULT(no),
        AC_MSG_RESULT(assuming no))
+      AC_MSG_CHECKING(whether SHM_LOCK is available)
+      AC_TRY_COMPILE([#include <sys/types.h>
+           #include <sys/ipc.h>
+           #include <sys/shm.h>],[
+           int foo( int shm_id ) {  shmctl(shm_id, SHM_LOCK, 0); }
+           ],
+       AC_DEFINE(IPC_HAVE_SHM_LOCK)
+       AC_MSG_RESULT(yes),
+       AC_MSG_RESULT(no))
     fi
   ])
 
@@ -165,6 +175,7 @@ define(WK_CHECK_MLOCK,
     if test "$ac_cv_func_mlock" = "yes"; then
        AC_MSG_CHECKING(whether mlock is broken)
          AC_TRY_RUN([
+               #include <stdlib.h>
                #include <unistd.h>
                #include <errno.h>
                #include <sys/mman.h>
index cbcea5f..251f4df 100644 (file)
@@ -1,3 +1,16 @@
+Mon Sep 28 13:23:09 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * md.c (md_digest): New.
+       (md_reset): New.
+
+Wed Sep 23 12:27:02 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * tiger.c (TIGER_CONTEXT): moved "buf", so that it is 64 bit aligned.
+
+Mon Sep 21 06:22:53 1998  Werner Koch  (wk@(none))
+
+       * des.c: Some patches from Michael.
+
 Thu Sep 17 19:00:06 1998  Werner Koch  (wk@(none))
 
        * des.c : New file from Michael Roth <mroth@nessie.de>
index 09edd4d..26c625d 100644 (file)
@@ -48,11 +48,11 @@ EXTRA_twofish_SOURCES = twofish.c
 
 
 tiger: $(srcdir)/tiger.c
-       `echo $(COMPILE) -shared  -fPIC -o tiger $(srcdir)/tiger.c | \
+       `echo $(COMPILE) -shared  -fPIC -lc -o tiger $(srcdir)/tiger.c | \
            sed -e 's/-O2/-O1/' `
 
 twofish: $(srcdir)/twofish.c
-       `echo $(COMPILE) -shared  -fPIC -o twofish $(srcdir)/twofish.c | \
+       `echo $(COMPILE) -shared  -fPIC -lc -o twofish $(srcdir)/twofish.c | \
            sed -e 's/-O2/  /' `
 
 
index f10716a..ef8ce7d 100644 (file)
  */
 typedef struct _des_ctx
   {
-    int mode;
     u32 encrypt_subkeys[32];
     u32 decrypt_subkeys[32];
   }
@@ -163,19 +162,19 @@ des_ctx[1];
  */
 typedef struct _tripledes_ctx
   {
-    int mode;
     u32 encrypt_subkeys[96];
     u32 decrypt_subkeys[96];
   }
 tripledes_ctx[1];
 
 
-static void des_key_schedule (const byte *, u32 *, int);
+static void des_key_schedule (const byte *, u32 *);
 static int des_setkey (struct _des_ctx *, const byte *);
 static int des_ecb_crypt (struct _des_ctx *, const byte *, byte *, int);
 static int tripledes_set2keys (struct _tripledes_ctx *, const byte *, const byte *);
 static int tripledes_set3keys (struct _tripledes_ctx *, const byte *, const byte *, const byte *);
 static int tripledes_ecb_crypt (struct _tripledes_ctx *, const byte *, byte *, int);
+static int is_weak_key ( const byte *key );
 static const char *selftest (void);
 
 
@@ -308,18 +307,58 @@ u32 rightkey_swap[16] =
 
 /*
  * Numbers of left shifts per round for encryption subkey schedule
+ * To calculate the decryption key scheduling we just reverse the
+ * ordering of the subkeys so we can omit the table for decryption
+ * subkey schedule.
  */
 static byte encrypt_rotate_tab[16] =
 {
   1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
 };
 
+
+
 /*
- * Numbers of right shifts per round for decryption subkey schedule
+ * Table with weak DES keys sorted in ascending order.
+ * In DES their are 64 known keys wich are weak. They are weak
+ * because they produce only one, two or four different
+ * subkeys in the subkey scheduling process.
+ * The keys in this table have all their parity bits cleared.
  */
-static byte decrypt_rotate_tab[16] =
+static byte weak_keys[64][8] =
 {
-  0, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },  { 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e },
+  { 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0 },  { 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe },
+  { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e },  { 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00 },
+  { 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe },  { 0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0 },
+  { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0 },  { 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe },
+  { 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00 },  { 0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e },
+  { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe },  { 0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0 },
+  { 0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e },  { 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00 },
+  { 0x0e, 0x0e, 0x0e, 0x0e, 0xf0, 0xf0, 0xf0, 0xf0 },  { 0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e },
+  { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 },  { 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe },
+  { 0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0 },  { 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00 },
+  { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e },  { 0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0 },
+  { 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe },  { 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe },
+  { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 },  { 0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e },
+  { 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00 },  { 0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0 },
+  { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe },  { 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00 },
+  { 0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e },  { 0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0 },
+  { 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe },  { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 },
+  { 0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e },  { 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe },
+  { 0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0 },  { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e },
+  { 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00 },  { 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00 },
+  { 0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e },  { 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe },
+  { 0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e },  { 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00 },
+  { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe },  { 0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0 },
+  { 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe },  { 0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0 },
+  { 0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e },  { 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00 },
+  { 0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0 },  { 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe },
+  { 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00 },  { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e },
+  { 0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e },  { 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00 },
+  { 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe },  { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 },
+  { 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00 },  { 0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e },
+  { 0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0 },  { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe }
 };
 
 
@@ -359,7 +398,7 @@ static byte decrypt_rotate_tab[16] =
 
 
 /*
- * A full DES round including 'expansion funtion', 'sbox substitution'
+ * A full DES round including 'expansion function', 'sbox substitution'
  * and 'primitive function P' but without swapping the left and right word.
  */
 #define DES_ROUND(from, to, work, subkey)              \
@@ -403,23 +442,22 @@ static byte decrypt_rotate_tab[16] =
 
 
 /*
- * des_key_schedule():   Calculate 16 subkeys pairs (even/odd) for one DES round
+ * des_key_schedule():   Calculate 16 subkeys pairs (even/odd) for
+ *                       16 encryption rounds.
+ *                       To calculate subkeys for decryption the caller
+ *                       have to reorder the generated subkeys.
  *
  *    rawkey:      8 Bytes of key data
  *    subkey:      Array of at least 32 u32s. Will be filled
  *                 with calculated subkeys.
- *    mode:        Key schedule mode.
- *                 mode == 0:  Calculate subkeys to encrypt
- *                 mode != 0:  Calculate subkeys to decrypt
  *
  */
 static void
-des_key_schedule (const byte * rawkey, u32 * subkey, int mode)
+des_key_schedule (const byte * rawkey, u32 * subkey)
 {
   u32 left, right, work;
   int round;
 
-
   READ_64BIT_DATA (rawkey, left, right)
 
   DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f)
@@ -441,20 +479,8 @@ des_key_schedule (const byte * rawkey, u32 * subkey, int mode)
 
   for (round = 0; round < 16; ++round)
     {
-      if (mode)
-       {
-         /* decrypt */
-
-         left = ((left >> decrypt_rotate_tab[round]) | (left << (28 - decrypt_rotate_tab[round]))) & 0x0fffffff;
-         right = ((right >> decrypt_rotate_tab[round]) | (right << (28 - decrypt_rotate_tab[round]))) & 0x0fffffff;
-       }
-      else
-       {
-         /* encrypt */
-
-         left = ((left << encrypt_rotate_tab[round]) | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
-         right = ((right << encrypt_rotate_tab[round]) | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
-       }
+      left = ((left << encrypt_rotate_tab[round]) | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
+      right = ((right << encrypt_rotate_tab[round]) | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
 
       *subkey++ = ((left << 4) & 0x24000000)
        | ((left << 28) & 0x10000000)
@@ -514,11 +540,15 @@ des_key_schedule (const byte * rawkey, u32 * subkey, int mode)
 static int
 des_setkey (struct _des_ctx *ctx, const byte * key)
 {
-  if (!ctx || !key)
-    return -1;
+  int i;
 
-  des_key_schedule (key, ctx->encrypt_subkeys, 0);
-  des_key_schedule (key, ctx->decrypt_subkeys, 1);
+  des_key_schedule (key, ctx->encrypt_subkeys);
+
+  for(i=0; i<32; i+=2)
+    {
+      ctx->decrypt_subkeys[i]  = ctx->encrypt_subkeys[30-i];
+      ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i];
+    }
 
   return 0;
 }
@@ -535,9 +565,6 @@ des_ecb_crypt (struct _des_ctx *ctx, const byte * from, byte * to, int mode)
   u32 left, right, work;
   u32 *keys;
 
-  if (!ctx || !from || !to)
-    return -1;
-
   keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
 
   READ_64BIT_DATA (from, left, right)
@@ -570,17 +597,25 @@ tripledes_set2keys (struct _tripledes_ctx *ctx,
                    const byte * key1,
                    const byte * key2)
 {
-  if (!ctx || !key1 || !key2)
-    return -1;
+  int i;
+
+  des_key_schedule (key1, ctx->encrypt_subkeys);
+  des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
 
-  des_key_schedule (key1, ctx->encrypt_subkeys, 0);
-  des_key_schedule (key1, ctx->decrypt_subkeys, 1);
+  for(i=0; i<32; i+=2)
+    {
+      ctx->decrypt_subkeys[i]   = ctx->encrypt_subkeys[30-i];
+      ctx->decrypt_subkeys[i+1]  = ctx->encrypt_subkeys[31-i];
+
+      ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i];
+      ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i];
 
-  des_key_schedule (key2, &(ctx->encrypt_subkeys[32]), 1);
-  des_key_schedule (key2, &(ctx->decrypt_subkeys[32]), 0);
+      ctx->encrypt_subkeys[i+64] = ctx->encrypt_subkeys[i];
+      ctx->encrypt_subkeys[i+65] = ctx->encrypt_subkeys[i+1];
 
-  des_key_schedule (key1, &(ctx->encrypt_subkeys[64]), 0);
-  des_key_schedule (key1, &(ctx->decrypt_subkeys[64]), 1);
+      ctx->decrypt_subkeys[i+64] = ctx->decrypt_subkeys[i];
+      ctx->decrypt_subkeys[i+65] = ctx->decrypt_subkeys[i+1];
+    }
 
   return 0;
 }
@@ -598,17 +633,23 @@ tripledes_set3keys (struct _tripledes_ctx *ctx,
                    const byte * key2,
                    const byte * key3)
 {
-  if (!ctx || !key1 || !key2 || !key3)
-    return -1;
+  int i;
 
-  des_key_schedule (key1, ctx->encrypt_subkeys, 0);
-  des_key_schedule (key1, ctx->decrypt_subkeys, 1);
+  des_key_schedule (key1, ctx->encrypt_subkeys);
+  des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
+  des_key_schedule (key3, &(ctx->encrypt_subkeys[64]));
 
-  des_key_schedule (key2, &(ctx->encrypt_subkeys[32]), 1);
-  des_key_schedule (key2, &(ctx->decrypt_subkeys[32]), 0);
+  for(i=0; i<32; i+=2)
+    {
+      ctx->decrypt_subkeys[i]   = ctx->encrypt_subkeys[94-i];
+      ctx->decrypt_subkeys[i+1]  = ctx->encrypt_subkeys[95-i];
+
+      ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i];
+      ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i];
 
-  des_key_schedule (key3, &(ctx->encrypt_subkeys[64]), 0);
-  des_key_schedule (key3, &(ctx->decrypt_subkeys[64]), 1);
+      ctx->decrypt_subkeys[i+64] = ctx->encrypt_subkeys[30-i];
+      ctx->decrypt_subkeys[i+65] = ctx->encrypt_subkeys[31-i];
+    }
 
   return 0;
 }
@@ -617,6 +658,7 @@ tripledes_set3keys (struct _tripledes_ctx *ctx,
 
 /*
  * Electronic Codebook Mode Triple-DES encryption/decryption of data according to 'mode'.
+ * Sometimes this mode is named 'EDE' mode (Encryption-Decryption-Encryption).
  */
 static int
 tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, byte * to, int mode)
@@ -624,9 +666,6 @@ tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, byte * to, i
   u32 left, right, work;
   u32 *keys;
 
-  if (!ctx || !from || !to)
-    return -1;
-
   keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
 
   READ_64BIT_DATA (from, left, right)
@@ -666,17 +705,45 @@ tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from, byte * to, i
 }
 
 
+
 /*
  * Check whether the 8 byte key is weak.
+ * Dose not check the parity bits of the key but simple ignore them.
  */
-
 static int
-is_weak_key ( byte *key )
+is_weak_key ( const byte *key )
 {
-    return 0; /* FIXME */
+  byte work[8];
+  int i, left, right, middle, cmp_result;
+
+  /* clear parity bits */
+  for(i=0; i<8; ++i)
+     work[i] = key[i] & 0xfe;
+
+  /* binary search in the weak key table */
+  left = 0;
+  right = 63;
+  while(1)
+    {
+      middle = (left + right) / 2;
+
+      if ( !(cmp_result=memcmp(work, weak_keys[middle], 8)) )
+         return -1;
+
+      if ( left == right )
+         break;
+
+      if ( cmp_result > 0 )
+         left = middle + 1;
+      else
+         right = middle - 1;
+    }
+
+  return 0;
 }
 
 
+
 /*
  * Performs a selftest of this DES/Triple-DES implementation.
  * Returns an string with the error text on failure.
@@ -717,12 +784,14 @@ selftest (void)
        memcpy (input, temp1, 8);
       }
     if (memcmp (temp3, result, 8))
-      return "DES maintenace test failed.";
+      return "DES maintenance test failed.";
   }
 
 
   /*
-   * Triple-DES test  (Does somebody known on official test?)
+   * Triple-DES test  (Do somebody known on official test?)
+   *
+   * FIXME: This test doesn't use tripledes_set3keys() !
    */
   {
     int i;
@@ -749,6 +818,20 @@ selftest (void)
       return "TRIPLE-DES test failed.";
   }
 
+
+  /*
+   * Check the weak key detection. We simply assume the table with
+   * weak keys is ok and check every key in the table if it is
+   * detected... (This test is a little bit stupid)
+   */
+  {
+    int i;
+
+    for (i = 0; i < 64; ++i)
+       if (!is_weak_key(weak_keys[i]))
+           return "DES weak key detection failed";
+  }
+
   return 0;
 }
 
@@ -759,11 +842,11 @@ do_tripledes_setkey ( struct _tripledes_ctx *ctx, byte *key, unsigned keylen )
     if( keylen != 24 )
        return G10ERR_WRONG_KEYLEN;
 
+    tripledes_set3keys ( ctx, key, key+8, key+16);
+
     if( is_weak_key( key ) || is_weak_key( key+8 ) || is_weak_key( key+16 ) )
        return G10ERR_WEAK_KEY;
 
-    tripledes_set3keys ( ctx, key, key+8, key+16);
-
     return 0;
 }
 
@@ -800,7 +883,7 @@ des_get_info( int algo, size_t *keylen,
     if( !did_selftest ) {
        const char *s = selftest();
        if( s )
-           log_fatal("selftest failed: %s", s );
+           log_fatal("selftest failed: %s\n", s );
        did_selftest = 1;
     }
 
index 56f639c..a041552 100644 (file)
@@ -256,7 +256,7 @@ md_copy( MD_HANDLE a )
                  : m_alloc( sizeof *b );
     memcpy( b, a, sizeof *a );
     b->list = NULL;
-    /* and now copy the compelte list of algorithms */
+    /* and now copy the complete list of algorithms */
     /* I know that the copied list is reversed, but that doesn't matter */
     for( ar=a->list; ar; ar = ar->next ) {
        br = a->secure ? m_alloc_secure( sizeof *br + ar->contextsize )
@@ -269,6 +269,23 @@ md_copy( MD_HANDLE a )
 }
 
 
+/****************
+ * Reset all contexts and discard any buffered stuuf.  This may be used
+ * instead of a md_close(); md_open().
+ */
+void
+md_reset( MD_HANDLE a )
+{
+    struct md_digest_list_s *r;
+
+    a->bufcount = 0;
+    for( r=a->list; r; r = r->next ) {
+       memset( r->context, 0, r->contextsize );
+       (*r->init)( &r->context );
+    }
+}
+
+
 void
 md_close(MD_HANDLE a)
 {
@@ -331,7 +348,7 @@ md_read( MD_HANDLE a, int algo )
     if( !algo ) {  /* return the first algorithm */
        if( (r=a->list) ) {
            if( r->next )
-               log_error("warning: more than algorithm in md_read(0)\n");
+               log_debug("more than algorithm in md_read(0)\n");
            return (*r->read)( &r->context );
        }
     }
@@ -344,6 +361,58 @@ md_read( MD_HANDLE a, int algo )
     return NULL;
 }
 
+
+/****************
+ * This function combines md_final and md_read but keeps the context
+ * intact.  This function can be used to calculate intermediate
+ * digests.  The digest is copied into buffer and the digestlength is
+ * returned.  If buffer is NULL only the needed size for buffer is returned.
+ * buflen gives the max size of buffer. If the buffer is too shourt to
+ * hold the complete digest, the buffer is filled with as many bytes are
+ * possible and this value is returned.
+ */
+int
+md_digest( MD_HANDLE a, int algo, byte *buffer, int buflen )
+{
+    struct md_digest_list_s *r = NULL;
+    char *context;
+    char *digest;
+
+    if( a->bufcount )
+       md_write( a, NULL, 0 );
+
+    if( !algo ) {  /* return digest for the first algorithm */
+       if( (r=a->list) && r->next )
+           log_debug("more than algorithm in md_digest(0)\n");
+    }
+    else {
+       for(r=a->list; r; r = r->next )
+           if( r->algo == algo )
+               break;
+    }
+    if( !r )
+       BUG();
+
+    if( !buffer )
+       return r->mdlen;
+
+    /* I don't want to change the interface, so I simply work on a copy
+     * the context (extra overhead - should be fixed)*/
+    context = a->secure ? m_alloc_secure( r->contextsize )
+                       : m_alloc( r->contextsize );
+    memcpy( context, r->context, r->contextsize );
+    (*r->final)( context );
+    digest = (*r->read)( context );
+
+    if( buflen > r->mdlen )
+       buflen = r->mdlen;
+    memcpy( buffer, digest, buflen );
+
+    m_free(context);
+    return buflen;
+}
+
+
 int
 md_get_algo( MD_HANDLE a )
 {
@@ -423,5 +492,13 @@ md_stop_debug( MD_HANDLE md )
        fclose(md->debug);
        md->debug = NULL;
     }
+  #ifdef HAVE_U64_TYPEDEF
+    {  /* a kludge to pull in the __muldi3 for Solaris */
+       volatile u32 a = (u32)md;
+       volatile u32 b = 42;
+       volatile u64 c;
+       c = a * b;
+    }
+  #endif
 }
 
index a78f788..62a48a6 100644 (file)
@@ -480,7 +480,7 @@ pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
 
 /****************
  * This is the interface to the public key signing.
- * Sign hash with skey and put the result into resarr which
+ * Sign data with skey and put the result into resarr which
  * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
  * algorithm allows this - check with pubkey_get_nsig() )
  */
index d02f5cb..c473e92 100644 (file)
@@ -29,9 +29,9 @@
 
 typedef struct {
     u64  a, b, c;
-    u32  nblocks;
     byte buf[64];
     int  count;
+    u32  nblocks;
 } TIGER_CONTEXT;
 
 
index bbb3eb9..bd5bc7b 100644 (file)
@@ -254,14 +254,15 @@ fi
 AC_SUBST(ZLIBS)
 
 
-AM_GNU_GETTEXT
 G10_LOCALEDIR="$g10_prefix/$DATADIRNAME/locale"
 AC_SUBST(G10_LOCALEDIR)
 AC_DEFINE_UNQUOTED(G10_LOCALEDIR, "$G10_LOCALEDIR")
-WK_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl )
+dnl WK_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl )
 
 WK_DO_LINK_FILES
 
+AM_GNU_GETTEXT
+
 AC_OUTPUT([
 Makefile
 intl/Makefile
index dc2ee58..9c83575 100644 (file)
@@ -1,9 +1,18 @@
 ## Process this file with automake to create Makefile.in
 
-EXTRA_DIST = DETAILS rfcs gpg.1pod gpg.1 FAQ
+EXTRA_DIST = DETAILS rfcs gpg.1pod gpg.1 FAQ  HACKING
 
 man_MANS = gpg.1
 
+
+
+install-data-hook:
+        if test -f $(man1dir)/gpgm.1; then rm $(man1dir)/gpgm.1; fi
+        ln -s $(man1dir)/gpg.1 $(man1dir)/gpgm.1 \
+           || ln $(man1dir)/gpg.1 $(man1dir)/gpgm.1
+
+
+
 %: %pod
         pod2man $< --section=`echo $@ | sed 's/^.*(?)$$/$$&/'`\
                    --release="`date -r $< '+%d %b %Y'`"\