General utilities cleanup. Add signature support to catcrypt. Throw in
[u/mdw/catacomb] / idea.c
diff --git a/idea.c b/idea.c
index f554bf4..ae4aa2d 100644 (file)
--- a/idea.c
+++ b/idea.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: idea.c,v 1.1 1999/09/03 08:41:12 mdw Exp $
+ * $Id: idea.c,v 1.5 2004/04/08 01:36:15 mdw Exp $
  *
  * Implementation of the IDEA cipher
  *
  * MA 02111-1307, USA.
  */
 
-/*----- Revision history --------------------------------------------------* 
- *
- * $Log: idea.c,v $
- * Revision 1.1  1999/09/03 08:41:12  mdw
- * Initial import.
- *
- */
-
 /*----- Header files ------------------------------------------------------*/
 
 #include <assert.h>
 #include <mLib/bits.h>
 
 #include "blkc.h"
+#include "gcipher.h"
 #include "idea.h"
 
+/*----- Global variables --------------------------------------------------*/
+
+const octet idea_keysz[] = { KSZ_SET, IDEA_KEYSZ };
+
 /*----- Main code ---------------------------------------------------------*/
 
 /* --- @inv@ --- *
@@ -63,13 +60,16 @@ static uint16 inv(uint16 n)
 {
   uint32 m = 0x10001;
   uint32 a = 1, b = 0;
+  uint32 nn = n;
 
+  if (!nn)
+    nn = 0x10000;
   for (;;) {
     uint32 q, r, t;
-    if (!(r = m % n))
+    if (!(r = m % nn))
       break;
-    q = m / n;
-    m = nn = r;
+    q = m / nn;
+    m = nn; nn = r;
     t = a; a = b - q * a; b = t;
   }
   if (a > MASK16)
@@ -82,22 +82,21 @@ static uint16 inv(uint16 n)
  * Arguments @x@ and @y@ are two 32-bit values to multiply.  On exit, @x@ is
  * the product of the two arguments.  The result is not normalized back to 16
  * bits; the arguments are not expected to be normalized.
+ *
+ * This code is from `Side Channel Attack Hardening of the IDEA Cipher',
+ * published by Ascom Tech.
  */
 
 #define MUL(x, y) do {                                                 \
-  uint32 _mx, _my = (y);                                               \
-  if ((_mx = U16(x)) == 0)                                             \
-    (x) = 1 - _my;                                                     \
-  else if (_my == 0)                                                   \
-    (x) = 1 - _mx;                                                     \
-  else {                                                               \
-    _my *= _mx;                                                                \
-    _mx = U16(_my); _my >>= 16;                                                \
-    if (_mx < _my)                                                     \
-      (x) = _mx - _my + 1;                                             \
-    else                                                               \
-      (x) = _mx - _my;                                                 \
-  }                                                                    \
+  unsigned _t;                                                         \
+  uint32 _tt;                                                          \
+                                                                       \
+  x = U16(x - 1);                                                      \
+  _t = U16(y - 1);                                                     \
+  _tt = (uint32)x * (uint32)_t + (uint32)x + (uint32)_t + 1;           \
+  x = U16(_tt);                                                                \
+  _t = U16(_tt >> 16);                                                 \
+  x = x - _t + (x <= _t);                                              \
 } while (0)
 
 /* --- @idea_init@ --- *
@@ -115,7 +114,7 @@ static uint16 inv(uint16 n)
 
 void idea_init(idea_ctx *k, const void *buf, size_t sz)
 {
-  assert(((void)"IDEA key must be 128 bits", sz == IDEA_KEYSZ));
+  KSZ_ASSERT(idea, sz);
 
   /* --- Unpack the encryption key --- */
 
@@ -201,28 +200,28 @@ void idea_init(idea_ctx *k, const void *buf, size_t sz)
 /* --- @ROUND@ --- */
 
 #define MIX(k, a, b, c, d) do {                                                \
-  MUL(a, (k)[0]);                                                      \
-  (b) += (k)[1];                                                       \
-  (c) += (k)[2];                                                       \
-  MUL(d, (k)[3]);                                                      \
+  MUL(a, k[0]);                                                                \
+  b += k[1];                                                           \
+  c += k[2];                                                           \
+  MUL(d, k[3]);                                                                \
 } while (0)
 
 #define MA(k, a, b, c, d) do {                                         \
-  unsigned _u = (a) ^ (c);                                             \
-  unsigned _v = (b) ^ (d);                                             \
-  MUL(_u, (k)[4]);                                                     \
+  unsigned _u = a ^ c;                                                 \
+  unsigned _v = b ^ d;                                                 \
+  MUL(_u, k[4]);                                                       \
   _v += _u;                                                            \
-  MUL(_v, (k)[5]);                                                     \
+  MUL(_v, k[5]);                                                       \
   _u += _v;                                                            \
-  (a) ^= _v;                                                           \
-  (b) ^= _u;                                                           \
-  (c) ^= _v;                                                           \
-  (d) ^= _u;                                                           \
+  a ^= _v;                                                             \
+  b ^= _u;                                                             \
+  c ^= _v;                                                             \
+  d ^= _u;                                                             \
 } while (0);
 
 #define ROUND(k, a, b, c, d) do {                                      \
-  MIX((k), (a), (b), (c), (d));                                                \
-  MA((k), (a), (b), (c), (d));                                         \
+  MIX(k, a, b, c, d);                                                  \
+  MA(k, a, b, c, d);                                                   \
   (k) += 6;                                                            \
 } while (0)
 
@@ -244,8 +243,8 @@ void idea_init(idea_ctx *k, const void *buf, size_t sz)
   ROUND(_k, _a, _b, _c, _d);                                           \
   ROUND(_k, _a, _c, _b, _d);                                           \
   MIX  (_k, _a, _c, _b, _d);                                           \
-  (c) = (U16(_a) << 16) | U16(_c);                                     \
-  (d) = (U16(_b) << 16) | U16(_d);                                     \
+  c = ((uint32)U16(_a) << 16) | (uint32)U16(_c);                       \
+  d = ((uint32)U16(_b) << 16) | (uint32)U16(_d);                       \
 } while (0)
 
 #define DBLK(k, a, b) EBLK((k), (a), (b))