.links: Drop obsolete `lib-config.in' file.
[u/mdw/catacomb] / des.c
diff --git a/des.c b/des.c
index 822a12f..e2f0761 100644 (file)
--- a/des.c
+++ b/des.c
@@ -1,13 +1,13 @@
 /* -*-c-*-
  *
- * $Id: des.c,v 1.3 2004/04/08 01:36:15 mdw Exp $
+ * $Id$
  *
  * The Data Encryption Standard
  *
  * (c) 1999 Straylight/Edgeware
  */
 
-/*----- Licensing notice --------------------------------------------------* 
+/*----- Licensing notice --------------------------------------------------*
  *
  * This file is part of Catacomb.
  *
  * it under the terms of the GNU Library General Public License as
  * published by the Free Software Foundation; either version 2 of the
  * License, or (at your option) any later version.
- * 
+ *
  * Catacomb is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU Library General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Library General Public
  * License along with Catacomb; if not, write to the Free
  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@@ -102,6 +102,43 @@ static void permute(const char *p, uint32 a, uint32 b, uint32 *d)
   d[1] = y;
 }
 
+/* --- @des_expand@ --- *
+ *
+ * Arguments:  @const octet *k@ = pointer to key material
+ *             @size_t n@ = number of octets of key material (7 or 8)
+ *             @uint32 *xx, *yy@ = where to put the results
+ *
+ * Returns:    ---
+ *
+ * Use:                Extracts 64 bits of key material from the given buffer,
+ *             possibly expanding it from 56 to 64 bits on the way.
+ *             Parity is set correctly if the key is expanded.
+ */
+
+void des_expand(const octet *k, size_t n, uint32 *xx, uint32 *yy)
+{
+  uint32 x, y, z;
+
+  if (n == 8) {
+    x = LOAD32(k + 0);
+    y = LOAD32(k + 4);
+  } else {
+    x = LOAD32(k + 0);
+    x = (x & 0xfe000000) | ((x & 0x01fffff0) >> 1);
+    x = (x & 0xfffe0000) | ((x & 0x0001fff8) >> 1);
+    x = (x & 0xfffffe00) | ((x & 0x000001fc) >> 1);
+    z = x; z ^= z >> 4; z ^= z >> 2; z ^= z >> 1;
+    x |= (z & 0x01010101) ^ 0x01010101;
+    y = LOAD32(k + 3) << 1; /* Note: misaligned */
+    y = (y & 0x000000fe) | ((y & 0x1fffff00) << 1);
+    y = (y & 0x0000fefe) | ((y & 0x3fff0000) << 1);
+    y = (y & 0x00fefefe) | ((y & 0x7f000000) << 1);
+    z = y; z ^= z >> 4; z ^= z >> 2; z ^= z >> 1;
+    y |= (z & 0x01010101) ^ 0x01010101;
+  }
+  *xx = x; *yy = y;
+}
+
 /* --- @des_init@ --- *
  *
  * Arguments:  @des_ctx *k@ = pointer to key block
@@ -121,6 +158,7 @@ void des_init(des_ctx *k, const void *buf, size_t sz)
 {
   uint32 x, y;
   uint32 *kp = k->k;
+  uint32 ka[2];
   int i;
 
   /* --- @pc1@ --- *
@@ -132,15 +170,15 @@ void des_init(des_ctx *k, const void *buf, size_t sz)
    */
 
   static const char pc1[] = {
-     0,  0,  0,  0,
+     0,         0,  0,  0,
     57, 49, 41, 33, 25, 17,  9,
      1, 58, 50, 42, 34, 26, 18,
-    10,  2, 59, 51, 43, 35, 27,
+    10,         2, 59, 51, 43, 35, 27,
     19, 11,  3, 60, 52, 44, 36,
-     0,  0,  0,  0,
+     0,         0,  0,  0,
     63, 55, 47, 39, 31, 23, 15,
      7, 62, 54, 46, 38, 30, 22,
-    14,  6, 61, 53, 45, 37, 29,
+    14,         6, 61, 53, 45, 37, 29,
     21, 13,  5, 28, 20, 12,  4
   };
 
@@ -160,14 +198,14 @@ void des_init(des_ctx *k, const void *buf, size_t sz)
    */
 
   static const char pc2[] = {
-     0,  0,  3 + 4, 28 + 4, 15 + 4,  6 + 4, 21 + 4, 10 + 4, /* S-box 2 */
-     0,  0, 16 + 4,  7 + 4, 27 + 4, 20 + 4, 13 + 4,  2 + 4, /* S-box 4 */
-     0,  0, 30 + 8, 40 + 8, 51 + 8, 45 + 8, 33 + 8, 48 + 8, /* S-box 6 */
-     0,  0, 46 + 8, 42 + 8, 50 + 8, 36 + 8, 29 + 8, 32 + 8, /* S-box 8 */
-     0,  0, 14 + 4, 17 + 4, 11 + 4, 24 + 4,  1 + 4,  5 + 4, /* S-box 1 */
-     0,  0, 23 + 4, 19 + 4, 12 + 4,  4 + 4, 26 + 4,  8 + 4, /* S-box 3 */
-     0,  0, 41 + 8, 52 + 8, 31 + 8, 37 + 8, 47 + 8, 55 + 8, /* S-box 5 */
-     0,  0, 44 + 8, 49 + 8, 39 + 8, 56 + 8, 34 + 8, 53 + 8  /* S-box 7 */
+     0,         0,  3 + 4, 28 + 4, 15 + 4,  6 + 4, 21 + 4, 10 + 4, /* S-box 2 */
+     0,         0, 16 + 4,  7 + 4, 27 + 4, 20 + 4, 13 + 4,  2 + 4, /* S-box 4 */
+     0,         0, 30 + 8, 40 + 8, 51 + 8, 45 + 8, 33 + 8, 48 + 8, /* S-box 6 */
+     0,         0, 46 + 8, 42 + 8, 50 + 8, 36 + 8, 29 + 8, 32 + 8, /* S-box 8 */
+     0,         0, 14 + 4, 17 + 4, 11 + 4, 24 + 4,  1 + 4,  5 + 4, /* S-box 1 */
+     0,         0, 23 + 4, 19 + 4, 12 + 4,  4 + 4, 26 + 4,  8 + 4, /* S-box 3 */
+     0,         0, 41 + 8, 52 + 8, 31 + 8, 37 + 8, 47 + 8, 55 + 8, /* S-box 5 */
+     0,         0, 44 + 8, 49 + 8, 39 + 8, 56 + 8, 34 + 8, 53 + 8  /* S-box 7 */
   };
 
   /* --- @v@ --- *
@@ -187,29 +225,12 @@ void des_init(des_ctx *k, const void *buf, size_t sz)
    */
 
   KSZ_ASSERT(des, sz);
-
-  if (sz == 8) {
-    const octet *p = buf;
-    x = LOAD32(p); y = LOAD32(p + 4);
-  } else {
-    const octet *p = buf;
-    x = LOAD32(p);
-    x = (x & 0xfe000000) | ((x & 0x01fffff0) >> 1);
-    x = (x & 0xfffe0000) | ((x & 0x0001fff8) >> 1);
-    x = (x & 0xfffffe00) | ((x & 0x000001fc) >> 1);
-    y = LOAD32(p + 3) << 1; /* Note: misaligned */
-    y = (y & 0x000000fe) | ((y & 0x1fffff00) << 1);
-    y = (y & 0x0000fefe) | ((y & 0x3fff0000) << 1);
-    y = (y & 0x00fefefe) | ((y & 0x7f000000) << 1);
-  }
+  des_expand(buf, sz, &x, &y);
 
   /* --- Permute using the pointless PC1 --- */
 
-  {
-    uint32 ka[2];
-    permute(pc1, x, y, ka);
-    x = ka[0]; y = ka[1];
-  }
+  permute(pc1, x, y, ka);
+  x = ka[0]; y = ka[1];
 
   /* --- Now for the key schedule proper --- */