*** empty log message ***
[gnupg.git] / cipher / des.c
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;
     }