]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
New files
authorNiels Möller <nisse@lysator.liu.se>
Thu, 3 Sep 1998 06:33:37 +0000 (08:33 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Thu, 3 Sep 1998 06:33:37 +0000 (08:33 +0200)
Rev: src/symmetric/Makefile.in:1.1
Rev: src/symmetric/cast.c:1.1
Rev: src/symmetric/cast_sboxes.h:1.1
Rev: src/symmetric/configure.in:1.1
Rev: src/symmetric/desCode.h:1.1
Rev: src/symmetric/desKerb.c:1.1
Rev: src/symmetric/desQuick.c:1.1
Rev: src/symmetric/desTest.c:1.1
Rev: src/symmetric/desUtil.c:1.1
Rev: src/symmetric/descore.README:1.1
Rev: src/symmetric/desdata.c:1.1
Rev: src/symmetric/desinfo.h:1.1
Rev: src/symmetric/idea.c:1.1
Rev: src/symmetric/include/RCSID.h:1.1
Rev: src/symmetric/include/cast.h:1.1
Rev: src/symmetric/include/crypto_types.h:1.1
Rev: src/symmetric/include/des.h:1.1
Rev: src/symmetric/include/idea.h:1.1
Rev: src/symmetric/include/md5.h:1.1
Rev: src/symmetric/include/rc4.h:1.1
Rev: src/symmetric/include/sha.h:1.1
Rev: src/symmetric/install-sh:1.1
Rev: src/symmetric/md5.c:1.1
Rev: src/symmetric/rc4.c:1.1
Rev: src/symmetric/sha.c:1.1

27 files changed:
.gitattributes [new file with mode: 0644]
.gitignore [new file with mode: 0644]
Makefile.in [new file with mode: 0644]
cast.c [new file with mode: 0644]
cast_sboxes.h [new file with mode: 0644]
configure.in [new file with mode: 0755]
desCode.h [new file with mode: 0644]
desKerb.c [new file with mode: 0644]
desQuick.c [new file with mode: 0644]
desTest.c [new file with mode: 0644]
desUtil.c [new file with mode: 0644]
descore.README [new file with mode: 0644]
desdata.c [new file with mode: 0644]
desinfo.h [new file with mode: 0644]
idea.c [new file with mode: 0644]
include/RCSID.h [new file with mode: 0644]
include/cast.h [new file with mode: 0644]
include/crypto_types.h [new file with mode: 0644]
include/des.h [new file with mode: 0644]
include/idea.h [new file with mode: 0644]
include/md5.h [new file with mode: 0644]
include/rc4.h [new file with mode: 0644]
include/sha.h [new file with mode: 0644]
install-sh [new file with mode: 0755]
md5.c [new file with mode: 0644]
rc4.c [new file with mode: 0644]
sha.c [new file with mode: 0644]

diff --git a/.gitattributes b/.gitattributes
new file mode 100644 (file)
index 0000000..a927944
--- /dev/null
@@ -0,0 +1,2 @@
+[attr]binary -text -crlf -diff -ident
+* text ident
diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..645bd64
--- /dev/null
@@ -0,0 +1,32 @@
+RCS
+SCCS
+CVS
+CVS.adm
+RCSLOG
+cvslog.*
+tags
+TAGS
+.make.state
+.nse_depinfo
+*~
+#*
+.#*
+,*
+_$*
+*$
+*.old
+*.bak
+*.BAK
+*.orig
+*.rej
+.del-*
+*.a
+*.olb
+*.o
+*.obj
+*.so
+*.exe
+*.Z
+*.elc
+*.ln
+core
diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..13441fd
--- /dev/null
@@ -0,0 +1,159 @@
+# $Id$
+#
+# Makefile for low-level crypto library
+
+CC=@CC@
+CPP=@CPP@
+RANLIB=@RANLIB@
+AR=ar
+
+# Reset VPATH
+SRCDIR=@srcdir@
+VPATH=$(SRCDIR):$(SRCDIR)/../include
+
+CRYPTO_INCLUDES=$(SRCDIR)/../include
+
+# Additional C preprocessor flags
+PREFLAGS=$(EXTRA_CPP_FLAGS) -I$(CRYPTO_INCLUDES) -I. -I$(SRCDIR) $(DEFINES)
+
+# The flags to generate a shared library
+CFLAGS=$(PREFLAGS) $(OTHERFLAGS) $(EXTRA_CFLAGS)
+LDFLAGS=@LDFLAGS@
+
+default: algorithms.a
+
+### Magic Makefile for descore
+
+# Interesting defines are sparc, mc68000, vax and i386
+# Rely on gcc defining them appropriately.
+# CPPFLAGS=    -Dsparc         # use 6+8 general regs
+# CPPFLAGS=    -Dmc68000       # use 3+4 addr (1+4 live), and 3+3 data regs
+# CPPFLAGS=    -Dvax           # use 6+0 general regs
+# CPPFLAGS=    -Di386          # use 3+0 regs, and 3+0 normal variables
+
+CODEGEN.c=     $(CC) $(CFLAGS) $(CPPFLAGS) -S
+COMPILE.c=     $(CC) $(CFLAGS) $(CPPFLAGS) -c
+LINK.c=                $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
+
+# hand-entered files that go into the library
+SC=            desKerb.c desUtil.c desQuick.c
+SO=            desKerb.o desUtil.o desQuick.o
+
+# special generated files
+GH=            parity.h rotors.h keymap.h
+GC=            desSmallFips.c desSmallCore.c desQuickFips.c desQuickCore.c
+GI=            desSmallFips.i desSmallCore.i desQuickFips.i desQuickCore.i
+GO=            desSmallFips.o desSmallCore.o desQuickFips.o desQuickCore.o
+
+O=             $(SO) $(GO)
+
+# prefer compilation from .i if .i exists
+#.SUFFIXES:
+#.SUFFIXES:    .i .o .c $(SUFFIXES)
+
+desTest:       desCore.a desTest.o
+               $(LINK.c) -o $@ desTest.o desCore.a
+               ./desTest
+
+# test all performance enhancement flags
+sure:
+               make clean ; make desTest 'CPPFLAGS=-Di386    -Umc68000 -Usparc'
+               make clean ; make desTest 'CPPFLAGS=-Dvax     -Umc68000 -Usparc'
+               make clean ; make desTest 'CPPFLAGS=-Dmc68000 -Usparc'
+               make clean ; make desTest 'CPPFLAGS=-Dsparc   -Umc68000'
+               make clean ; make desTest
+
+clean:
+       -rm -f *.o *.i *.x *.a ./desTest
+       -rm -f $(GC) $(GH) desdata
+
+depend:
+
+desCore.a:     $O
+               $(AR) cru $@ $O
+               $(RANLIB) $@
+
+desdata.o:     desinfo.h $(SRCDIR)/../include/des.h
+desUtil.o:     $(GH)
+$(SO):         $(SRCDIR)/../include/des.h
+$(GI):         desCode.h $(SRCDIR)/../include/des.h Makefile
+desTest.o:     $(SRCDIR)/../include/des.h
+
+$(GH):         desdata
+               ./desdata $@ > $@
+
+desdata:       desdata.o
+               $(LINK.c) -o $@ desdata.o
+
+# new rules  (note: tr|sed|tr is NOT necessary,  just there so .i is readable)
+.c.i:
+       $(CPP) $(CFLAGS) $(CPPFLAGS) $< > $*.x
+       @tr ';'\\012 \\012';' < $*.x |                  \
+        sed    -e 's/[         ][      ]*/ /g'         \
+               -e 's/^ //'                             \
+               -e 's/ $$//'                            \
+               -e '/^$$/d'                             \
+               -e '/^[^;]/s/^/;/'                      \
+               -e 's/#[^;]*;//g'                       \
+               -e 's/\([){]\) *\(register\)/\1;\2/g'   \
+               -e 's/\([[(]\) /\1/g'                   \
+               -e 's/ \([])]\)/\1/g'                   \
+               -e 's/\([^]+0123 ]\) =/\1  =/g'         \
+               -e 's/}/};;/g'                          \
+               -e 's/ *; */;/g'                        \
+               -e 's/;;;*/;;/g'                        \
+               -e '1s/^;*//' |                         \
+        tr ';'\\012 \\012';' > $@
+       @echo ""  >> $@
+#      @echo "}" >> $@                 # last definition must be a procedure
+
+#              -e 's/\(;[kmxyz][0-9]*\)\([^;]*=\)/\1  \2/g'
+
+.i.o:
+               $(CODEGEN.c) $<
+               $(COMPILE.c) $*.s
+
+# slowest to quickest
+desSmallFips.c:
+               @echo '#include "desCode.h"' > $@
+               @echo \
+'ENCRYPT(DesSmallFipsEncrypt,TEMPSMALL,LOADFIPS,KEYMAPSMALL,SAVEFIPS)' >> $@
+               @echo \
+'DECRYPT(DesSmallFipsDecrypt,TEMPSMALL,LOADFIPS,KEYMAPSMALL,SAVEFIPS)' >> $@
+desSmallCore.c:
+               @echo '#include "desCode.h"' > $@
+               @echo \
+'ENCRYPT(DesSmallCoreEncrypt,TEMPSMALL,LOADCORE,KEYMAPSMALL,SAVECORE)' >> $@
+               @echo \
+'DECRYPT(DesSmallCoreDecrypt,TEMPSMALL,LOADCORE,KEYMAPSMALL,SAVECORE)' >> $@
+desQuickFips.c:
+               @echo '#include "desCode.h"' > $@
+               @echo \
+'ENCRYPT(DesQuickFipsEncrypt,TEMPQUICK,LOADFIPS,KEYMAPQUICK,SAVEFIPS)' >> $@
+               @echo \
+'DECRYPT(DesQuickFipsDecrypt,TEMPQUICK,LOADFIPS,KEYMAPQUICK,SAVEFIPS)' >> $@
+desQuickCore.c:
+               @echo '#include "desCode.h"' > $@
+               @echo \
+'ENCRYPT(DesQuickCoreEncrypt,TEMPQUICK,LOADCORE,KEYMAPQUICK,SAVECORE)' >> $@
+               @echo \
+'DECRYPT(DesQuickCoreDecrypt,TEMPQUICK,LOADCORE,KEYMAPQUICK,SAVECORE)' >> $@
+
+### End of rules for desCore
+
+# BEGIN NATIONAL SECURITY
+MASS_DESTRUCTION_OBJS = idea.o rc4.o cast.o $(O)
+# END NATIONAL SECURITY
+
+OBJS = $(MASS_DESTRUCTION_OBJS) sha.o md5.o
+
+algorithms.a: $(OBJS)
+       rm -f algorithms.a
+       $(AR) cru algorithms.a $(OBJS)
+       $(RANLIB) algorithms.a
+
+Makefile: $(SRCDIR)/Makefile.in config.status
+       CONFIG_FILES=Makefile CONFIG_HEADERS="" ./config.status
+       @echo "Run make again"
+       @exit 1
+
diff --git a/cast.c b/cast.c
new file mode 100644 (file)
index 0000000..c2e467c
--- /dev/null
+++ b/cast.c
@@ -0,0 +1,248 @@
+/*
+ * $Id$
+ *
+ *     CAST-128 in C
+ *     Written by Steve Reid <sreid@sea-to-sky.net>
+ *     100% Public Domain - no warranty
+ *     Released 1997.10.11
+ */
+
+/* Adapted to the pike cryptographic toolkit by Niels Möller */
+
+#include <cast.h>
+
+#define u8 unsigned INT8
+#define u32 unsigned INT32
+
+#include "cast_sboxes.h"
+
+/* Macros to access 8-bit bytes out of a 32-bit word */
+#define U8a(x) ( (u8) (x>>24) )
+#define U8b(x) ( (u8) ((x>>16)&255) )
+#define U8c(x) ( (u8) ((x>>8)&255) )
+#define U8d(x) ( (u8) ((x)&255) )
+
+/* Circular left shift */
+#define ROL(x, n) ( ((x)<<(n)) | ((x)>>(32-(n))) )
+
+/* CAST-128 uses three different round functions */
+#define F1(l, r, i) \
+       t = ROL(key->xkey[i] + r, key->xkey[i+16]); \
+       l ^= ((cast_sbox1[U8a(t)] ^ cast_sbox2[U8b(t)]) \
+        - cast_sbox3[U8c(t)]) + cast_sbox4[U8d(t)];
+#define F2(l, r, i) \
+       t = ROL(key->xkey[i] ^ r, key->xkey[i+16]); \
+       l ^= ((cast_sbox1[U8a(t)] - cast_sbox2[U8b(t)]) \
+        + cast_sbox3[U8c(t)]) ^ cast_sbox4[U8d(t)];
+#define F3(l, r, i) \
+       t = ROL(key->xkey[i] - r, key->xkey[i+16]); \
+       l ^= ((cast_sbox1[U8a(t)] + cast_sbox2[U8b(t)]) \
+        ^ cast_sbox3[U8c(t)]) - cast_sbox4[U8d(t)];
+
+
+/***** Encryption Function *****/
+
+void cast_encrypt(struct cast_key *key, u8 *inblock, u8 *outblock)
+{
+  u32 t, l, r;
+
+  /* Get inblock into l,r */
+  l = ((u32)inblock[0] << 24) | ((u32)inblock[1] << 16)
+    | ((u32)inblock[2] << 8) | (u32)inblock[3];
+  r = ((u32)inblock[4] << 24) | ((u32)inblock[5] << 16)
+    | ((u32)inblock[6] << 8) | (u32)inblock[7];
+  /* Do the work */
+  F1(l, r,  0);
+  F2(r, l,  1);
+  F3(l, r,  2);
+  F1(r, l,  3);
+  F2(l, r,  4);
+  F3(r, l,  5);
+  F1(l, r,  6);
+  F2(r, l,  7);
+  F3(l, r,  8);
+  F1(r, l,  9);
+  F2(l, r, 10);
+  F3(r, l, 11);
+  /* Only do full 16 rounds if key length > 80 bits */
+  if (key->rounds > 12) {
+    F1(l, r, 12);
+    F2(r, l, 13);
+    F3(l, r, 14);
+    F1(r, l, 15);
+  }
+  /* Put l,r into outblock */
+  outblock[0] = U8a(r);
+  outblock[1] = U8b(r);
+  outblock[2] = U8c(r);
+  outblock[3] = U8d(r);
+  outblock[4] = U8a(l);
+  outblock[5] = U8b(l);
+  outblock[6] = U8c(l);
+  outblock[7] = U8d(l);
+  /* Wipe clean */
+  t = l = r = 0;
+}
+
+
+/***** Decryption Function *****/
+
+void cast_decrypt(struct cast_key *key, u8 *inblock, u8 *outblock)
+{
+  u32 t, l, r;
+
+  /* Get inblock into l,r */
+  r = ((u32)inblock[0] << 24) | ((u32)inblock[1] << 16)
+    | ((u32)inblock[2] << 8) | (u32)inblock[3];
+  l = ((u32)inblock[4] << 24) | ((u32)inblock[5] << 16)
+    | ((u32)inblock[6] << 8) | (u32)inblock[7];
+  /* Do the work */
+  /* Only do full 16 rounds if key length > 80 bits */
+  if (key->rounds > 12) {
+    F1(r, l, 15);
+    F3(l, r, 14);
+    F2(r, l, 13);
+    F1(l, r, 12);
+  }
+  F3(r, l, 11);
+  F2(l, r, 10);
+  F1(r, l,  9);
+  F3(l, r,  8);
+  F2(r, l,  7);
+  F1(l, r,  6);
+  F3(r, l,  5);
+  F2(l, r,  4);
+  F1(r, l,  3);
+  F3(l, r,  2);
+  F2(r, l,  1);
+  F1(l, r,  0);
+  /* Put l,r into outblock */
+  outblock[0] = U8a(l);
+  outblock[1] = U8b(l);
+  outblock[2] = U8c(l);
+  outblock[3] = U8d(l);
+  outblock[4] = U8a(r);
+  outblock[5] = U8b(r);
+  outblock[6] = U8c(r);
+  outblock[7] = U8d(r);
+  /* Wipe clean */
+  t = l = r = 0;
+}
+
+
+/***** Key Schedual *****/
+
+void cast_setkey(struct cast_key *key, u8 *rawkey, unsigned keybytes)
+{
+  u32 t[4], z[4], x[4];
+  unsigned i;
+
+  /* Set number of rounds to 12 or 16, depending on key length */
+  key->rounds = (keybytes <= CAST_SMALL_KEY)
+    ? CAST_SMALL_ROUNDS : CAST_FULL_ROUNDS;
+
+  /* Copy key to workspace x */
+  for (i = 0; i < 4; i++) {
+    x[i] = 0;
+    if ((i*4+0) < keybytes) x[i] = (u32)rawkey[i*4+0] << 24;
+    if ((i*4+1) < keybytes) x[i] |= (u32)rawkey[i*4+1] << 16;
+    if ((i*4+2) < keybytes) x[i] |= (u32)rawkey[i*4+2] << 8;
+    if ((i*4+3) < keybytes) x[i] |= (u32)rawkey[i*4+3];
+  }
+  /* Generate 32 subkeys, four at a time */
+  for (i = 0; i < 32; i+=4) {
+    switch (i & 4) {
+    case 0:
+      t[0] = z[0] = x[0] ^ cast_sbox5[U8b(x[3])]
+       ^ cast_sbox6[U8d(x[3])] ^ cast_sbox7[U8a(x[3])]
+       ^ cast_sbox8[U8c(x[3])] ^ cast_sbox7[U8a(x[2])];
+      t[1] = z[1] = x[2] ^ cast_sbox5[U8a(z[0])]
+       ^ cast_sbox6[U8c(z[0])] ^ cast_sbox7[U8b(z[0])]
+       ^ cast_sbox8[U8d(z[0])] ^ cast_sbox8[U8c(x[2])];
+      t[2] = z[2] = x[3] ^ cast_sbox5[U8d(z[1])]
+       ^ cast_sbox6[U8c(z[1])] ^ cast_sbox7[U8b(z[1])]
+       ^ cast_sbox8[U8a(z[1])] ^ cast_sbox5[U8b(x[2])];
+      t[3] = z[3] = x[1] ^ cast_sbox5[U8c(z[2])] ^
+       cast_sbox6[U8b(z[2])] ^ cast_sbox7[U8d(z[2])]
+       ^ cast_sbox8[U8a(z[2])] ^ cast_sbox6[U8d(x[2])];
+      break;
+    case 4:
+      t[0] = x[0] = z[2] ^ cast_sbox5[U8b(z[1])]
+       ^ cast_sbox6[U8d(z[1])] ^ cast_sbox7[U8a(z[1])]
+       ^ cast_sbox8[U8c(z[1])] ^ cast_sbox7[U8a(z[0])];
+      t[1] = x[1] = z[0] ^ cast_sbox5[U8a(x[0])]
+       ^ cast_sbox6[U8c(x[0])] ^ cast_sbox7[U8b(x[0])]
+       ^ cast_sbox8[U8d(x[0])] ^ cast_sbox8[U8c(z[0])];
+      t[2] = x[2] = z[1] ^ cast_sbox5[U8d(x[1])]
+       ^ cast_sbox6[U8c(x[1])] ^ cast_sbox7[U8b(x[1])]
+       ^ cast_sbox8[U8a(x[1])] ^ cast_sbox5[U8b(z[0])];
+      t[3] = x[3] = z[3] ^ cast_sbox5[U8c(x[2])]
+       ^ cast_sbox6[U8b(x[2])] ^ cast_sbox7[U8d(x[2])]
+       ^ cast_sbox8[U8a(x[2])] ^ cast_sbox6[U8d(z[0])];
+      break;
+    }
+    switch (i & 12) {
+    case 0:
+    case 12:
+      key->xkey[i+0] = cast_sbox5[U8a(t[2])] ^ cast_sbox6[U8b(t[2])]
+       ^ cast_sbox7[U8d(t[1])] ^ cast_sbox8[U8c(t[1])];
+      key->xkey[i+1] = cast_sbox5[U8c(t[2])] ^ cast_sbox6[U8d(t[2])]
+       ^ cast_sbox7[U8b(t[1])] ^ cast_sbox8[U8a(t[1])];
+      key->xkey[i+2] = cast_sbox5[U8a(t[3])] ^ cast_sbox6[U8b(t[3])]
+       ^ cast_sbox7[U8d(t[0])] ^ cast_sbox8[U8c(t[0])];
+      key->xkey[i+3] = cast_sbox5[U8c(t[3])] ^ cast_sbox6[U8d(t[3])]
+       ^ cast_sbox7[U8b(t[0])] ^ cast_sbox8[U8a(t[0])];
+      break;
+    case 4:
+    case 8:
+      key->xkey[i+0] = cast_sbox5[U8d(t[0])] ^ cast_sbox6[U8c(t[0])]
+       ^ cast_sbox7[U8a(t[3])] ^ cast_sbox8[U8b(t[3])];
+      key->xkey[i+1] = cast_sbox5[U8b(t[0])] ^ cast_sbox6[U8a(t[0])]
+       ^ cast_sbox7[U8c(t[3])] ^ cast_sbox8[U8d(t[3])];
+      key->xkey[i+2] = cast_sbox5[U8d(t[1])] ^ cast_sbox6[U8c(t[1])]
+       ^ cast_sbox7[U8a(t[2])] ^ cast_sbox8[U8b(t[2])];
+      key->xkey[i+3] = cast_sbox5[U8b(t[1])] ^ cast_sbox6[U8a(t[1])]
+       ^ cast_sbox7[U8c(t[2])] ^ cast_sbox8[U8d(t[2])];
+      break;
+    }
+    switch (i & 12) {
+    case 0:
+      key->xkey[i+0] ^= cast_sbox5[U8c(z[0])];
+      key->xkey[i+1] ^= cast_sbox6[U8c(z[1])];
+      key->xkey[i+2] ^= cast_sbox7[U8b(z[2])];
+      key->xkey[i+3] ^= cast_sbox8[U8a(z[3])];
+      break;
+    case 4:
+      key->xkey[i+0] ^= cast_sbox5[U8a(x[2])];
+      key->xkey[i+1] ^= cast_sbox6[U8b(x[3])];
+      key->xkey[i+2] ^= cast_sbox7[U8d(x[0])];
+      key->xkey[i+3] ^= cast_sbox8[U8d(x[1])];
+      break;
+    case 8:
+      key->xkey[i+0] ^= cast_sbox5[U8b(z[2])];
+      key->xkey[i+1] ^= cast_sbox6[U8a(z[3])];
+      key->xkey[i+2] ^= cast_sbox7[U8c(z[0])];
+      key->xkey[i+3] ^= cast_sbox8[U8c(z[1])];
+      break;
+    case 12:
+      key->xkey[i+0] ^= cast_sbox5[U8d(x[0])];
+      key->xkey[i+1] ^= cast_sbox6[U8d(x[1])];
+      key->xkey[i+2] ^= cast_sbox7[U8a(x[2])];
+      key->xkey[i+3] ^= cast_sbox8[U8b(x[3])];
+      break;
+    }
+    if (i >= 16) {
+      key->xkey[i+0] &= 31;
+      key->xkey[i+1] &= 31;
+      key->xkey[i+2] &= 31;
+      key->xkey[i+3] &= 31;
+    }
+  }
+  /* Wipe clean */
+  for (i = 0; i < 4; i++) {
+    t[i] = x[i] = z[i] = 0;
+  }
+}
+
+/* Made in Canada */
+
diff --git a/cast_sboxes.h b/cast_sboxes.h
new file mode 100644 (file)
index 0000000..2e061aa
--- /dev/null
@@ -0,0 +1,545 @@
+/*
+ * $Id$
+ *
+ *     CAST-128 in C
+ *     Written by Steve Reid <sreid@sea-to-sky.net>
+ *     100% Public Domain - no warranty
+ *     Released 1997.10.11
+ */
+
+static const u32 cast_sbox1[256] = {
+  0x30FB40D4, 0x9FA0FF0B, 0x6BECCD2F, 0x3F258C7A,
+  0x1E213F2F, 0x9C004DD3, 0x6003E540, 0xCF9FC949,
+  0xBFD4AF27, 0x88BBBDB5, 0xE2034090, 0x98D09675,
+  0x6E63A0E0, 0x15C361D2, 0xC2E7661D, 0x22D4FF8E,
+  0x28683B6F, 0xC07FD059, 0xFF2379C8, 0x775F50E2,
+  0x43C340D3, 0xDF2F8656, 0x887CA41A, 0xA2D2BD2D,
+  0xA1C9E0D6, 0x346C4819, 0x61B76D87, 0x22540F2F,
+  0x2ABE32E1, 0xAA54166B, 0x22568E3A, 0xA2D341D0,
+  0x66DB40C8, 0xA784392F, 0x004DFF2F, 0x2DB9D2DE,
+  0x97943FAC, 0x4A97C1D8, 0x527644B7, 0xB5F437A7,
+  0xB82CBAEF, 0xD751D159, 0x6FF7F0ED, 0x5A097A1F,
+  0x827B68D0, 0x90ECF52E, 0x22B0C054, 0xBC8E5935,
+  0x4B6D2F7F, 0x50BB64A2, 0xD2664910, 0xBEE5812D,
+  0xB7332290, 0xE93B159F, 0xB48EE411, 0x4BFF345D,
+  0xFD45C240, 0xAD31973F, 0xC4F6D02E, 0x55FC8165,
+  0xD5B1CAAD, 0xA1AC2DAE, 0xA2D4B76D, 0xC19B0C50,
+  0x882240F2, 0x0C6E4F38, 0xA4E4BFD7, 0x4F5BA272,
+  0x564C1D2F, 0xC59C5319, 0xB949E354, 0xB04669FE,
+  0xB1B6AB8A, 0xC71358DD, 0x6385C545, 0x110F935D,
+  0x57538AD5, 0x6A390493, 0xE63D37E0, 0x2A54F6B3,
+  0x3A787D5F, 0x6276A0B5, 0x19A6FCDF, 0x7A42206A,
+  0x29F9D4D5, 0xF61B1891, 0xBB72275E, 0xAA508167,
+  0x38901091, 0xC6B505EB, 0x84C7CB8C, 0x2AD75A0F,
+  0x874A1427, 0xA2D1936B, 0x2AD286AF, 0xAA56D291,
+  0xD7894360, 0x425C750D, 0x93B39E26, 0x187184C9,
+  0x6C00B32D, 0x73E2BB14, 0xA0BEBC3C, 0x54623779,
+  0x64459EAB, 0x3F328B82, 0x7718CF82, 0x59A2CEA6,
+  0x04EE002E, 0x89FE78E6, 0x3FAB0950, 0x325FF6C2,
+  0x81383F05, 0x6963C5C8, 0x76CB5AD6, 0xD49974C9,
+  0xCA180DCF, 0x380782D5, 0xC7FA5CF6, 0x8AC31511,
+  0x35E79E13, 0x47DA91D0, 0xF40F9086, 0xA7E2419E,
+  0x31366241, 0x051EF495, 0xAA573B04, 0x4A805D8D,
+  0x548300D0, 0x00322A3C, 0xBF64CDDF, 0xBA57A68E,
+  0x75C6372B, 0x50AFD341, 0xA7C13275, 0x915A0BF5,
+  0x6B54BFAB, 0x2B0B1426, 0xAB4CC9D7, 0x449CCD82,
+  0xF7FBF265, 0xAB85C5F3, 0x1B55DB94, 0xAAD4E324,
+  0xCFA4BD3F, 0x2DEAA3E2, 0x9E204D02, 0xC8BD25AC,
+  0xEADF55B3, 0xD5BD9E98, 0xE31231B2, 0x2AD5AD6C,
+  0x954329DE, 0xADBE4528, 0xD8710F69, 0xAA51C90F,
+  0xAA786BF6, 0x22513F1E, 0xAA51A79B, 0x2AD344CC,
+  0x7B5A41F0, 0xD37CFBAD, 0x1B069505, 0x41ECE491,
+  0xB4C332E6, 0x032268D4, 0xC9600ACC, 0xCE387E6D,
+  0xBF6BB16C, 0x6A70FB78, 0x0D03D9C9, 0xD4DF39DE,
+  0xE01063DA, 0x4736F464, 0x5AD328D8, 0xB347CC96,
+  0x75BB0FC3, 0x98511BFB, 0x4FFBCC35, 0xB58BCF6A,
+  0xE11F0ABC, 0xBFC5FE4A, 0xA70AEC10, 0xAC39570A,
+  0x3F04442F, 0x6188B153, 0xE0397A2E, 0x5727CB79,
+  0x9CEB418F, 0x1CACD68D, 0x2AD37C96, 0x0175CB9D,
+  0xC69DFF09, 0xC75B65F0, 0xD9DB40D8, 0xEC0E7779,
+  0x4744EAD4, 0xB11C3274, 0xDD24CB9E, 0x7E1C54BD,
+  0xF01144F9, 0xD2240EB1, 0x9675B3FD, 0xA3AC3755,
+  0xD47C27AF, 0x51C85F4D, 0x56907596, 0xA5BB15E6,
+  0x580304F0, 0xCA042CF1, 0x011A37EA, 0x8DBFAADB,
+  0x35BA3E4A, 0x3526FFA0, 0xC37B4D09, 0xBC306ED9,
+  0x98A52666, 0x5648F725, 0xFF5E569D, 0x0CED63D0,
+  0x7C63B2CF, 0x700B45E1, 0xD5EA50F1, 0x85A92872,
+  0xAF1FBDA7, 0xD4234870, 0xA7870BF3, 0x2D3B4D79,
+  0x42E04198, 0x0CD0EDE7, 0x26470DB8, 0xF881814C,
+  0x474D6AD7, 0x7C0C5E5C, 0xD1231959, 0x381B7298,
+  0xF5D2F4DB, 0xAB838653, 0x6E2F1E23, 0x83719C9E,
+  0xBD91E046, 0x9A56456E, 0xDC39200C, 0x20C8C571,
+  0x962BDA1C, 0xE1E696FF, 0xB141AB08, 0x7CCA89B9,
+  0x1A69E783, 0x02CC4843, 0xA2F7C579, 0x429EF47D,
+  0x427B169C, 0x5AC9F049, 0xDD8F0F00, 0x5C8165BF
+};
+
+static const u32 cast_sbox2[256] = {
+  0x1F201094, 0xEF0BA75B, 0x69E3CF7E, 0x393F4380,
+  0xFE61CF7A, 0xEEC5207A, 0x55889C94, 0x72FC0651,
+  0xADA7EF79, 0x4E1D7235, 0xD55A63CE, 0xDE0436BA,
+  0x99C430EF, 0x5F0C0794, 0x18DCDB7D, 0xA1D6EFF3,
+  0xA0B52F7B, 0x59E83605, 0xEE15B094, 0xE9FFD909,
+  0xDC440086, 0xEF944459, 0xBA83CCB3, 0xE0C3CDFB,
+  0xD1DA4181, 0x3B092AB1, 0xF997F1C1, 0xA5E6CF7B,
+  0x01420DDB, 0xE4E7EF5B, 0x25A1FF41, 0xE180F806,
+  0x1FC41080, 0x179BEE7A, 0xD37AC6A9, 0xFE5830A4,
+  0x98DE8B7F, 0x77E83F4E, 0x79929269, 0x24FA9F7B,
+  0xE113C85B, 0xACC40083, 0xD7503525, 0xF7EA615F,
+  0x62143154, 0x0D554B63, 0x5D681121, 0xC866C359,
+  0x3D63CF73, 0xCEE234C0, 0xD4D87E87, 0x5C672B21,
+  0x071F6181, 0x39F7627F, 0x361E3084, 0xE4EB573B,
+  0x602F64A4, 0xD63ACD9C, 0x1BBC4635, 0x9E81032D,
+  0x2701F50C, 0x99847AB4, 0xA0E3DF79, 0xBA6CF38C,
+  0x10843094, 0x2537A95E, 0xF46F6FFE, 0xA1FF3B1F,
+  0x208CFB6A, 0x8F458C74, 0xD9E0A227, 0x4EC73A34,
+  0xFC884F69, 0x3E4DE8DF, 0xEF0E0088, 0x3559648D,
+  0x8A45388C, 0x1D804366, 0x721D9BFD, 0xA58684BB,
+  0xE8256333, 0x844E8212, 0x128D8098, 0xFED33FB4,
+  0xCE280AE1, 0x27E19BA5, 0xD5A6C252, 0xE49754BD,
+  0xC5D655DD, 0xEB667064, 0x77840B4D, 0xA1B6A801,
+  0x84DB26A9, 0xE0B56714, 0x21F043B7, 0xE5D05860,
+  0x54F03084, 0x066FF472, 0xA31AA153, 0xDADC4755,
+  0xB5625DBF, 0x68561BE6, 0x83CA6B94, 0x2D6ED23B,
+  0xECCF01DB, 0xA6D3D0BA, 0xB6803D5C, 0xAF77A709,
+  0x33B4A34C, 0x397BC8D6, 0x5EE22B95, 0x5F0E5304,
+  0x81ED6F61, 0x20E74364, 0xB45E1378, 0xDE18639B,
+  0x881CA122, 0xB96726D1, 0x8049A7E8, 0x22B7DA7B,
+  0x5E552D25, 0x5272D237, 0x79D2951C, 0xC60D894C,
+  0x488CB402, 0x1BA4FE5B, 0xA4B09F6B, 0x1CA815CF,
+  0xA20C3005, 0x8871DF63, 0xB9DE2FCB, 0x0CC6C9E9,
+  0x0BEEFF53, 0xE3214517, 0xB4542835, 0x9F63293C,
+  0xEE41E729, 0x6E1D2D7C, 0x50045286, 0x1E6685F3,
+  0xF33401C6, 0x30A22C95, 0x31A70850, 0x60930F13,
+  0x73F98417, 0xA1269859, 0xEC645C44, 0x52C877A9,
+  0xCDFF33A6, 0xA02B1741, 0x7CBAD9A2, 0x2180036F,
+  0x50D99C08, 0xCB3F4861, 0xC26BD765, 0x64A3F6AB,
+  0x80342676, 0x25A75E7B, 0xE4E6D1FC, 0x20C710E6,
+  0xCDF0B680, 0x17844D3B, 0x31EEF84D, 0x7E0824E4,
+  0x2CCB49EB, 0x846A3BAE, 0x8FF77888, 0xEE5D60F6,
+  0x7AF75673, 0x2FDD5CDB, 0xA11631C1, 0x30F66F43,
+  0xB3FAEC54, 0x157FD7FA, 0xEF8579CC, 0xD152DE58,
+  0xDB2FFD5E, 0x8F32CE19, 0x306AF97A, 0x02F03EF8,
+  0x99319AD5, 0xC242FA0F, 0xA7E3EBB0, 0xC68E4906,
+  0xB8DA230C, 0x80823028, 0xDCDEF3C8, 0xD35FB171,
+  0x088A1BC8, 0xBEC0C560, 0x61A3C9E8, 0xBCA8F54D,
+  0xC72FEFFA, 0x22822E99, 0x82C570B4, 0xD8D94E89,
+  0x8B1C34BC, 0x301E16E6, 0x273BE979, 0xB0FFEAA6,
+  0x61D9B8C6, 0x00B24869, 0xB7FFCE3F, 0x08DC283B,
+  0x43DAF65A, 0xF7E19798, 0x7619B72F, 0x8F1C9BA4,
+  0xDC8637A0, 0x16A7D3B1, 0x9FC393B7, 0xA7136EEB,
+  0xC6BCC63E, 0x1A513742, 0xEF6828BC, 0x520365D6,
+  0x2D6A77AB, 0x3527ED4B, 0x821FD216, 0x095C6E2E,
+  0xDB92F2FB, 0x5EEA29CB, 0x145892F5, 0x91584F7F,
+  0x5483697B, 0x2667A8CC, 0x85196048, 0x8C4BACEA,
+  0x833860D4, 0x0D23E0F9, 0x6C387E8A, 0x0AE6D249,
+  0xB284600C, 0xD835731D, 0xDCB1C647, 0xAC4C56EA,
+  0x3EBD81B3, 0x230EABB0, 0x6438BC87, 0xF0B5B1FA,
+  0x8F5EA2B3, 0xFC184642, 0x0A036B7A, 0x4FB089BD,
+  0x649DA589, 0xA345415E, 0x5C038323, 0x3E5D3BB9,
+  0x43D79572, 0x7E6DD07C, 0x06DFDF1E, 0x6C6CC4EF,
+  0x7160A539, 0x73BFBE70, 0x83877605, 0x4523ECF1
+};
+
+static const u32 cast_sbox3[256] = {
+  0x8DEFC240, 0x25FA5D9F, 0xEB903DBF, 0xE810C907,
+  0x47607FFF, 0x369FE44B, 0x8C1FC644, 0xAECECA90,
+  0xBEB1F9BF, 0xEEFBCAEA, 0xE8CF1950, 0x51DF07AE,
+  0x920E8806, 0xF0AD0548, 0xE13C8D83, 0x927010D5,
+  0x11107D9F, 0x07647DB9, 0xB2E3E4D4, 0x3D4F285E,
+  0xB9AFA820, 0xFADE82E0, 0xA067268B, 0x8272792E,
+  0x553FB2C0, 0x489AE22B, 0xD4EF9794, 0x125E3FBC,
+  0x21FFFCEE, 0x825B1BFD, 0x9255C5ED, 0x1257A240,
+  0x4E1A8302, 0xBAE07FFF, 0x528246E7, 0x8E57140E,
+  0x3373F7BF, 0x8C9F8188, 0xA6FC4EE8, 0xC982B5A5,
+  0xA8C01DB7, 0x579FC264, 0x67094F31, 0xF2BD3F5F,
+  0x40FFF7C1, 0x1FB78DFC, 0x8E6BD2C1, 0x437BE59B,
+  0x99B03DBF, 0xB5DBC64B, 0x638DC0E6, 0x55819D99,
+  0xA197C81C, 0x4A012D6E, 0xC5884A28, 0xCCC36F71,
+  0xB843C213, 0x6C0743F1, 0x8309893C, 0x0FEDDD5F,
+  0x2F7FE850, 0xD7C07F7E, 0x02507FBF, 0x5AFB9A04,
+  0xA747D2D0, 0x1651192E, 0xAF70BF3E, 0x58C31380,
+  0x5F98302E, 0x727CC3C4, 0x0A0FB402, 0x0F7FEF82,
+  0x8C96FDAD, 0x5D2C2AAE, 0x8EE99A49, 0x50DA88B8,
+  0x8427F4A0, 0x1EAC5790, 0x796FB449, 0x8252DC15,
+  0xEFBD7D9B, 0xA672597D, 0xADA840D8, 0x45F54504,
+  0xFA5D7403, 0xE83EC305, 0x4F91751A, 0x925669C2,
+  0x23EFE941, 0xA903F12E, 0x60270DF2, 0x0276E4B6,
+  0x94FD6574, 0x927985B2, 0x8276DBCB, 0x02778176,
+  0xF8AF918D, 0x4E48F79E, 0x8F616DDF, 0xE29D840E,
+  0x842F7D83, 0x340CE5C8, 0x96BBB682, 0x93B4B148,
+  0xEF303CAB, 0x984FAF28, 0x779FAF9B, 0x92DC560D,
+  0x224D1E20, 0x8437AA88, 0x7D29DC96, 0x2756D3DC,
+  0x8B907CEE, 0xB51FD240, 0xE7C07CE3, 0xE566B4A1,
+  0xC3E9615E, 0x3CF8209D, 0x6094D1E3, 0xCD9CA341,
+  0x5C76460E, 0x00EA983B, 0xD4D67881, 0xFD47572C,
+  0xF76CEDD9, 0xBDA8229C, 0x127DADAA, 0x438A074E,
+  0x1F97C090, 0x081BDB8A, 0x93A07EBE, 0xB938CA15,
+  0x97B03CFF, 0x3DC2C0F8, 0x8D1AB2EC, 0x64380E51,
+  0x68CC7BFB, 0xD90F2788, 0x12490181, 0x5DE5FFD4,
+  0xDD7EF86A, 0x76A2E214, 0xB9A40368, 0x925D958F,
+  0x4B39FFFA, 0xBA39AEE9, 0xA4FFD30B, 0xFAF7933B,
+  0x6D498623, 0x193CBCFA, 0x27627545, 0x825CF47A,
+  0x61BD8BA0, 0xD11E42D1, 0xCEAD04F4, 0x127EA392,
+  0x10428DB7, 0x8272A972, 0x9270C4A8, 0x127DE50B,
+  0x285BA1C8, 0x3C62F44F, 0x35C0EAA5, 0xE805D231,
+  0x428929FB, 0xB4FCDF82, 0x4FB66A53, 0x0E7DC15B,
+  0x1F081FAB, 0x108618AE, 0xFCFD086D, 0xF9FF2889,
+  0x694BCC11, 0x236A5CAE, 0x12DECA4D, 0x2C3F8CC5,
+  0xD2D02DFE, 0xF8EF5896, 0xE4CF52DA, 0x95155B67,
+  0x494A488C, 0xB9B6A80C, 0x5C8F82BC, 0x89D36B45,
+  0x3A609437, 0xEC00C9A9, 0x44715253, 0x0A874B49,
+  0xD773BC40, 0x7C34671C, 0x02717EF6, 0x4FEB5536,
+  0xA2D02FFF, 0xD2BF60C4, 0xD43F03C0, 0x50B4EF6D,
+  0x07478CD1, 0x006E1888, 0xA2E53F55, 0xB9E6D4BC,
+  0xA2048016, 0x97573833, 0xD7207D67, 0xDE0F8F3D,
+  0x72F87B33, 0xABCC4F33, 0x7688C55D, 0x7B00A6B0,
+  0x947B0001, 0x570075D2, 0xF9BB88F8, 0x8942019E,
+  0x4264A5FF, 0x856302E0, 0x72DBD92B, 0xEE971B69,
+  0x6EA22FDE, 0x5F08AE2B, 0xAF7A616D, 0xE5C98767,
+  0xCF1FEBD2, 0x61EFC8C2, 0xF1AC2571, 0xCC8239C2,
+  0x67214CB8, 0xB1E583D1, 0xB7DC3E62, 0x7F10BDCE,
+  0xF90A5C38, 0x0FF0443D, 0x606E6DC6, 0x60543A49,
+  0x5727C148, 0x2BE98A1D, 0x8AB41738, 0x20E1BE24,
+  0xAF96DA0F, 0x68458425, 0x99833BE5, 0x600D457D,
+  0x282F9350, 0x8334B362, 0xD91D1120, 0x2B6D8DA0,
+  0x642B1E31, 0x9C305A00, 0x52BCE688, 0x1B03588A,
+  0xF7BAEFD5, 0x4142ED9C, 0xA4315C11, 0x83323EC5,
+  0xDFEF4636, 0xA133C501, 0xE9D3531C, 0xEE353783
+};
+
+static const u32 cast_sbox4[256] = {
+  0x9DB30420, 0x1FB6E9DE, 0xA7BE7BEF, 0xD273A298,
+  0x4A4F7BDB, 0x64AD8C57, 0x85510443, 0xFA020ED1,
+  0x7E287AFF, 0xE60FB663, 0x095F35A1, 0x79EBF120,
+  0xFD059D43, 0x6497B7B1, 0xF3641F63, 0x241E4ADF,
+  0x28147F5F, 0x4FA2B8CD, 0xC9430040, 0x0CC32220,
+  0xFDD30B30, 0xC0A5374F, 0x1D2D00D9, 0x24147B15,
+  0xEE4D111A, 0x0FCA5167, 0x71FF904C, 0x2D195FFE,
+  0x1A05645F, 0x0C13FEFE, 0x081B08CA, 0x05170121,
+  0x80530100, 0xE83E5EFE, 0xAC9AF4F8, 0x7FE72701,
+  0xD2B8EE5F, 0x06DF4261, 0xBB9E9B8A, 0x7293EA25,
+  0xCE84FFDF, 0xF5718801, 0x3DD64B04, 0xA26F263B,
+  0x7ED48400, 0x547EEBE6, 0x446D4CA0, 0x6CF3D6F5,
+  0x2649ABDF, 0xAEA0C7F5, 0x36338CC1, 0x503F7E93,
+  0xD3772061, 0x11B638E1, 0x72500E03, 0xF80EB2BB,
+  0xABE0502E, 0xEC8D77DE, 0x57971E81, 0xE14F6746,
+  0xC9335400, 0x6920318F, 0x081DBB99, 0xFFC304A5,
+  0x4D351805, 0x7F3D5CE3, 0xA6C866C6, 0x5D5BCCA9,
+  0xDAEC6FEA, 0x9F926F91, 0x9F46222F, 0x3991467D,
+  0xA5BF6D8E, 0x1143C44F, 0x43958302, 0xD0214EEB,
+  0x022083B8, 0x3FB6180C, 0x18F8931E, 0x281658E6,
+  0x26486E3E, 0x8BD78A70, 0x7477E4C1, 0xB506E07C,
+  0xF32D0A25, 0x79098B02, 0xE4EABB81, 0x28123B23,
+  0x69DEAD38, 0x1574CA16, 0xDF871B62, 0x211C40B7,
+  0xA51A9EF9, 0x0014377B, 0x041E8AC8, 0x09114003,
+  0xBD59E4D2, 0xE3D156D5, 0x4FE876D5, 0x2F91A340,
+  0x557BE8DE, 0x00EAE4A7, 0x0CE5C2EC, 0x4DB4BBA6,
+  0xE756BDFF, 0xDD3369AC, 0xEC17B035, 0x06572327,
+  0x99AFC8B0, 0x56C8C391, 0x6B65811C, 0x5E146119,
+  0x6E85CB75, 0xBE07C002, 0xC2325577, 0x893FF4EC,
+  0x5BBFC92D, 0xD0EC3B25, 0xB7801AB7, 0x8D6D3B24,
+  0x20C763EF, 0xC366A5FC, 0x9C382880, 0x0ACE3205,
+  0xAAC9548A, 0xECA1D7C7, 0x041AFA32, 0x1D16625A,
+  0x6701902C, 0x9B757A54, 0x31D477F7, 0x9126B031,
+  0x36CC6FDB, 0xC70B8B46, 0xD9E66A48, 0x56E55A79,
+  0x026A4CEB, 0x52437EFF, 0x2F8F76B4, 0x0DF980A5,
+  0x8674CDE3, 0xEDDA04EB, 0x17A9BE04, 0x2C18F4DF,
+  0xB7747F9D, 0xAB2AF7B4, 0xEFC34D20, 0x2E096B7C,
+  0x1741A254, 0xE5B6A035, 0x213D42F6, 0x2C1C7C26,
+  0x61C2F50F, 0x6552DAF9, 0xD2C231F8, 0x25130F69,
+  0xD8167FA2, 0x0418F2C8, 0x001A96A6, 0x0D1526AB,
+  0x63315C21, 0x5E0A72EC, 0x49BAFEFD, 0x187908D9,
+  0x8D0DBD86, 0x311170A7, 0x3E9B640C, 0xCC3E10D7,
+  0xD5CAD3B6, 0x0CAEC388, 0xF73001E1, 0x6C728AFF,
+  0x71EAE2A1, 0x1F9AF36E, 0xCFCBD12F, 0xC1DE8417,
+  0xAC07BE6B, 0xCB44A1D8, 0x8B9B0F56, 0x013988C3,
+  0xB1C52FCA, 0xB4BE31CD, 0xD8782806, 0x12A3A4E2,
+  0x6F7DE532, 0x58FD7EB6, 0xD01EE900, 0x24ADFFC2,
+  0xF4990FC5, 0x9711AAC5, 0x001D7B95, 0x82E5E7D2,
+  0x109873F6, 0x00613096, 0xC32D9521, 0xADA121FF,
+  0x29908415, 0x7FBB977F, 0xAF9EB3DB, 0x29C9ED2A,
+  0x5CE2A465, 0xA730F32C, 0xD0AA3FE8, 0x8A5CC091,
+  0xD49E2CE7, 0x0CE454A9, 0xD60ACD86, 0x015F1919,
+  0x77079103, 0xDEA03AF6, 0x78A8565E, 0xDEE356DF,
+  0x21F05CBE, 0x8B75E387, 0xB3C50651, 0xB8A5C3EF,
+  0xD8EEB6D2, 0xE523BE77, 0xC2154529, 0x2F69EFDF,
+  0xAFE67AFB, 0xF470C4B2, 0xF3E0EB5B, 0xD6CC9876,
+  0x39E4460C, 0x1FDA8538, 0x1987832F, 0xCA007367,
+  0xA99144F8, 0x296B299E, 0x492FC295, 0x9266BEAB,
+  0xB5676E69, 0x9BD3DDDA, 0xDF7E052F, 0xDB25701C,
+  0x1B5E51EE, 0xF65324E6, 0x6AFCE36C, 0x0316CC04,
+  0x8644213E, 0xB7DC59D0, 0x7965291F, 0xCCD6FD43,
+  0x41823979, 0x932BCDF6, 0xB657C34D, 0x4EDFD282,
+  0x7AE5290C, 0x3CB9536B, 0x851E20FE, 0x9833557E,
+  0x13ECF0B0, 0xD3FFB372, 0x3F85C5C1, 0x0AEF7ED2
+};
+
+static const u32 cast_sbox5[256] = {
+  0x7EC90C04, 0x2C6E74B9, 0x9B0E66DF, 0xA6337911,
+  0xB86A7FFF, 0x1DD358F5, 0x44DD9D44, 0x1731167F,
+  0x08FBF1FA, 0xE7F511CC, 0xD2051B00, 0x735ABA00,
+  0x2AB722D8, 0x386381CB, 0xACF6243A, 0x69BEFD7A,
+  0xE6A2E77F, 0xF0C720CD, 0xC4494816, 0xCCF5C180,
+  0x38851640, 0x15B0A848, 0xE68B18CB, 0x4CAADEFF,
+  0x5F480A01, 0x0412B2AA, 0x259814FC, 0x41D0EFE2,
+  0x4E40B48D, 0x248EB6FB, 0x8DBA1CFE, 0x41A99B02,
+  0x1A550A04, 0xBA8F65CB, 0x7251F4E7, 0x95A51725,
+  0xC106ECD7, 0x97A5980A, 0xC539B9AA, 0x4D79FE6A,
+  0xF2F3F763, 0x68AF8040, 0xED0C9E56, 0x11B4958B,
+  0xE1EB5A88, 0x8709E6B0, 0xD7E07156, 0x4E29FEA7,
+  0x6366E52D, 0x02D1C000, 0xC4AC8E05, 0x9377F571,
+  0x0C05372A, 0x578535F2, 0x2261BE02, 0xD642A0C9,
+  0xDF13A280, 0x74B55BD2, 0x682199C0, 0xD421E5EC,
+  0x53FB3CE8, 0xC8ADEDB3, 0x28A87FC9, 0x3D959981,
+  0x5C1FF900, 0xFE38D399, 0x0C4EFF0B, 0x062407EA,
+  0xAA2F4FB1, 0x4FB96976, 0x90C79505, 0xB0A8A774,
+  0xEF55A1FF, 0xE59CA2C2, 0xA6B62D27, 0xE66A4263,
+  0xDF65001F, 0x0EC50966, 0xDFDD55BC, 0x29DE0655,
+  0x911E739A, 0x17AF8975, 0x32C7911C, 0x89F89468,
+  0x0D01E980, 0x524755F4, 0x03B63CC9, 0x0CC844B2,
+  0xBCF3F0AA, 0x87AC36E9, 0xE53A7426, 0x01B3D82B,
+  0x1A9E7449, 0x64EE2D7E, 0xCDDBB1DA, 0x01C94910,
+  0xB868BF80, 0x0D26F3FD, 0x9342EDE7, 0x04A5C284,
+  0x636737B6, 0x50F5B616, 0xF24766E3, 0x8ECA36C1,
+  0x136E05DB, 0xFEF18391, 0xFB887A37, 0xD6E7F7D4,
+  0xC7FB7DC9, 0x3063FCDF, 0xB6F589DE, 0xEC2941DA,
+  0x26E46695, 0xB7566419, 0xF654EFC5, 0xD08D58B7,
+  0x48925401, 0xC1BACB7F, 0xE5FF550F, 0xB6083049,
+  0x5BB5D0E8, 0x87D72E5A, 0xAB6A6EE1, 0x223A66CE,
+  0xC62BF3CD, 0x9E0885F9, 0x68CB3E47, 0x086C010F,
+  0xA21DE820, 0xD18B69DE, 0xF3F65777, 0xFA02C3F6,
+  0x407EDAC3, 0xCBB3D550, 0x1793084D, 0xB0D70EBA,
+  0x0AB378D5, 0xD951FB0C, 0xDED7DA56, 0x4124BBE4,
+  0x94CA0B56, 0x0F5755D1, 0xE0E1E56E, 0x6184B5BE,
+  0x580A249F, 0x94F74BC0, 0xE327888E, 0x9F7B5561,
+  0xC3DC0280, 0x05687715, 0x646C6BD7, 0x44904DB3,
+  0x66B4F0A3, 0xC0F1648A, 0x697ED5AF, 0x49E92FF6,
+  0x309E374F, 0x2CB6356A, 0x85808573, 0x4991F840,
+  0x76F0AE02, 0x083BE84D, 0x28421C9A, 0x44489406,
+  0x736E4CB8, 0xC1092910, 0x8BC95FC6, 0x7D869CF4,
+  0x134F616F, 0x2E77118D, 0xB31B2BE1, 0xAA90B472,
+  0x3CA5D717, 0x7D161BBA, 0x9CAD9010, 0xAF462BA2,
+  0x9FE459D2, 0x45D34559, 0xD9F2DA13, 0xDBC65487,
+  0xF3E4F94E, 0x176D486F, 0x097C13EA, 0x631DA5C7,
+  0x445F7382, 0x175683F4, 0xCDC66A97, 0x70BE0288,
+  0xB3CDCF72, 0x6E5DD2F3, 0x20936079, 0x459B80A5,
+  0xBE60E2DB, 0xA9C23101, 0xEBA5315C, 0x224E42F2,
+  0x1C5C1572, 0xF6721B2C, 0x1AD2FFF3, 0x8C25404E,
+  0x324ED72F, 0x4067B7FD, 0x0523138E, 0x5CA3BC78,
+  0xDC0FD66E, 0x75922283, 0x784D6B17, 0x58EBB16E,
+  0x44094F85, 0x3F481D87, 0xFCFEAE7B, 0x77B5FF76,
+  0x8C2302BF, 0xAAF47556, 0x5F46B02A, 0x2B092801,
+  0x3D38F5F7, 0x0CA81F36, 0x52AF4A8A, 0x66D5E7C0,
+  0xDF3B0874, 0x95055110, 0x1B5AD7A8, 0xF61ED5AD,
+  0x6CF6E479, 0x20758184, 0xD0CEFA65, 0x88F7BE58,
+  0x4A046826, 0x0FF6F8F3, 0xA09C7F70, 0x5346ABA0,
+  0x5CE96C28, 0xE176EDA3, 0x6BAC307F, 0x376829D2,
+  0x85360FA9, 0x17E3FE2A, 0x24B79767, 0xF5A96B20,
+  0xD6CD2595, 0x68FF1EBF, 0x7555442C, 0xF19F06BE,
+  0xF9E0659A, 0xEEB9491D, 0x34010718, 0xBB30CAB8,
+  0xE822FE15, 0x88570983, 0x750E6249, 0xDA627E55,
+  0x5E76FFA8, 0xB1534546, 0x6D47DE08, 0xEFE9E7D4
+};
+
+static const u32 cast_sbox6[256] = {
+  0xF6FA8F9D, 0x2CAC6CE1, 0x4CA34867, 0xE2337F7C,
+  0x95DB08E7, 0x016843B4, 0xECED5CBC, 0x325553AC,
+  0xBF9F0960, 0xDFA1E2ED, 0x83F0579D, 0x63ED86B9,
+  0x1AB6A6B8, 0xDE5EBE39, 0xF38FF732, 0x8989B138,
+  0x33F14961, 0xC01937BD, 0xF506C6DA, 0xE4625E7E,
+  0xA308EA99, 0x4E23E33C, 0x79CBD7CC, 0x48A14367,
+  0xA3149619, 0xFEC94BD5, 0xA114174A, 0xEAA01866,
+  0xA084DB2D, 0x09A8486F, 0xA888614A, 0x2900AF98,
+  0x01665991, 0xE1992863, 0xC8F30C60, 0x2E78EF3C,
+  0xD0D51932, 0xCF0FEC14, 0xF7CA07D2, 0xD0A82072,
+  0xFD41197E, 0x9305A6B0, 0xE86BE3DA, 0x74BED3CD,
+  0x372DA53C, 0x4C7F4448, 0xDAB5D440, 0x6DBA0EC3,
+  0x083919A7, 0x9FBAEED9, 0x49DBCFB0, 0x4E670C53,
+  0x5C3D9C01, 0x64BDB941, 0x2C0E636A, 0xBA7DD9CD,
+  0xEA6F7388, 0xE70BC762, 0x35F29ADB, 0x5C4CDD8D,
+  0xF0D48D8C, 0xB88153E2, 0x08A19866, 0x1AE2EAC8,
+  0x284CAF89, 0xAA928223, 0x9334BE53, 0x3B3A21BF,
+  0x16434BE3, 0x9AEA3906, 0xEFE8C36E, 0xF890CDD9,
+  0x80226DAE, 0xC340A4A3, 0xDF7E9C09, 0xA694A807,
+  0x5B7C5ECC, 0x221DB3A6, 0x9A69A02F, 0x68818A54,
+  0xCEB2296F, 0x53C0843A, 0xFE893655, 0x25BFE68A,
+  0xB4628ABC, 0xCF222EBF, 0x25AC6F48, 0xA9A99387,
+  0x53BDDB65, 0xE76FFBE7, 0xE967FD78, 0x0BA93563,
+  0x8E342BC1, 0xE8A11BE9, 0x4980740D, 0xC8087DFC,
+  0x8DE4BF99, 0xA11101A0, 0x7FD37975, 0xDA5A26C0,
+  0xE81F994F, 0x9528CD89, 0xFD339FED, 0xB87834BF,
+  0x5F04456D, 0x22258698, 0xC9C4C83B, 0x2DC156BE,
+  0x4F628DAA, 0x57F55EC5, 0xE2220ABE, 0xD2916EBF,
+  0x4EC75B95, 0x24F2C3C0, 0x42D15D99, 0xCD0D7FA0,
+  0x7B6E27FF, 0xA8DC8AF0, 0x7345C106, 0xF41E232F,
+  0x35162386, 0xE6EA8926, 0x3333B094, 0x157EC6F2,
+  0x372B74AF, 0x692573E4, 0xE9A9D848, 0xF3160289,
+  0x3A62EF1D, 0xA787E238, 0xF3A5F676, 0x74364853,
+  0x20951063, 0x4576698D, 0xB6FAD407, 0x592AF950,
+  0x36F73523, 0x4CFB6E87, 0x7DA4CEC0, 0x6C152DAA,
+  0xCB0396A8, 0xC50DFE5D, 0xFCD707AB, 0x0921C42F,
+  0x89DFF0BB, 0x5FE2BE78, 0x448F4F33, 0x754613C9,
+  0x2B05D08D, 0x48B9D585, 0xDC049441, 0xC8098F9B,
+  0x7DEDE786, 0xC39A3373, 0x42410005, 0x6A091751,
+  0x0EF3C8A6, 0x890072D6, 0x28207682, 0xA9A9F7BE,
+  0xBF32679D, 0xD45B5B75, 0xB353FD00, 0xCBB0E358,
+  0x830F220A, 0x1F8FB214, 0xD372CF08, 0xCC3C4A13,
+  0x8CF63166, 0x061C87BE, 0x88C98F88, 0x6062E397,
+  0x47CF8E7A, 0xB6C85283, 0x3CC2ACFB, 0x3FC06976,
+  0x4E8F0252, 0x64D8314D, 0xDA3870E3, 0x1E665459,
+  0xC10908F0, 0x513021A5, 0x6C5B68B7, 0x822F8AA0,
+  0x3007CD3E, 0x74719EEF, 0xDC872681, 0x073340D4,
+  0x7E432FD9, 0x0C5EC241, 0x8809286C, 0xF592D891,
+  0x08A930F6, 0x957EF305, 0xB7FBFFBD, 0xC266E96F,
+  0x6FE4AC98, 0xB173ECC0, 0xBC60B42A, 0x953498DA,
+  0xFBA1AE12, 0x2D4BD736, 0x0F25FAAB, 0xA4F3FCEB,
+  0xE2969123, 0x257F0C3D, 0x9348AF49, 0x361400BC,
+  0xE8816F4A, 0x3814F200, 0xA3F94043, 0x9C7A54C2,
+  0xBC704F57, 0xDA41E7F9, 0xC25AD33A, 0x54F4A084,
+  0xB17F5505, 0x59357CBE, 0xEDBD15C8, 0x7F97C5AB,
+  0xBA5AC7B5, 0xB6F6DEAF, 0x3A479C3A, 0x5302DA25,
+  0x653D7E6A, 0x54268D49, 0x51A477EA, 0x5017D55B,
+  0xD7D25D88, 0x44136C76, 0x0404A8C8, 0xB8E5A121,
+  0xB81A928A, 0x60ED5869, 0x97C55B96, 0xEAEC991B,
+  0x29935913, 0x01FDB7F1, 0x088E8DFA, 0x9AB6F6F5,
+  0x3B4CBF9F, 0x4A5DE3AB, 0xE6051D35, 0xA0E1D855,
+  0xD36B4CF1, 0xF544EDEB, 0xB0E93524, 0xBEBB8FBD,
+  0xA2D762CF, 0x49C92F54, 0x38B5F331, 0x7128A454,
+  0x48392905, 0xA65B1DB8, 0x851C97BD, 0xD675CF2F
+};
+
+static const u32 cast_sbox7[256] = {
+  0x85E04019, 0x332BF567, 0x662DBFFF, 0xCFC65693,
+  0x2A8D7F6F, 0xAB9BC912, 0xDE6008A1, 0x2028DA1F,
+  0x0227BCE7, 0x4D642916, 0x18FAC300, 0x50F18B82,
+  0x2CB2CB11, 0xB232E75C, 0x4B3695F2, 0xB28707DE,
+  0xA05FBCF6, 0xCD4181E9, 0xE150210C, 0xE24EF1BD,
+  0xB168C381, 0xFDE4E789, 0x5C79B0D8, 0x1E8BFD43,
+  0x4D495001, 0x38BE4341, 0x913CEE1D, 0x92A79C3F,
+  0x089766BE, 0xBAEEADF4, 0x1286BECF, 0xB6EACB19,
+  0x2660C200, 0x7565BDE4, 0x64241F7A, 0x8248DCA9,
+  0xC3B3AD66, 0x28136086, 0x0BD8DFA8, 0x356D1CF2,
+  0x107789BE, 0xB3B2E9CE, 0x0502AA8F, 0x0BC0351E,
+  0x166BF52A, 0xEB12FF82, 0xE3486911, 0xD34D7516,
+  0x4E7B3AFF, 0x5F43671B, 0x9CF6E037, 0x4981AC83,
+  0x334266CE, 0x8C9341B7, 0xD0D854C0, 0xCB3A6C88,
+  0x47BC2829, 0x4725BA37, 0xA66AD22B, 0x7AD61F1E,
+  0x0C5CBAFA, 0x4437F107, 0xB6E79962, 0x42D2D816,
+  0x0A961288, 0xE1A5C06E, 0x13749E67, 0x72FC081A,
+  0xB1D139F7, 0xF9583745, 0xCF19DF58, 0xBEC3F756,
+  0xC06EBA30, 0x07211B24, 0x45C28829, 0xC95E317F,
+  0xBC8EC511, 0x38BC46E9, 0xC6E6FA14, 0xBAE8584A,
+  0xAD4EBC46, 0x468F508B, 0x7829435F, 0xF124183B,
+  0x821DBA9F, 0xAFF60FF4, 0xEA2C4E6D, 0x16E39264,
+  0x92544A8B, 0x009B4FC3, 0xABA68CED, 0x9AC96F78,
+  0x06A5B79A, 0xB2856E6E, 0x1AEC3CA9, 0xBE838688,
+  0x0E0804E9, 0x55F1BE56, 0xE7E5363B, 0xB3A1F25D,
+  0xF7DEBB85, 0x61FE033C, 0x16746233, 0x3C034C28,
+  0xDA6D0C74, 0x79AAC56C, 0x3CE4E1AD, 0x51F0C802,
+  0x98F8F35A, 0x1626A49F, 0xEED82B29, 0x1D382FE3,
+  0x0C4FB99A, 0xBB325778, 0x3EC6D97B, 0x6E77A6A9,
+  0xCB658B5C, 0xD45230C7, 0x2BD1408B, 0x60C03EB7,
+  0xB9068D78, 0xA33754F4, 0xF430C87D, 0xC8A71302,
+  0xB96D8C32, 0xEBD4E7BE, 0xBE8B9D2D, 0x7979FB06,
+  0xE7225308, 0x8B75CF77, 0x11EF8DA4, 0xE083C858,
+  0x8D6B786F, 0x5A6317A6, 0xFA5CF7A0, 0x5DDA0033,
+  0xF28EBFB0, 0xF5B9C310, 0xA0EAC280, 0x08B9767A,
+  0xA3D9D2B0, 0x79D34217, 0x021A718D, 0x9AC6336A,
+  0x2711FD60, 0x438050E3, 0x069908A8, 0x3D7FEDC4,
+  0x826D2BEF, 0x4EEB8476, 0x488DCF25, 0x36C9D566,
+  0x28E74E41, 0xC2610ACA, 0x3D49A9CF, 0xBAE3B9DF,
+  0xB65F8DE6, 0x92AEAF64, 0x3AC7D5E6, 0x9EA80509,
+  0xF22B017D, 0xA4173F70, 0xDD1E16C3, 0x15E0D7F9,
+  0x50B1B887, 0x2B9F4FD5, 0x625ABA82, 0x6A017962,
+  0x2EC01B9C, 0x15488AA9, 0xD716E740, 0x40055A2C,
+  0x93D29A22, 0xE32DBF9A, 0x058745B9, 0x3453DC1E,
+  0xD699296E, 0x496CFF6F, 0x1C9F4986, 0xDFE2ED07,
+  0xB87242D1, 0x19DE7EAE, 0x053E561A, 0x15AD6F8C,
+  0x66626C1C, 0x7154C24C, 0xEA082B2A, 0x93EB2939,
+  0x17DCB0F0, 0x58D4F2AE, 0x9EA294FB, 0x52CF564C,
+  0x9883FE66, 0x2EC40581, 0x763953C3, 0x01D6692E,
+  0xD3A0C108, 0xA1E7160E, 0xE4F2DFA6, 0x693ED285,
+  0x74904698, 0x4C2B0EDD, 0x4F757656, 0x5D393378,
+  0xA132234F, 0x3D321C5D, 0xC3F5E194, 0x4B269301,
+  0xC79F022F, 0x3C997E7E, 0x5E4F9504, 0x3FFAFBBD,
+  0x76F7AD0E, 0x296693F4, 0x3D1FCE6F, 0xC61E45BE,
+  0xD3B5AB34, 0xF72BF9B7, 0x1B0434C0, 0x4E72B567,
+  0x5592A33D, 0xB5229301, 0xCFD2A87F, 0x60AEB767,
+  0x1814386B, 0x30BCC33D, 0x38A0C07D, 0xFD1606F2,
+  0xC363519B, 0x589DD390, 0x5479F8E6, 0x1CB8D647,
+  0x97FD61A9, 0xEA7759F4, 0x2D57539D, 0x569A58CF,
+  0xE84E63AD, 0x462E1B78, 0x6580F87E, 0xF3817914,
+  0x91DA55F4, 0x40A230F3, 0xD1988F35, 0xB6E318D2,
+  0x3FFA50BC, 0x3D40F021, 0xC3C0BDAE, 0x4958C24C,
+  0x518F36B2, 0x84B1D370, 0x0FEDCE83, 0x878DDADA,
+  0xF2A279C7, 0x94E01BE8, 0x90716F4B, 0x954B8AA3
+};
+
+static const u32 cast_sbox8[256] = {
+  0xE216300D, 0xBBDDFFFC, 0xA7EBDABD, 0x35648095,
+  0x7789F8B7, 0xE6C1121B, 0x0E241600, 0x052CE8B5,
+  0x11A9CFB0, 0xE5952F11, 0xECE7990A, 0x9386D174,
+  0x2A42931C, 0x76E38111, 0xB12DEF3A, 0x37DDDDFC,
+  0xDE9ADEB1, 0x0A0CC32C, 0xBE197029, 0x84A00940,
+  0xBB243A0F, 0xB4D137CF, 0xB44E79F0, 0x049EEDFD,
+  0x0B15A15D, 0x480D3168, 0x8BBBDE5A, 0x669DED42,
+  0xC7ECE831, 0x3F8F95E7, 0x72DF191B, 0x7580330D,
+  0x94074251, 0x5C7DCDFA, 0xABBE6D63, 0xAA402164,
+  0xB301D40A, 0x02E7D1CA, 0x53571DAE, 0x7A3182A2,
+  0x12A8DDEC, 0xFDAA335D, 0x176F43E8, 0x71FB46D4,
+  0x38129022, 0xCE949AD4, 0xB84769AD, 0x965BD862,
+  0x82F3D055, 0x66FB9767, 0x15B80B4E, 0x1D5B47A0,
+  0x4CFDE06F, 0xC28EC4B8, 0x57E8726E, 0x647A78FC,
+  0x99865D44, 0x608BD593, 0x6C200E03, 0x39DC5FF6,
+  0x5D0B00A3, 0xAE63AFF2, 0x7E8BD632, 0x70108C0C,
+  0xBBD35049, 0x2998DF04, 0x980CF42A, 0x9B6DF491,
+  0x9E7EDD53, 0x06918548, 0x58CB7E07, 0x3B74EF2E,
+  0x522FFFB1, 0xD24708CC, 0x1C7E27CD, 0xA4EB215B,
+  0x3CF1D2E2, 0x19B47A38, 0x424F7618, 0x35856039,
+  0x9D17DEE7, 0x27EB35E6, 0xC9AFF67B, 0x36BAF5B8,
+  0x09C467CD, 0xC18910B1, 0xE11DBF7B, 0x06CD1AF8,
+  0x7170C608, 0x2D5E3354, 0xD4DE495A, 0x64C6D006,
+  0xBCC0C62C, 0x3DD00DB3, 0x708F8F34, 0x77D51B42,
+  0x264F620F, 0x24B8D2BF, 0x15C1B79E, 0x46A52564,
+  0xF8D7E54E, 0x3E378160, 0x7895CDA5, 0x859C15A5,
+  0xE6459788, 0xC37BC75F, 0xDB07BA0C, 0x0676A3AB,
+  0x7F229B1E, 0x31842E7B, 0x24259FD7, 0xF8BEF472,
+  0x835FFCB8, 0x6DF4C1F2, 0x96F5B195, 0xFD0AF0FC,
+  0xB0FE134C, 0xE2506D3D, 0x4F9B12EA, 0xF215F225,
+  0xA223736F, 0x9FB4C428, 0x25D04979, 0x34C713F8,
+  0xC4618187, 0xEA7A6E98, 0x7CD16EFC, 0x1436876C,
+  0xF1544107, 0xBEDEEE14, 0x56E9AF27, 0xA04AA441,
+  0x3CF7C899, 0x92ECBAE6, 0xDD67016D, 0x151682EB,
+  0xA842EEDF, 0xFDBA60B4, 0xF1907B75, 0x20E3030F,
+  0x24D8C29E, 0xE139673B, 0xEFA63FB8, 0x71873054,
+  0xB6F2CF3B, 0x9F326442, 0xCB15A4CC, 0xB01A4504,
+  0xF1E47D8D, 0x844A1BE5, 0xBAE7DFDC, 0x42CBDA70,
+  0xCD7DAE0A, 0x57E85B7A, 0xD53F5AF6, 0x20CF4D8C,
+  0xCEA4D428, 0x79D130A4, 0x3486EBFB, 0x33D3CDDC,
+  0x77853B53, 0x37EFFCB5, 0xC5068778, 0xE580B3E6,
+  0x4E68B8F4, 0xC5C8B37E, 0x0D809EA2, 0x398FEB7C,
+  0x132A4F94, 0x43B7950E, 0x2FEE7D1C, 0x223613BD,
+  0xDD06CAA2, 0x37DF932B, 0xC4248289, 0xACF3EBC3,
+  0x5715F6B7, 0xEF3478DD, 0xF267616F, 0xC148CBE4,
+  0x9052815E, 0x5E410FAB, 0xB48A2465, 0x2EDA7FA4,
+  0xE87B40E4, 0xE98EA084, 0x5889E9E1, 0xEFD390FC,
+  0xDD07D35B, 0xDB485694, 0x38D7E5B2, 0x57720101,
+  0x730EDEBC, 0x5B643113, 0x94917E4F, 0x503C2FBA,
+  0x646F1282, 0x7523D24A, 0xE0779695, 0xF9C17A8F,
+  0x7A5B2121, 0xD187B896, 0x29263A4D, 0xBA510CDF,
+  0x81F47C9F, 0xAD1163ED, 0xEA7B5965, 0x1A00726E,
+  0x11403092, 0x00DA6D77, 0x4A0CDD61, 0xAD1F4603,
+  0x605BDFB0, 0x9EEDC364, 0x22EBE6A8, 0xCEE7D28A,
+  0xA0E736A0, 0x5564A6B9, 0x10853209, 0xC7EB8F37,
+  0x2DE705CA, 0x8951570F, 0xDF09822B, 0xBD691A6C,
+  0xAA12E4F2, 0x87451C0F, 0xE0F6A27A, 0x3ADA4819,
+  0x4CF1764F, 0x0D771C2B, 0x67CDB156, 0x350D8384,
+  0x5938FA0F, 0x42399EF3, 0x36997B07, 0x0E84093D,
+  0x4AA93E61, 0x8360D87B, 0x1FA98B0C, 0x1149382C,
+  0xE97625A5, 0x0614D1B7, 0x0E25244B, 0x0C768347,
+  0x589E8D82, 0x0D2059D1, 0xA466BB1E, 0xF8DA0A82,
+  0x04F19130, 0xBA6E4EC0, 0x99265164, 0x1EE7230D,
+  0x50B2AD80, 0xEAEE6801, 0x8DB2A283, 0xEA8BF59E
+};
+
diff --git a/configure.in b/configure.in
new file mode 100755 (executable)
index 0000000..6f9bd70
--- /dev/null
@@ -0,0 +1,10 @@
+# $Id$
+AC_INIT(sha.c)
+
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_RANLIB
+
+AC_C_CONST
+
+AC_OUTPUT(Makefile)
diff --git a/desCode.h b/desCode.h
new file mode 100644 (file)
index 0000000..c38e491
--- /dev/null
+++ b/desCode.h
@@ -0,0 +1,414 @@
+/*
+ *     des - fast & portable DES encryption & decryption.
+ *     Copyright (C) 1992  Dana L. How
+ *     Please see the file `README' for the complete copyright notice.
+ */
+
+
+
+#include "des.h"
+
+#include "RCSID.h"
+RCSID2(desCode_hRcs, "$Id$");
+
+extern unsigned INT32 des_keymap[], des_bigmap[];
+
+/* optional customization:
+ * the idea here is to alter the code so it will still run correctly
+ * on any machine,  but the quickest on the specific machine in mind.
+ * note that these silly tweaks can give you a 15%-20% speed improvement
+ * on the sparc -- it's probably even more significant on the 68000. */
+
+/* take care of machines with incredibly few registers */
+#if    defined(i386)
+#define        REGISTER                /* only x, y, z will be declared register */
+#else
+#define        REGISTER        register
+#endif /* i386 */
+
+/* is auto inc/dec faster than 7bit unsigned indexing? */
+#if    defined(vax) || defined(mc68000)
+#define        FIXR            r += 32;
+#define        FIXS            s +=  8;
+#define        PREV(v,o)       *--v
+#define        NEXT(v,o)       *v++
+#else
+#define        FIXR
+#define        FIXS
+#define        PREV(v,o)       v[o]
+#define        NEXT(v,o)       v[o]
+#endif
+
+/* if no machine type, default is indexing, 6 registers and cheap literals */
+#if    !defined(i386) && !defined(vax) && !defined(mc68000) && !defined(sparc)
+#define        vax
+#endif
+
+
+/* handle a compiler which can't reallocate registers */
+/* The BYTE type is used as parameter for the encrypt/decrypt functions.
+ * It's pretty bad to have the function prototypes depend on
+ * a macro definition that the users of the function doesn't
+ * know about. - Niels */
+#if    0                       /* didn't feel like deleting */
+#define        SREGFREE        ; s = (unsigned INT8 *) D
+#define        DEST            s
+#define        D               m0
+#define        BYTE            unsigned INT32
+#else
+#define        SREGFREE
+#define        DEST            d
+#define        D               d
+#define        BYTE            unsigned INT8
+#endif
+
+/* handle constants in the optimal way for 386 & vax */
+/* 386: we declare 3 register variables (see above) and use 3 more variables;
+ * vax: we use 6 variables, all declared register;
+ * we assume address literals are cheap & unrestricted;
+ * we assume immediate constants are cheap & unrestricted. */
+#if    defined(i386) || defined(vax)
+#define        MQ0      des_bigmap
+#define        MQ1     (des_bigmap +  64)
+#define        MQ2     (des_bigmap + 128)
+#define        MQ3     (des_bigmap + 192)
+#define        HQ0(z)                          /*      z |= 0X01000000L; */
+#define        HQ2(z)                          /*      z |= 0X03000200L; */
+#define        LQ0(z)  0XFCFC & z
+#define        LQ1(z)  0XFCFC & z
+#define        LQ2(z)  0XFCFC & z
+#define        LQ3(z)  0XFCFC & z
+#define        SQ      16
+#define        MS0      des_keymap 
+#define        MS1     (des_keymap +  64)
+#define        MS2     (des_keymap + 128)
+#define        MS3     (des_keymap + 192)
+#define        MS4     (des_keymap + 256)
+#define        MS5     (des_keymap + 320)
+#define        MS6     (des_keymap + 384)
+#define        MS7     (des_keymap + 448)
+#define        HS(z)
+#define        LS0(z)  0XFC & z
+#define        LS1(z)  0XFC & z
+#define        LS2(z)  0XFC & z
+#define        LS3(z)  0XFC & z
+#define        REGQUICK
+#define        SETQUICK
+#define        REGSMALL
+#define        SETSMALL
+#endif /* defined(i386) || defined(vax) */
+
+/* handle constants in the optimal way for mc68000 */
+/* in addition to the core 6 variables, we declare 3 registers holding constants
+ * and 4 registers holding address literals.
+ * at most 6 data values and 5 address values are actively used at once.
+ * we assume address literals are so expensive we never use them;
+ * we assume constant index offsets > 127 are expensive, so they are not used.
+ * we assume all constants are expensive and put them in registers,
+ * including shift counts greater than 8. */
+#if    defined(mc68000)
+#define        MQ0     m0
+#define        MQ1     m1
+#define        MQ2     m2
+#define        MQ3     m3
+#define        HQ0(z)
+#define        HQ2(z)
+#define        LQ0(z)  k0 & z
+#define        LQ1(z)  k0 & z
+#define        LQ2(z)  k0 & z
+#define        LQ3(z)  k0 & z
+#define        SQ      k1
+#define        MS0     m0
+#define        MS1     m0
+#define        MS2     m1
+#define        MS3     m1
+#define        MS4     m2
+#define        MS5     m2
+#define        MS6     m3
+#define        MS7     m3
+#define        HS(z)   z |= k0;
+#define        LS0(z)  k1 & z
+#define        LS1(z)  k2 & z
+#define        LS2(z)  k1 & z
+#define        LS3(z)  k2 & z
+#define        REGQUICK                                \
+       register unsigned INT32 k0, k1;                 \
+       register unsigned INT32 *m0, *m1, *m2, *m3;
+#define        SETQUICK                                \
+       ; k0 = 0XFCFC                           \
+       ; k1 = 16                               \
+       /*k2 = 28 to speed up ROL */            \
+       ; m0 = des_bigmap                       \
+       ; m1 = m0 + 64                          \
+       ; m2 = m1 + 64                          \
+       ; m3 = m2 + 64
+#define        REGSMALL                                \
+       register unsigned INT32 k0, k1, k2;             \
+       register unsigned INT32 *m0, *m1, *m2, *m3;
+#define        SETSMALL                                \
+       ; k0 = 0X01000100L                      \
+       ; k1 = 0X0FC                            \
+       ; k2 = 0X1FC                            \
+       ; m0 = des_keymap                       \
+       ; m1 = m0 + 128                         \
+       ; m2 = m1 + 128                         \
+       ; m3 = m2 + 128
+#endif /* defined(mc68000) */
+
+/* handle constants in the optimal way for sparc */
+/* in addition to the core 6 variables, we either declare:
+ * 4 registers holding address literals and 1 register holding a constant, or
+ * 8 registers holding address literals.
+ * up to 14 register variables are declared (sparc has %i0-%i5, %l0-%l7).
+ * we assume address literals are so expensive we never use them;
+ * we assume any constant with >10 bits is expensive and put it in a register,
+ * and any other is cheap and is coded in-line. */
+#if    defined(sparc)
+#define        MQ0     m0
+#define        MQ1     m1
+#define        MQ2     m2
+#define        MQ3     m3
+#define        HQ0(z)
+#define        HQ2(z)
+#define        LQ0(z)  k0 & z
+#define        LQ1(z)  k0 & z
+#define        LQ2(z)  k0 & z
+#define        LQ3(z)  k0 & z
+#define        SQ      16
+#define        MS0     m0
+#define        MS1     m1
+#define        MS2     m2
+#define        MS3     m3
+#define        MS4     m4
+#define        MS5     m5
+#define        MS6     m6
+#define        MS7     m7
+#define        HS(z)
+#define        LS0(z)  0XFC & z
+#define        LS1(z)  0XFC & z
+#define        LS2(z)  0XFC & z
+#define        LS3(z)  0XFC & z
+#define        REGQUICK                                \
+       register unsigned INT32 k0;             \
+       register unsigned INT32 *m0, *m1, *m2, *m3;
+#define        SETQUICK                                \
+       ; k0 = 0XFCFC                           \
+       ; m0 = des_bigmap                       \
+       ; m1 = m0 + 64                          \
+       ; m2 = m1 + 64                          \
+       ; m3 = m2 + 64
+#define        REGSMALL                                \
+       register unsigned INT32 *m0, *m1, *m2, *m3, *m4, *m5, *m6, *m7;
+#define        SETSMALL                                \
+       ; m0 = des_keymap                       \
+       ; m1 = m0 + 64                          \
+       ; m2 = m1 + 64                          \
+       ; m3 = m2 + 64                          \
+       ; m4 = m3 + 64                          \
+       ; m5 = m4 + 64                          \
+       ; m6 = m5 + 64                          \
+       ; m7 = m6 + 64
+#endif /* defined(sparc) */
+
+
+/* some basic stuff */
+
+/* generate addresses from a base and an index */
+#define        ADD(b,x)        (unsigned INT32 *) ((unsigned INT8 *)b + (x))
+
+/* low level rotate operations */
+#define        NOP(d,c,o)
+#define        ROL(d,c,o)      d = d << c | d >> o
+#define        ROR(d,c,o)      d = d >> c | d << o
+#define        ROL1(d)         ROL(d, 1, 31)
+#define        ROR1(d)         ROR(d, 1, 31)
+
+/* elementary swap for doing IP/FP */
+#define        SWAP(x,y,m,b)                           \
+       z  = ((x >> b) ^ y) & m;                \
+       x ^= z << b;                            \
+       y ^= z
+
+
+/* the following macros contain all the important code fragments */
+
+/* load input data, then setup special registers holding constants */
+#define        TEMPQUICK(LOAD)                         \
+       REGQUICK                                \
+       LOAD()                                  \
+       SETQUICK
+#define        TEMPSMALL(LOAD)                         \
+       REGSMALL                                \
+       LOAD()                                  \
+       SETSMALL
+
+/* load data */
+#define        LOADDATA(x,y)                           \
+       FIXS                                    \
+       y  = PREV(s, 7); y<<= 8;                \
+       y |= PREV(s, 6); y<<= 8;                \
+       y |= PREV(s, 5); y<<= 8;                \
+       y |= PREV(s, 4);                        \
+       x  = PREV(s, 3); x<<= 8;                \
+       x |= PREV(s, 2); x<<= 8;                \
+       x |= PREV(s, 1); x<<= 8;                \
+       x |= PREV(s, 0)                         \
+       SREGFREE
+/* load data without initial permutation and put into efficient position */
+#define        LOADCORE()                              \
+       LOADDATA(x, y);                         \
+       ROR1(x);                                \
+       ROR1(y)
+/* load data, do the initial permutation and put into efficient position */
+#define        LOADFIPS()                              \
+       LOADDATA(y, x);                         \
+       SWAP(x, y, 0X0F0F0F0FL, 004);           \
+       SWAP(y, x, 0X0000FFFFL, 020);           \
+       SWAP(x, y, 0X33333333L, 002);           \
+       SWAP(y, x, 0X00FF00FFL, 010);           \
+       ROR1(x);                                \
+       z  = (x ^ y) & 0X55555555L;             \
+       y ^= z;                                 \
+       x ^= z;                                 \
+       ROR1(y)
+
+
+/* core encryption/decryption operations */
+/* S box mapping and P perm */
+#define        KEYMAPSMALL(x,z,mq0,mq1,hq,lq0,lq1,sq,ms0,ms1,ms2,ms3,hs,ls0,ls1,ls2,ls3)\
+       hs(z)                                   \
+       x ^= *ADD(ms3, ls3(z));                 \
+       z>>= 8;                                 \
+       x ^= *ADD(ms2, ls2(z));                 \
+       z>>= 8;                                 \
+       x ^= *ADD(ms1, ls1(z));                 \
+       z>>= 8;                                 \
+       x ^= *ADD(ms0, ls0(z))
+/* alternate version: use 64k of tables */
+#define        KEYMAPQUICK(x,z,mq0,mq1,hq,lq0,lq1,sq,ms0,ms1,ms2,ms3,hs,ls0,ls1,ls2,ls3)\
+       hq(z)                                   \
+       x ^= *ADD(mq0, lq0(z));                 \
+       z>>= sq;                                \
+       x ^= *ADD(mq1, lq1(z))
+/* apply 24 key bits and do the odd  s boxes */
+#define        S7S1(x,y,z,r,m,KEYMAP,LOAD)             \
+       z  = LOAD(r, m);                        \
+       z ^= y;                                 \
+       KEYMAP(x,z,MQ0,MQ1,HQ0,LQ0,LQ1,SQ,MS0,MS1,MS2,MS3,HS,LS0,LS1,LS2,LS3)
+/* apply 24 key bits and do the even s boxes */
+#define        S6S0(x,y,z,r,m,KEYMAP,LOAD)             \
+       z  = LOAD(r, m);                        \
+       z ^= y;                                 \
+       ROL(z, 4, 28);                          \
+       KEYMAP(x,z,MQ2,MQ3,HQ2,LQ2,LQ3,SQ,MS4,MS5,MS6,MS7,HS,LS0,LS1,LS2,LS3)
+/* actual iterations.  equivalent except for UPDATE & swapping m and n */
+#define        ENCR(x,y,z,r,m,n,KEYMAP)                \
+       S7S1(x,y,z,r,m,KEYMAP,NEXT);            \
+       S6S0(x,y,z,r,n,KEYMAP,NEXT)
+#define        DECR(x,y,z,r,m,n,KEYMAP)                \
+       S6S0(x,y,z,r,m,KEYMAP,PREV);            \
+       S7S1(x,y,z,r,n,KEYMAP,PREV)
+
+/* write out result in correct byte order */
+#define        SAVEDATA(x,y)                           \
+       NEXT(DEST, 0) = x; x>>= 8;              \
+       NEXT(DEST, 1) = x; x>>= 8;              \
+       NEXT(DEST, 2) = x; x>>= 8;              \
+       NEXT(DEST, 3) = x;                      \
+       NEXT(DEST, 4) = y; y>>= 8;              \
+       NEXT(DEST, 5) = y; y>>= 8;              \
+       NEXT(DEST, 6) = y; y>>= 8;              \
+       NEXT(DEST, 7) = y
+/* write out result */
+#define        SAVECORE()                              \
+       ROL1(x);                                \
+       ROL1(y);                                \
+       SAVEDATA(y, x)
+/* do final permutation and write out result */
+#define        SAVEFIPS()                              \
+       ROL1(x);                                \
+       z  = (x ^ y) & 0X55555555L;             \
+       y ^= z;                                 \
+       x ^= z;                                 \
+       ROL1(y);                                \
+       SWAP(x, y, 0X00FF00FFL, 010);           \
+       SWAP(y, x, 0X33333333L, 002);           \
+       SWAP(x, y, 0X0000FFFFL, 020);           \
+       SWAP(y, x, 0X0F0F0F0FL, 004);           \
+       SAVEDATA(x, y)
+
+
+/* the following macros contain the encryption/decryption skeletons */
+
+#define        ENCRYPT(NAME, TEMP, LOAD, KEYMAP, SAVE) \
+                                               \
+void                                           \
+NAME(REGISTER BYTE *D,                          \
+     REGISTER unsigned INT32 *r,                \
+     REGISTER unsigned INT8 *s)                 \
+{                                              \
+       register unsigned INT32 x, y, z;        \
+                                               \
+       /* declare temps & load data */         \
+       TEMP(LOAD);                             \
+                                               \
+       /* do the 16 iterations */              \
+       ENCR(x,y,z,r, 0, 1,KEYMAP);             \
+       ENCR(y,x,z,r, 2, 3,KEYMAP);             \
+       ENCR(x,y,z,r, 4, 5,KEYMAP);             \
+       ENCR(y,x,z,r, 6, 7,KEYMAP);             \
+       ENCR(x,y,z,r, 8, 9,KEYMAP);             \
+       ENCR(y,x,z,r,10,11,KEYMAP);             \
+       ENCR(x,y,z,r,12,13,KEYMAP);             \
+       ENCR(y,x,z,r,14,15,KEYMAP);             \
+       ENCR(x,y,z,r,16,17,KEYMAP);             \
+       ENCR(y,x,z,r,18,19,KEYMAP);             \
+       ENCR(x,y,z,r,20,21,KEYMAP);             \
+       ENCR(y,x,z,r,22,23,KEYMAP);             \
+       ENCR(x,y,z,r,24,25,KEYMAP);             \
+       ENCR(y,x,z,r,26,27,KEYMAP);             \
+       ENCR(x,y,z,r,28,29,KEYMAP);             \
+       ENCR(y,x,z,r,30,31,KEYMAP);             \
+                                               \
+       /* save result */                       \
+       SAVE();                                 \
+                                               \
+       return;                                 \
+}
+
+#define        DECRYPT(NAME, TEMP, LOAD, KEYMAP, SAVE) \
+                                               \
+void                                           \
+NAME(REGISTER BYTE *D,                          \
+     REGISTER unsigned INT32 *r,                \
+     REGISTER unsigned INT8 *s)                 \
+{                                              \
+       register unsigned INT32 x, y, z;        \
+                                               \
+       /* declare temps & load data */         \
+       TEMP(LOAD);                             \
+                                               \
+       /* do the 16 iterations */              \
+       FIXR                                    \
+       DECR(x,y,z,r,31,30,KEYMAP);             \
+       DECR(y,x,z,r,29,28,KEYMAP);             \
+       DECR(x,y,z,r,27,26,KEYMAP);             \
+       DECR(y,x,z,r,25,24,KEYMAP);             \
+       DECR(x,y,z,r,23,22,KEYMAP);             \
+       DECR(y,x,z,r,21,20,KEYMAP);             \
+       DECR(x,y,z,r,19,18,KEYMAP);             \
+       DECR(y,x,z,r,17,16,KEYMAP);             \
+       DECR(x,y,z,r,15,14,KEYMAP);             \
+       DECR(y,x,z,r,13,12,KEYMAP);             \
+       DECR(x,y,z,r,11,10,KEYMAP);             \
+       DECR(y,x,z,r, 9, 8,KEYMAP);             \
+       DECR(x,y,z,r, 7, 6,KEYMAP);             \
+       DECR(y,x,z,r, 5, 4,KEYMAP);             \
+       DECR(x,y,z,r, 3, 2,KEYMAP);             \
+       DECR(y,x,z,r, 1, 0,KEYMAP);             \
+                                               \
+       /* save result */                       \
+       SAVE();                                 \
+                                               \
+       return;                                 \
+}
diff --git a/desKerb.c b/desKerb.c
new file mode 100644 (file)
index 0000000..3e32b72
--- /dev/null
+++ b/desKerb.c
@@ -0,0 +1,31 @@
+/*
+ *     des - fast & portable DES encryption & decryption.
+ *     Copyright (C) 1992  Dana L. How
+ *     Please see the file `README' for the complete copyright notice.
+ */
+
+#include "des.h"
+
+#include "RCSID.h"
+RCSID2(desKerb_cRcs, "$Id$");
+
+/* permit the default style of des functions to be changed */
+
+DesFunc *DesCryptFuncs[2] = { DesSmallFipsDecrypt, DesSmallFipsEncrypt };
+
+/* kerberos-compatible key schedule function */
+
+int
+des_key_sched(unsigned INT8 *k, unsigned INT32 *s)
+{
+       return DesMethod(s, k);
+}
+
+/* kerberos-compatible des coding function */
+
+int
+des_ecb_encrypt(unsigned INT8 *s, unsigned INT8 *d, unsigned INT32 *r, int e)
+{
+       (*DesCryptFuncs[e])(d, r, s);
+       return 0;
+}
diff --git a/desQuick.c b/desQuick.c
new file mode 100644 (file)
index 0000000..b5220c2
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *     des - fast & portable DES encryption & decryption.
+ *     Copyright (C) 1992  Dana L. How
+ *     Please see the file `README' for the complete copyright notice.
+ *
+ * Slightly edited by Niels Möller, 1997
+ */
+
+#include "des.h"
+
+#include "RCSID.h"
+RCSID2(desQuick_cRcs, "$Id$");
+
+extern unsigned INT32 des_keymap[];
+
+
+/* static information */
+
+static int depth = 0;          /* keep track of the request depth */
+unsigned INT32 des_bigmap[0x4000];     /* big lookup table */
+
+/* fill in the 64k table used by the `quick' option */
+
+void
+DesQuickInit(void)
+{
+       int s1, s3, x;
+       unsigned INT32 * t0, * t1, * t2, * t3;
+
+       if ( depth++ )
+               return;
+
+       t0 = des_bigmap;
+       t1 = t0 + 64;
+       t2 = t1 + 64;
+       t3 = t2 + 64;
+
+       for ( s3 = 63; s3 >= 0; s3-- ) {
+               for ( s1 = 63; s1 >= 0; s1-- ) {
+                       x = (s3 << 8) | s1;
+                       t0[x] = des_keymap[s3+128] ^ des_keymap[s1+192];
+                       t1[x] = des_keymap[s3    ] ^ des_keymap[s1+ 64];
+                       t2[x] = des_keymap[s3+384] ^ des_keymap[s1+448];
+                       t3[x] = des_keymap[s3+256] ^ des_keymap[s1+320];
+               }
+       }
+}
+
+/* free the 64k table, if necessary */
+
+void
+DesQuickDone(void)
+{
+}
diff --git a/desTest.c b/desTest.c
new file mode 100644 (file)
index 0000000..10b2aa8
--- /dev/null
+++ b/desTest.c
@@ -0,0 +1,186 @@
+/*
+ *     des - fast & portable DES encryption & decryption.
+ *     Copyright (C) 1992  Dana L. How
+ *     Please see the file `README' for the complete copyright notice.
+ *
+ *     Exercise the DES routines and collect performance statistics.
+ */
+
+#ifndef        lint
+static char desTest_cRcs[] = "$Id$";
+#endif
+
+#include       "des.h"
+#include <stdio.h>
+
+/* define now(w) to be the elapsed time in hundredths of a second */
+
+#ifndef __NT__
+#include       <sys/time.h>
+#include       <sys/resource.h>
+extern getrusage();
+static struct rusage usage;
+#define        now(w)  (                                               \
+               (void)getrusage(RUSAGE_SELF, &usage),           \
+               usage.ru_utime.tv_sec  * 100 +                  \
+               usage.ru_utime.tv_usec / 10000                  \
+       )
+#else
+#include       <windows.h>
+#define now(w) 0
+#endif
+
+/* test data
+ * the tests (key0-3, text0-3) are cribbed from code which is (c) 1988 MIT
+ */
+
+byte keyt[8] =         {0x5d, 0x85, 0x91, 0x73, 0xcb, 0x49, 0xdf, 0x2f};
+byte key0[8] =         {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80};
+byte key1[8] =         {0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};
+byte key2[8] =         {0x08, 0x19, 0x2a, 0x3b, 0x4c, 0x5d, 0x6e, 0x7f};
+byte key3[8] =         {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
+byte textt[8] =                {0x67, 0x1f, 0xc8, 0x93, 0x46, 0x5e, 0xab, 0x1e};
+byte text0[8] =                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+byte text1[8] =                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40};
+byte text2[8] =                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+byte text3[8] =                {'N',  'o',  'w',  ' ',  'i',  's',  ' ',  't' };
+
+/* work areas */
+
+DesKeys keys;
+byte cipher[8], output[8];
+
+/* noisy interfaces to the routines under test */
+
+static void
+method(key)
+byte *key;
+{
+       int j;
+
+       (void)printf("\nkey:\t");
+       for ( j = 0; j < 8; j++ )
+               (void)printf("%02X ", key[j]);
+       if ( des_key_sched(key, keys) )
+               (void)printf("W");
+       (void)printf("\t");
+}
+
+static void
+encode(src, dst)
+byte *src, *dst;
+{
+       int j;
+
+       (void)printf("clear:\t");
+       for (j = 0; j < 8; j++)
+               (void)printf("%02X ", src[j]);
+
+       (void)des_ecb_encrypt(src, dst, keys, 1);
+
+       (void)printf("\tcipher:\t");
+       for (j = 0; j < 8; j++)
+               (void)printf("%02X ", dst[j]);
+       (void)printf("\n");
+}
+
+static void
+decode(src, dst, check)
+byte *src, *dst, *check;
+{
+       int j;
+
+       (void)printf("cipher:\t");
+       for (j = 0; j < 8; j++)
+               (void)printf("%02X ", src[j]);
+
+       (void)des_ecb_encrypt(src, dst, keys, 0);
+
+       (void)printf("\tclear:\t");
+       for (j = 0; j < 8; j++)
+               (void)printf("%02X ", dst[j]);
+
+        if(!memcmp(dst,check,8))
+           printf("Ok\n");
+        else
+           printf("FAIL\n");
+}
+
+/* run the tests */
+
+int
+main()
+{
+       int j, m, e, n;
+       void (*f)();
+       static char * expect[] = {
+               "57 99 F7 2A D2 3F AE 4C", "9C C6 2D F4 3B 6E ED 74",
+               "90 E6 96 A2 AD 56 50 0D", "A3 80 E0 2A 6B E5 46 96",
+               "43 5C FF C5 68 B3 70 1D", "25 DD AC 3E 96 17 64 67",
+               "80 B5 07 E1 E6 A7 47 3D", "3F A4 0E 8A 98 4D 48 15",
+       };
+       static void (*funcs[])() = {
+               DesQuickCoreEncrypt, DesQuickFipsEncrypt,
+               DesSmallCoreEncrypt, DesSmallFipsEncrypt,
+               DesQuickCoreDecrypt, DesQuickFipsDecrypt,
+               DesSmallCoreDecrypt, DesSmallFipsDecrypt };
+       static char * names[] = {
+               "QuickCore", "QuickFips",
+               "SmallCore", "SmallFips" };
+
+       n = 0;
+       DesQuickInit();
+
+       /* do timing info first */
+
+       f = (void (*)())DesMethod;
+       j = 10000;
+       m = now(0);
+       do
+               (*f)(keys, keyt);
+       while ( --j );
+       m = now(1) - m;
+
+       do {
+                   DesCryptFuncs[0] = funcs[n+4];
+               f = DesCryptFuncs[1] = funcs[n  ];
+               j = 100000;
+               e = now(0);
+               do
+                       (*f)(cipher, keys, textt);
+               while ( --j );
+               e = now(1) - e;
+
+               (void)printf(   "%s:  setkey,%5duS;  encode,%3d.%1duS.\n",
+                               names[n], m, e/10, e%10);
+
+               /* now check functionality */
+
+               method(key0);
+               (void)printf("cipher?\t%s\n", expect[(n % 2) + 0]);
+               encode(text0, cipher);
+               decode(cipher, output, text0);
+
+               method(key1);
+               (void)printf("cipher?\t%s\n", expect[(n % 2) + 2]);
+               encode(text1, cipher);
+               decode(cipher, output, text1);
+
+               method(key2);
+               (void)printf("cipher?\t%s\n", expect[(n % 2) + 4]);
+               encode(text2, cipher);
+               decode(cipher, output, text2);
+
+               method(key3);
+               (void)printf("cipher?\t%s\n", expect[(n % 2) + 6]);
+               encode(text3, cipher);
+               decode(cipher, output, text3);
+
+               (void)printf("%c", "\n\f\n\0"[n]);
+
+       } while ( ++n < 4 );
+
+       DesQuickDone();
+       fflush(stdout);
+       return 0;
+}
diff --git a/desUtil.c b/desUtil.c
new file mode 100644 (file)
index 0000000..bdf014b
--- /dev/null
+++ b/desUtil.c
@@ -0,0 +1,168 @@
+/*
+ *     des - fast & portable DES encryption & decryption.
+ *     Copyright (C) 1992  Dana L. How
+ *     Please see the file `README' for the complete copyright notice.
+ */
+
+#include       "desCode.h"
+
+#include "RCSID.h"
+RCSID2(desUtil_cRcs, "$Id$");
+
+/* various tables */
+
+unsigned INT32 des_keymap[] = {
+#include       "keymap.h"
+};
+
+static unsigned INT8 rotors[] = {
+#include       "rotors.h"
+};
+static char parity[] = {
+#include       "parity.h"
+};
+
+RCSID2(ego, "\n\nFast DES Library Copyright (c) 1991 Dana L. How\n\n");
+
+
+/* set up the method list from the key */
+
+int
+DesMethod(unsigned INT32 *method, unsigned INT8 *k)
+{
+       register unsigned INT32 n, w;
+       register char * b0, * b1;
+       char bits0[56], bits1[56];
+
+       /* check for bad parity and weak keys */
+       b0 = parity;
+       n  = b0[k[0]]; n <<= 4;
+       n |= b0[k[1]]; n <<= 4;
+       n |= b0[k[2]]; n <<= 4;
+       n |= b0[k[3]]; n <<= 4;
+       n |= b0[k[4]]; n <<= 4;
+       n |= b0[k[5]]; n <<= 4;
+       n |= b0[k[6]]; n <<= 4;
+       n |= b0[k[7]];
+       w  = 0X88888888L;
+       /* report bad parity in key */
+       if ( n & w )
+               return -1;
+       /* report a weak or semi-weak key */
+       if ( !((n - (w >> 3)) & w) ) {  /* 1 in 10^10 keys passes this test */
+               if ( n < 0X41415151 ) {
+                       if ( n < 0X31312121 ) {
+                               if ( n < 0X14141515 ) {
+                                       /* 01 01 01 01 01 01 01 01 */
+                                       if ( n == 0X11111111 ) return -2;
+                                       /* 01 1F 01 1F 01 0E 01 0E */
+                                       if ( n == 0X13131212 ) return -2;
+                               } else {
+                                       /* 01 E0 01 E0 01 F1 01 F1 */
+                                       if ( n == 0X14141515 ) return -2;
+                                       /* 01 FE 01 FE 01 FE 01 FE */
+                                       if ( n == 0X16161616 ) return -2;
+                               }
+                       } else {
+                               if ( n < 0X34342525 ) {
+                                       /* 1F 01 1F 01 0E 01 0E 01 */
+                                       if ( n == 0X31312121 ) return -2;
+                                       /* 1F 1F 1F 1F 0E 0E 0E 0E */   /* ? */
+                                       if ( n == 0X33332222 ) return -2;
+                               } else {
+                                       /* 1F E0 1F E0 0E F1 0E F1 */
+                                       if ( n == 0X34342525 ) return -2;
+                                       /* 1F FE 1F FE 0E FE 0E FE */
+                                       if ( n == 0X36362626 ) return -2;
+                               }
+                       }
+               } else {
+                       if ( n < 0X61616161 ) {
+                               if ( n < 0X44445555 ) {
+                                       /* E0 01 E0 01 F1 01 F1 01 */
+                                       if ( n == 0X41415151 ) return -2;
+                                       /* E0 1F E0 1F F1 0E F1 0E */
+                                       if ( n == 0X43435252 ) return -2;
+                               } else {
+                                       /* E0 E0 E0 E0 F1 F1 F1 F1 */   /* ? */
+                                       if ( n == 0X44445555 ) return -2;
+                                       /* E0 FE E0 FE F1 FE F1 FE */
+                                       if ( n == 0X46465656 ) return -2;
+                               }
+                       } else {
+                               if ( n < 0X64646565 ) {
+                                       /* FE 01 FE 01 FE 01 FE 01 */
+                                       if ( n == 0X61616161 ) return -2;
+                                       /* FE 1F FE 1F FE 0E FE 0E */
+                                       if ( n == 0X63636262 ) return -2;
+                               } else {
+                                       /* FE E0 FE E0 FE F1 FE F1 */
+                                       if ( n == 0X64646565 ) return -2;
+                                       /* FE FE FE FE FE FE FE FE */
+                                       if ( n == 0X66666666 ) return -2;
+                               }
+                       }
+               }
+       }
+
+       /* explode the bits */
+       n = 56;
+       b0 = bits0;
+       b1 = bits1;
+       do {
+               w = (256 | *k++) << 2;
+               do {
+                       --n;
+                       b1[n] = 8 & w;
+                       w >>= 1;
+                       b0[n] = 4 & w;
+               } while ( w >= 16 );
+       } while ( n );
+
+       /* put the bits in the correct places */
+       n = 16;
+       k = rotors;
+       do {
+               w   = (b1[k[ 0   ]] | b0[k[ 1   ]]) << 4;
+               w  |= (b1[k[ 2   ]] | b0[k[ 3   ]]) << 2;
+               w  |=  b1[k[ 4   ]] | b0[k[ 5   ]];
+               w <<= 8;
+               w  |= (b1[k[ 6   ]] | b0[k[ 7   ]]) << 4;
+               w  |= (b1[k[ 8   ]] | b0[k[ 9   ]]) << 2;
+               w  |=  b1[k[10   ]] | b0[k[11   ]];
+               w <<= 8;
+               w  |= (b1[k[12   ]] | b0[k[13   ]]) << 4;
+               w  |= (b1[k[14   ]] | b0[k[15   ]]) << 2;
+               w  |=  b1[k[16   ]] | b0[k[17   ]];
+               w <<= 8;
+               w  |= (b1[k[18   ]] | b0[k[19   ]]) << 4;
+               w  |= (b1[k[20   ]] | b0[k[21   ]]) << 2;
+               w  |=  b1[k[22   ]] | b0[k[23   ]];
+
+               method[0] = w;
+
+               w   = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4;
+               w  |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2;
+               w  |=  b1[k[ 4+24]] | b0[k[ 5+24]];
+               w <<= 8;
+               w  |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4;
+               w  |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2;
+               w  |=  b1[k[10+24]] | b0[k[11+24]];
+               w <<= 8;
+               w  |= (b1[k[12+24]] | b0[k[13+24]]) << 4;
+               w  |= (b1[k[14+24]] | b0[k[15+24]]) << 2;
+               w  |=  b1[k[16+24]] | b0[k[17+24]];
+               w <<= 8;
+               w  |= (b1[k[18+24]] | b0[k[19+24]]) << 4;
+               w  |= (b1[k[20+24]] | b0[k[21+24]]) << 2;
+               w  |=  b1[k[22+24]] | b0[k[23+24]];
+
+               ROR(w, 4, 28);          /* could be eliminated */
+               method[1] = w;
+
+               k       += 48;
+               method  += 2;
+       } while ( --n );
+
+       return 0;
+}
diff --git a/descore.README b/descore.README
new file mode 100644 (file)
index 0000000..d95d8f0
--- /dev/null
@@ -0,0 +1,313 @@
+des - fast & portable DES encryption & decryption.
+Copyright (C) 1992  Dana L. How
+
+This program is free software; you can redistribute it and/or modify
+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.
+
+This program 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 this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Author's address: how@isl.stanford.edu
+
+$Id$
+
+
+==>> To compile after untarring/unsharring, just `make' <<==
+
+
+This package was designed with the following goals:
+1.     Highest possible encryption/decryption PERFORMANCE.
+2.     PORTABILITY to any byte-addressable machine with a 32bit unsigned C type
+3.     Plug-compatible replacement for KERBEROS's low-level routines.
+
+
+performance comparison to other available des code which i could
+compile on a SPARCStation 1 (cc -O4):
+
+this code (byte-order independent):
+   30us per encryption (options: 64k tables, no IP/FP)
+   33us per encryption (options: 64k tables, FIPS standard bit ordering)
+   45us per encryption (options:  2k tables, no IP/FP)
+   49us per encryption (options:  2k tables, FIPS standard bit ordering)
+  275us to set a new key (uses 1k of key tables)
+       this has the quickest encryption/decryption routines i've seen.
+       since i was interested in fast des filters rather than crypt(3)
+       and password cracking, i haven't really bothered yet to speed up
+       the key setting routine. also, i have no interest in re-implementing
+       all the other junk in the mit kerberos des library, so i've just
+       provided my routines with little stub interfaces so they can be
+       used as drop-in replacements with mit's code or any of the mit-
+       compatible packages below. (note that the first two timings above
+       are highly variable because of cache effects).
+
+kerberos des replacement from australia:
+   68us per encryption (uses 2k of tables)
+   96us to set a new key (uses 2.25k of key tables)
+       this is a very nice package which implements the most important
+       of the optimizations which i did in my encryption routines.
+       it's a bit weak on common low-level optimizations which is why
+       it's 39%-106% slower.  because he was interested in fast crypt(3) and
+       password-cracking applications,  he also used the same ideas to
+       speed up the key-setting routines with impressive results.
+       (at some point i may do the same in my package).  he also implements
+       the rest of the mit des library.
+       (code from eay@psych.psy.uq.oz.au via comp.sources.misc)
+
+fast crypt(3) package from denmark:
+       the des routine here is buried inside a loop to do the
+       crypt function and i didn't feel like ripping it out and measuring
+       performance. his code takes 26 sparc instructions to compute one
+       des iteration; above, Quick (64k) takes 21 and Small (2k) takes 37.
+       he claims to use 280k of tables but the iteration calculation seems
+       to use only 128k.  his tables and code are machine independent.
+       (code from glad@daimi.aau.dk via alt.sources or comp.sources.misc)
+
+swedish reimplementation of Kerberos des library
+  108us per encryption (uses 34k worth of tables)
+  134us to set a new key (uses 32k of key tables to get this speed!)
+       the tables used seem to be machine-independent;
+       he seems to have included a lot of special case code
+       so that, e.g., `long' loads can be used instead of 4 `char' loads
+       when the machine's architecture allows it.
+       (code obtained from chalmers.se:pub/des)
+
+crack 3.3c package from england:
+       as in crypt above, the des routine is buried in a loop. it's
+       also very modified for crypt.  his iteration code uses 16k
+       of tables and appears to be slow.
+       (code obtained from aem@aber.ac.uk via alt.sources or comp.sources.misc)
+
+``highly optimized'' and tweaked Kerberos/Athena code (byte-order dependent):
+  165us per encryption (uses 6k worth of tables)
+  478us to set a new key (uses <1k of key tables)
+       so despite the comments in this code, it was possible to get
+       faster code AND smaller tables, as well as making the tables
+       machine-independent.
+       (code obtained from prep.ai.mit.edu)
+
+UC Berkeley code (depends on machine-endedness):
+  226us per encryption
+10848us to set a new key
+       table sizes are unclear, but they don't look very small
+       (code obtained from wuarchive.wustl.edu)
+
+
+motivation and history
+
+a while ago i wanted some des routines and the routines documented on sun's
+man pages either didn't exist or dumped core.  i had heard of kerberos,
+and knew that it used des,  so i figured i'd use its routines.  but once
+i got it and looked at the code,  it really set off a lot of pet peeves -
+it was too convoluted, the code had been written without taking
+advantage of the regular structure of operations such as IP, E, and FP
+(i.e. the author didn't sit down and think before coding),
+it was excessively slow,  the author had attempted to clarify the code
+by adding MORE statements to make the data movement more `consistent'
+instead of simplifying his implementation and cutting down on all data
+movement (in particular, his use of L1, R1, L2, R2), and it was full of
+idiotic `tweaks' for particular machines which failed to deliver significant
+speedups but which did obfuscate everything.  so i took the test data
+from his verification program and rewrote everything else.
+
+a while later i ran across the great crypt(3) package mentioned above.
+the fact that this guy was computing 2 sboxes per table lookup rather
+than one (and using a MUCH larger table in the process) emboldened me to
+do the same - it was a trivial change from which i had been scared away
+by the larger table size.  in his case he didn't realize you don't need to keep
+the working data in TWO forms, one for easy use of half the sboxes in
+indexing, the other for easy use of the other half; instead you can keep
+it in the form for the first half and use a simple rotate to get the other
+half.  this means i have (almost) half the data manipulation and half
+the table size.  in fairness though he might be encoding something particular
+to crypt(3) in his tables - i didn't check.
+
+i'm glad that i implemented it the way i did, because this C version is
+portable (the ifdef's are performance enhancements) and it is faster
+than versions hand-written in assembly for the sparc!
+
+
+porting notes
+
+one thing i did not want to do was write an enormous mess
+which depended on endedness and other machine quirks,
+and which necessarily produced different code and different lookup tables
+for different machines.  see the kerberos code for an example
+of what i didn't want to do; all their endedness-specific `optimizations'
+obfuscate the code and in the end were slower than a simpler machine
+independent approach.  however, there are always some portability
+considerations of some kind, and i have included some options
+for varying numbers of register variables.
+perhaps some will still regard the result as a mess!
+
+1) i assume everything is byte addressable, although i don't actually
+   depend on the byte order, and that bytes are 8 bits.
+   i assume word pointers can be freely cast to and from char pointers.
+   note that 99% of C programs make these assumptions.
+   i always use unsigned char's if the high bit could be set.
+2) the typedef `word' means a 32 bit unsigned integral type.
+   if `unsigned long' is not 32 bits, change the typedef in desCore.h.
+   i assume sizeof(word) == 4 EVERYWHERE.
+
+the (worst-case) cost of my NOT doing endedness-specific optimizations
+in the data loading and storing code surrounding the key iterations
+is less than 12%.  also, there is the added benefit that
+the input and output work areas do not need to be word-aligned.
+
+
+OPTIONAL performance optimizations
+
+1) you should define one of `i386,' `vax,' `mc68000,' or `sparc,'
+   whichever one is closest to the capabilities of your machine.
+   see the start of desCode.h to see exactly what this selection implies.
+   note that if you select the wrong one, the des code will still work;
+   these are just performance tweaks.
+2) for those with functional `asm' keywords: you should change the
+   ROR and ROL macros to use machine rotate instructions if you have them.
+   this will save 2 instructions and a temporary per use,
+   or about 32 to 40 instructions per en/decryption.
+
+these optimizations are all rather persnickety, yet with them you should
+be able to get performance equal to assembly-coding, except that:
+1) with the lack of a bit rotate operator in C, rotates have to be synthesized
+   from shifts.  so access to `asm' will speed things up if your machine
+   has rotates, as explained above in (3).
+2) if your machine has less than 12 32-bit registers i doubt your compiler will
+   generate good code.
+   `i386' tries to configure the code for a 386 by only declaring 3 registers
+   (it appears that gcc can use ebx, esi and edi to hold register variables).
+   however, if you like assembly coding, the 386 does have 7 32-bit registers,
+   and if you use ALL of them, use `scaled by 8' address modes with displacement
+   and other tricks, you can get reasonable routines for DesQuickCore... with
+   about 250 instructions apiece.  For DesSmall... it will help to rearrange
+   des_keymap, i.e., now the sbox # is the high part of the index and
+   the 6 bits of data is the low part; it helps to exchange these.
+   since i have no way to conveniently test it i have not provided my
+   shoehorned 386 version.
+
+coding notes
+
+the en/decryption routines each use 6 necessary register variables,
+with 4 being actively used at once during the inner iterations.
+if you don't have 4 register variables get a new machine.
+up to 8 more registers are used to hold constants in some configurations.
+
+i assume that the use of a constant is more expensive than using a register:
+a) additionally, i have tried to put the larger constants in registers.
+   registering priority was by the following:
+       anything more than 12 bits (bad for RISC and CISC)
+       greater than 127 in value (can't use movq or byte immediate on CISC)
+       9-127 (may not be able to use CISC shift immediate or add/sub quick),
+       1-8 were never registered, being the cheapest constants.
+b) the compiler may be too stupid to realize table and table+256 should
+   be assigned to different constant registers and instead repetitively
+   do the arithmetic, so i assign these to explicit `m' register variables
+   when possible and helpful.
+
+i assume that indexing is cheaper or equivalent to auto increment/decrement,
+where the index is 7 bits unsigned or smaller.
+this assumption is reversed for 68k and vax.
+
+i assume that addresses can be cheaply formed from two registers,
+or from a register and a small constant.  i never use the `two registers
+and offset' form you see in some CISC machines.
+all index scaling is done explicitly - no hidden shifts by log2(sizeof).
+
+the code is written so that even a dumb compiler
+should never need more than one hidden temporary,
+increasing the chance that everything will fit in the registers.
+KEEP THIS MORE SUBTLE POINT IN MIND IF YOU REWRITE ANYTHING.
+
+
+special efficient data format
+
+bits are manipulated in this arrangement most of the time (S7 S5 S3 S1):
+       003130292827xxxx242322212019xxxx161514131211xxxx080706050403xxxx
+(the x bits are still there, i'm just emphasizing where the S boxes are).
+bits are rotated left 4 when computing S6 S4 S2 S0:
+       282726252423xxxx201918171615xxxx121110090807xxxx040302010031xxxx
+the rightmost two bits are usually cleared so the lower byte can be used
+as an index into an sbox mapping table. the next two x'd bits are set
+to various values to access different parts of the tables.
+
+
+how to use the routines
+
+datatypes:
+       pointer to 8 byte area of type DesData
+       used to hold keys and input/output blocks to des.
+
+       pointer to 128 byte area of type DesKeys
+       used to hold full 768-bit key.
+       must be long-aligned.
+
+DesQuickInit()
+       call this before using any other routine with `Quick' in its name.
+       it generates the special 64k table these routines need.
+DesQuickDone()
+       frees this table
+
+DesMethod(m, k)
+       m points to a 128byte block, k points to an 8 byte des key
+       which must have odd parity (or -1 is returned) and which must
+       not be a (semi-)weak key (or -2 is returned).
+       normally DesMethod() returns 0.
+       m is filled in from k so that when one of the routines below
+       is called with m, the routine will act like standard des
+       en/decryption with the key k. if you use DesMethod,
+       you supply a standard 56bit key; however, if you fill in
+       m yourself, you will get a 768bit key - but then it won't
+       be standard.  it's 768bits not 1024 because the least significant
+       two bits of each byte are not used.  and yes, each byte controls
+       a specific sbox during a specific iteration.
+       NOTE: actually, every other word has been rotated right 4 bits
+       to reduce the number of temporaries needed when the key is used.
+       you really shouldn't use the 768bit format directly;  i should
+       provide a routine that converts 128 6-bit bytes (specified in
+       S-box mapping order or something) into the right format for you.
+       this would entail some byte concatenation and rotation.
+
+Des{Small|Quick}{Fips|Core}{Encrypt|Decrypt}(d, m, s)
+       performs des on the 8 bytes at s into the 8 bytes at d. (d,s: char *).
+       uses m as a 768bit key as explained above.
+       the Encrypt|Decrypt choice is obvious.
+       Fips|Core determines whether a completely standard FIPS initial
+       and final permutation is done; if not, then the data is loaded
+       and stored in a nonstandard bit order (FIPS w/o IP/FP).
+       Fips slows down Quick by 10%, Small by 9%.
+       Small|Quick determines whether you use the normal routine
+       or the crazy quick one which gobbles up 64k more of memory.
+       Small is 50% slower then Quick, but Quick needs 32 times as much
+       memory.  Quick is included for programs that do nothing but DES,
+       e.g., encryption filters, etc.
+
+
+Getting it to compile on your machine
+
+there are no machine-dependencies in the code (see porting),
+except perhaps the `now()' macro in desTest.c.
+ALL generated tables are machine independent.
+you should edit the Makefile with the appropriate optimization flags
+for your compiler (MAX optimization).
+
+
+Speeding up kerberos (and/or its des library)
+
+note that i have included a kerberos-compatible interface in desUtil.c
+through the functions des_key_sched() and des_ecb_encrypt().
+to use these with kerberos or kerberos-compatible code put desCore.a
+ahead of the kerberos-compatible library on your linker's command line.
+you should not need to #include desCore.h;  just include the header
+file provided with the kerberos library.
+
+Other uses
+
+the macros in desCode.h would be very useful for putting inline des
+functions in more complicated encryption routines.
diff --git a/desdata.c b/desdata.c
new file mode 100644 (file)
index 0000000..4089be7
--- /dev/null
+++ b/desdata.c
@@ -0,0 +1,191 @@
+/*
+ *     des - fast & portable DES encryption & decryption.
+ *     Copyright (C) 1992  Dana L. How
+ *     Please see the file `README' for the complete copyright notice.
+ *
+ *     Generate tables used by desUtil.c and desCode.h.
+ */
+
+#include       "desinfo.h"
+
+#include       "desCode.h"
+
+#include "RCSID.h"
+RCSID2(desdata_cRcs, "$Id$");
+
+/* list of weak and semi-weak keys
+
+        +0   +1   +2   +3   +4   +5   +6   +7
+       0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01
+       0x01 0x1f 0x01 0x1f 0x01 0x0e 0x01 0x0e
+       0x01 0xe0 0x01 0xe0 0x01 0xf1 0x01 0xf1
+       0x01 0xfe 0x01 0xfe 0x01 0xfe 0x01 0xfe
+       0x1f 0x01 0x1f 0x01 0x0e 0x01 0x0e 0x01
+       0x1f 0x1f 0x1f 0x1f 0x0e 0x0e 0x0e 0x0e
+       0x1f 0xe0 0x1f 0xe0 0x0e 0xf1 0x0e 0xf1
+       0x1f 0xfe 0x1f 0xfe 0x0e 0xfe 0x0e 0xfe
+       0xe0 0x01 0xe0 0x01 0xf1 0x01 0xf1 0x01
+       0xe0 0x1f 0xe0 0x1f 0xf1 0x0e 0xf1 0x0e
+       0xe0 0xe0 0xe0 0xe0 0xf1 0xf1 0xf1 0xf1
+       0xe0 0xfe 0xe0 0xfe 0xf1 0xfe 0xf1 0xfe
+       0xfe 0x01 0xfe 0x01 0xfe 0x01 0xfe 0x01
+       0xfe 0x1f 0xfe 0x1f 0xfe 0x0e 0xfe 0x0e
+       0xfe 0xe0 0xfe 0xe0 0xfe 0xf1 0xfe 0xf1
+       0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe 0xfe
+ */
+
+/* key bit order in each method pair: bits 31->00 of 1st, bits 31->00 of 2nd */
+/* this does not reflect the rotate of the 2nd word */
+
+#define        S(box,bit)      (box*6+bit)
+int korder[] = {
+       S(7, 5), S(7, 4), S(7, 3), S(7, 2), S(7, 1), S(7, 0),
+       S(5, 5), S(5, 4), S(5, 3), S(5, 2), S(5, 1), S(5, 0),
+       S(3, 5), S(3, 4), S(3, 3), S(3, 2), S(3, 1), S(3, 0),
+       S(1, 5), S(1, 4), S(1, 3), S(1, 2), S(1, 1), S(1, 0),
+       S(6, 5), S(6, 4), S(6, 3), S(6, 2), S(6, 1), S(6, 0),
+       S(4, 5), S(4, 4), S(4, 3), S(4, 2), S(4, 1), S(4, 0),
+       S(2, 5), S(2, 4), S(2, 3), S(2, 2), S(2, 1), S(2, 0),
+       S(0, 5), S(0, 4), S(0, 3), S(0, 2), S(0, 1), S(0, 0),
+};
+
+/* the order in which the algorithm accesses the s boxes */
+
+int sorder[] = {
+       7, 5, 3, 1, 6, 4, 2, 0,
+};
+
+int printf(const char *, ...);
+
+int
+main(int argc, char **argv)
+{
+       unsigned INT32 d, i, j, k, l, m, n, s;
+       char b[256], ksr[56];
+
+       switch ( argv[1][0] ) {
+
+       /*
+        * <<< make the key parity table >>>
+        */
+
+case 'p':
+       (void)printf(
+"/* automagically produced - do not fuss with this information */\n\n");
+
+       /* store parity information */
+       for ( i = 0; i < 256; i++ ) {
+               j  = i;
+               j ^= j >> 4;    /* bits 3-0 have pairs */
+               j ^= j << 2;    /* bits 3-2 have quads */
+               j ^= j << 1;    /* bit  3 has the entire eight (no cox) */
+               b[i] = 8 & ~j;  /* 0 is okay and 8 is bad parity */
+       }
+
+       /* only these characters can appear in a weak key */
+       b[0x01] = 1;
+       b[0x0e] = 2;
+       b[0x1f] = 3;
+       b[0xe0] = 4;
+       b[0xf1] = 5;
+       b[0xfe] = 6;
+
+       /* print it out */
+       for ( i = 0; i < 256; i++ ) {
+               (void)printf("%d,", b[i]);
+               if ( (i & 31) == 31 )
+                       (void)printf("\n");
+       }
+
+       break;
+
+
+       /*
+        * <<< make the key usage table >>>
+        */
+
+case 'r':
+       (void)printf("/* automagically made - do not fuss with this */\n\n");
+
+       /* KL specifies the initial key bit positions */
+       for (i = 0; i < 56; i++)
+               ksr[i] = (KL[i] - 1) ^ 7;
+
+       for (i = 0; i < 16; i++) {
+
+               /* apply the appropriate number of left shifts */
+               for (j = 0; j < KS[i]; j++) {
+                       m = ksr[ 0];
+                       n = ksr[28];
+                       for (k = 0; k < 27; k++)
+                               ksr[k     ] = ksr[k +  1],
+                               ksr[k + 28] = ksr[k + 29];
+                       ksr[27] = m;
+                       ksr[55] = n;
+               }
+
+               /* output the key bit numbers */
+               for (j = 0; j < 48; j++) {
+                       m = ksr[KC[korder[j]] - 1];
+                       m = (m / 8) * 7 + (m % 8) - 1;
+                       m = 55 - m;
+                       (void)printf(" %2ld,", (long) m);
+                       if ((j % 12) == 11)
+                               (void)printf("\n");
+               }
+               (void)printf("\n");
+       }
+
+       break;
+
+
+       /*
+        * <<< make the keymap table >>>
+        */
+
+case 'k':
+       (void)printf("/* automagically made - do not fuss with this */\n\n");
+
+       for ( i = 0; i <= 7 ; i++ ) {
+               s = sorder[i];
+               for ( d = 0; d <= 63; d++ ) {
+                       /* flip bits */
+                       k =     ((d << 5) & 32) |
+                               ((d << 3) & 16) |
+                               ((d << 1) &  8) |
+                               ((d >> 1) &  4) |
+                               ((d >> 3) &  2) |
+                               ((d >> 5) &  1) ;
+                       /* more bit twiddling */
+                       l =     ((k << 0) & 32) |       /* overlap bit */
+                               ((k << 4) & 16) |       /* overlap bit */
+                               ((k >> 1) & 15) ;       /* unique bits */
+                       /* look up s box value */
+                       m = SB[s][l];
+                       /* flip bits */
+                       n =     ((m << 3) &  8) |
+                               ((m << 1) &  4) |
+                               ((m >> 1) &  2) |
+                               ((m >> 3) &  1) ;
+                       /* put in correct nybble */
+                       n <<= (s << 2);
+                       /* perform p permutation */
+                       for ( m = j = 0; j < 32; j++ )
+                               if ( n & (1 << (SP[j] - 1)) )
+                                       m |= (1 << j);
+                       /* rotate right (alg keeps everything rotated by 1) */
+                       ROR(m, 1, 31);
+                       /* print it out */
+                       (void)printf(" 0x%08lx,", (long) m);
+                       if ( ( d & 3 ) == 3 )
+                               (void)printf("\n");
+               }
+               (void)printf("\n");
+       }
+
+       break;
+
+       }
+
+       return 0;
+}
diff --git a/desinfo.h b/desinfo.h
new file mode 100644 (file)
index 0000000..8c90ff8
--- /dev/null
+++ b/desinfo.h
@@ -0,0 +1,96 @@
+/*
+ *     des - fast & portable DES encryption & decryption.
+ *     Copyright (C) 1992  Dana L. How
+ *     Please see the file `README' for the complete copyright notice.
+ *
+ *     Tables describing DES rather than just this implementation.
+ *     These are used in desdata but NOT in runtime code.
+ */
+
+#include "RCSID.h"
+RCSID2(desinfo_hRcs, "$Id$");
+
+/* the initial permutation, E selection, and final permutation are hardwired */
+
+/* Key Load: how to load the shift register from the user key */
+
+unsigned char KL[] = {
+
+       57, 49, 41, 33, 25, 17,  9,  1, 58, 50, 42, 34, 26, 18,
+       10,  2, 59, 51, 43, 35, 27, 19, 11,  3, 60, 52, 44, 36,
+
+       63, 55, 47, 39, 31, 23, 15,  7, 62, 54, 46, 38, 30, 22,
+       14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 28, 20, 12,  4,
+};
+
+/* Key Shift: how many times to shift the key shift register */
+
+unsigned char KS[] = {
+
+       1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
+};
+
+/* Key Choose: which key bits from shift reg are used in the key schedule */
+
+unsigned char KC[] = {
+
+       14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,
+       23, 19, 12,  4, 26,  8, 16,  7, 27, 20, 13,  2,
+
+       41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
+       44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32,
+};
+
+/* S Boxes */
+
+unsigned char SB[8][64] = {
+  {
+       14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
+        0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
+        4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
+       15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
+  },{
+       15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
+        3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
+        0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
+       13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,
+  },{
+       10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
+       13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
+       13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
+        1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
+  },{
+        7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
+       13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
+       10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
+        3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
+  },{
+        2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
+       14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
+        4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
+       11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
+  },{
+       12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
+       10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
+        9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
+        4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
+  },{
+        4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
+       13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
+        1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
+        6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
+  },{
+       13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
+        1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
+        7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
+        2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
+  }
+};
+
+/* Sbox Permutation */
+
+char SP[] = {  
+
+       16,  7, 20, 21, 29, 12, 28, 17,  1, 15, 23, 26,  5, 18, 31, 10,
+        2,  8, 24, 14, 32, 27,  3,  9, 19, 13, 30,  6, 22, 11,  4, 25,
+};
diff --git a/idea.c b/idea.c
new file mode 100644 (file)
index 0000000..59a0a14
--- /dev/null
+++ b/idea.c
@@ -0,0 +1,266 @@
+/* $Id$
+ *
+ * The basic IDEA transformation
+ *
+ * This implementation is taken from pgp, see note below.
+ *
+ * Only primitive operations are done here, chaining modes etc
+ * are implemented in a higher level program.
+ *
+ **********************************************************************
+ *
+ *    idea.c - C source code for IDEA block cipher.
+ *      IDEA (International Data Encryption Algorithm), formerly known as 
+ *      IPES (Improved Proposed Encryption Standard).
+ *      Algorithm developed by Xuejia Lai and James L. Massey, of ETH Zurich.
+ *      This implementation modified and derived from original C code 
+ *      developed by Xuejia Lai.  
+ *      Zero-based indexing added, names changed from IPES to IDEA.
+ *      CFB functions added.  Random number routines added.
+ *
+ *      Extensively optimized and restructured by Colin Plumb.
+ *
+ ***********************************************************************
+ *
+ * Some changes including endianness cleanup done by Niels Möller.
+ *
+ */
+
+#include "crypto_types.h"
+#include <idea.h>
+
+#include <string.h>
+
+/*-------------------------------------------------------------*/
+
+#define low16(x)  ((x) & 0xffff)
+
+/*
+ *     Multiplication, modulo (2**16)+1
+ * Note that this code is structured on the assumption that
+ * untaken branches are cheaper than taken branches, and the
+ * compiler doesn't schedule branches.
+ */
+#ifdef SMALL_CACHE
+const static unsigned INT16
+mul(unsigned INT16 a, unsigned INT16 b)
+{
+  register unsigned INT32 p;
+
+  p = (unsigned INT32)a * b;
+  if (p)
+    {
+      b = low16(p);
+      a = p>>16;
+      return (b - a) + (b < a);
+    }
+  else if (a)
+    {
+      return 1-b;
+    }
+  else
+    {
+      return 1-a;
+    }
+} /* mul */
+#endif /* SMALL_CACHE */
+
+/*
+ * Compute the multiplicative inverse of x, modulo 65537, using Euclid's
+ * algorithm. It is unrolled twice to avoid swapping the registers each
+ * iteration, and some subtracts of t have been changed to adds.
+ */
+static const unsigned INT16
+inv(unsigned INT16 x)     
+{
+  unsigned INT16 t0, t1;
+  unsigned INT16 q, y;
+
+  if (x <= 1)
+    return x;  /* 0 and 1 are self-inverse */
+  t1 = 0x10001L / x;   /* Since x >= 2, this fits into 16 bits */
+  y = 0x10001L % x;
+  if (y == 1)
+    return low16(1-t1);
+  t0 = 1;
+  do
+    {
+      q = x / y;
+      x = x % y;
+      t0 += q * t1;
+      if (x == 1)
+       return t0;
+      q = y / x;
+      y = y % x;
+      t1 += q * t0;
+    }
+  while (y != 1);
+  return low16(1-t1);
+} /* inv */
+
+/*
+ * Expand a 128-bit user key to a working encryption key ctx
+ */
+void
+idea_expand(unsigned INT16 *ctx,
+           const unsigned INT8 *userkey)
+{
+  int i,j;
+  
+  for (j=0; j<8; j++) {
+    ctx[j] = (userkey[0]<<8) + userkey[1];
+    userkey += 2;
+  }
+  for (i=0; j < IDEA_KEYLEN; j++) {
+    i++;
+    ctx[i+7] = ctx[i & 7] << 9 | ctx[(i+1) & 7] >> 7;
+    ctx += i & 8;
+    i &= 7;
+  }
+} /* idea_expand */
+
+/*
+ * Compute IDEA decryption key DK from an expanded IDEA encryption key EK
+ * Note that the input and output may be the same.  Thus, the key is
+ * inverted into an internal buffer, and then copied to the output.
+ */
+void
+idea_invert(unsigned INT16 *d,
+           const unsigned INT16 *e)
+{
+  int i;
+  unsigned INT16 t1, t2, t3;
+  unsigned INT16 temp[IDEA_KEYLEN];
+  unsigned INT16 *p = temp + IDEA_KEYLEN;
+
+  t1 = inv(*e++);
+  t2 = -*e++;
+  t3 = -*e++;
+  *--p = inv(*e++);
+  *--p = t3;
+  *--p = t2;
+  *--p = t1;
+
+  for (i = 0; i < IDEA_ROUNDS-1; i++) {
+    t1 = *e++;
+    *--p = *e++;
+    *--p = t1;
+
+    t1 = inv(*e++);
+    t2 = -*e++;
+    t3 = -*e++;
+    *--p = inv(*e++);
+    *--p = t2;
+    *--p = t3;
+    *--p = t1;
+  }
+  t1 = *e++;
+  *--p = *e++;
+  *--p = t1;
+
+  t1 = inv(*e++);
+  t2 = -*e++;
+  t3 = -*e++;
+  *--p = inv(*e++);
+  *--p = t3;
+  *--p = t2;
+  *--p = t1;
+  /* Copy and destroy temp copy */
+  memcpy(d, temp, sizeof(temp));
+  memset(temp, 0, sizeof(temp));
+} /* idea_invert */
+
+/*
+ * MUL(x,y) computes x = x*y, modulo 0x10001.  Requires two temps, 
+ * t16 and t32.  x is modified, and must me a side-effect-free lvalue.
+ * y may be anything, but unlike x, must be strictly 16 bits even if
+ * low16() is #defined.
+ * All of these are equivalent - see which is faster on your machine
+ */
+#ifdef SMALL_CACHE
+#define MUL(x,y) (x = mul(low16(x),y))
+#else /* !SMALL_CACHE */
+#ifdef AVOID_JUMPS
+#define MUL(x,y) (x = low16(x-1), t16 = low16((y)-1), \
+               t32 = (unsigned INT32)x*t16 + x + t16 + 1, x = low16(t32), \
+               t16 = t32>>16, x = (x-t16) + (x<t16) )
+#else /* !AVOID_JUMPS (default) */
+#define MUL(x,y) \
+       ((t16 = (y)) ? \
+               (x=low16(x)) ? \
+                       t32 = (unsigned INT32)x*t16, \
+                       x = low16(t32), \
+                       t16 = t32>>16, \
+                       x = (x-t16)+(x<t16) \
+               : \
+                       (x = 1-t16) \
+       : \
+               (x = 1-x))
+#endif
+#endif
+
+/* Endian independent conversions */
+#define char2word(dest, p) \
+     do { \
+           (dest) = *(p)++ << 8; (dest) |= *(p)++; \
+       } while(0)
+     
+#define word2char(src, p) \
+     do { \
+           *(p)++ = (src) >> 8; *(p)++ = (src) & 0xff; \
+       } while(0)
+     
+/*     IDEA encryption/decryption algorithm */
+/* Note that in and out can be the same buffer */
+void
+idea_crypt(const unsigned INT16 *key,
+          unsigned INT8 *dest,
+          const unsigned INT8 *src)
+{
+  register unsigned INT16 x1, x2, x3, x4, s2, s3;
+  
+  /* Setup */
+    
+  char2word(x1, src); char2word(x2, src);
+  char2word(x3, src); char2word(x4, src);
+  
+  /* Encrypt */
+  {
+#ifndef SMALL_CACHE
+    register unsigned INT16 t16;       /* Temporaries needed by MUL macro */
+    register unsigned INT32 t32;
+#endif
+    int r = IDEA_ROUNDS;
+    do
+      {
+       MUL(x1,*key++);
+       x2 += *key++;
+       x3 += *key++;
+       MUL(x4, *key++);
+
+       s3 = x3;
+       x3 ^= x1;
+       MUL(x3, *key++);
+       s2 = x2;
+       x2 ^= x4;
+       x2 += x3;
+       MUL(x2, *key++);
+       x3 += x2;
+
+       x1 ^= x2;  x4 ^= x3;
+
+       x2 ^= s3;  x3 ^= s2;
+      }
+    while (--r);
+    MUL(x1, *key++);
+    x3 += *key++;
+    x2 += *key++;
+    MUL(x4, *key);
+  }
+  word2char(x1, dest); word2char(x3, dest);
+  word2char(x2, dest); word2char(x4, dest);
+} /* idea_crypt */
+
+/*-------------------------------------------------------------*/
+
+
diff --git a/include/RCSID.h b/include/RCSID.h
new file mode 100644 (file)
index 0000000..15ca429
--- /dev/null
@@ -0,0 +1,20 @@
+/* $Id$ */
+#ifndef RCSID_H_INCLUDED
+#define RCSID_H_INCLUDED
+
+/* Taken from pike/src/global.h */
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+#define RCSID2(name, X) \
+ static char *name __attribute__ ((unused)) =X
+#elif __GNUC__ == 2
+ /* No need for PIKE_CONCAT() here since gcc supports ## */
+#define RCSID2(name, X) \
+ static char *name = X; \
+ static void *use_##name=(&use_##name, (void *)&name)
+#else
+#define RCSID2(name, X) \
+ static char *name = X
+#endif
+
+#endif /* RCSID_H_INCLUDED */
diff --git a/include/cast.h b/include/cast.h
new file mode 100644 (file)
index 0000000..65ce86c
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * $Id$
+ *
+ *     CAST-128 in C
+ *     Written by Steve Reid <sreid@sea-to-sky.net>
+ *     100% Public Domain - no warranty
+ *     Released 1997.10.11
+ */
+
+#ifndef _CAST_H_INCLUDED
+#define _CAST_H_INCLUDED
+
+#define CAST_MIN_KEYSIZE 5
+#define CAST_MAX_KEYSIZE 16
+#define CAST_BLOCKSIZE 8
+
+#define CAST_SMALL_KEY 10
+#define CAST_SMALL_ROUNDS 12
+#define CAST_FULL_ROUNDS 16
+
+#include "crypto_types.h"
+
+struct cast_key {
+       unsigned INT32 xkey[32];        /* Key, after expansion */
+       unsigned rounds;                /* Number of rounds to use, 12 or 16 */
+};
+
+void cast_setkey(struct cast_key *key, unsigned INT8 *rawkey,
+                unsigned keybytes);
+void cast_encrypt(struct cast_key *key, unsigned INT8 *inblock,
+                 unsigned INT8 *outblock);
+void cast_decrypt(struct cast_key *key, unsigned INT8 *inblock,
+                 unsigned INT8* outblock);
+
+#endif /* ifndef _CAST_H_INCLUDED */
+
diff --git a/include/crypto_types.h b/include/crypto_types.h
new file mode 100644 (file)
index 0000000..9429902
--- /dev/null
@@ -0,0 +1,17 @@
+/* $Id$
+ *
+ * Defines the types INT32 and INT8 */
+
+#ifndef CRYPTO_TYPES_H_INCLUDED
+#define CRYPTO_TYPES_H_INCLUDED
+
+#ifdef PIKE
+#include "pike_types.h"
+#include "global.h"
+#else /* !PIKE */
+#define INT32 long
+#define INT16 short
+#define INT8 char
+#endif
+
+#endif /* CRYPTO_TYPES_H_INCLUDED */
diff --git a/include/des.h b/include/des.h
new file mode 100644 (file)
index 0000000..911eaef
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *     des - fast & portable DES encryption & decryption.
+ *     Copyright (C) 1992  Dana L. How
+ *     Please see the file `README' for the complete copyright notice.
+ *
+ * Slightly edited by Niels Möller, 1997
+ */
+
+#ifndef DES_H_INCLUDED
+#define DES_H_INCLUDED
+
+#include "crypto_types.h"
+
+#include "RCSID.h"
+RCSID2(desCore_hRcs, "$Id$");
+
+#define DES_KEYSIZE 8
+#define DES_BLOCKSIZE 8
+#define DES_EXPANDED_KEYLEN 32
+
+typedef unsigned INT8 DesData[DES_BLOCKSIZE];
+typedef unsigned INT32 DesKeys[DES_EXPANDED_KEYLEN];
+typedef void DesFunc(unsigned INT8 *d, unsigned INT32 *r, unsigned INT8 *s);
+
+extern int DesMethod(unsigned INT32 *method, unsigned INT8 *k);
+extern void DesQuickInit(void);
+extern void DesQuickDone(void);
+extern DesFunc DesQuickCoreEncrypt;
+extern DesFunc DesQuickFipsEncrypt;
+extern DesFunc DesQuickCoreDecrypt;
+extern DesFunc DesQuickFipsDecrypt;
+extern DesFunc DesSmallCoreEncrypt;
+extern DesFunc DesSmallFipsEncrypt;
+extern DesFunc DesSmallCoreDecrypt;
+extern DesFunc DesSmallFipsDecrypt;
+
+extern DesFunc *DesCryptFuncs[2];
+extern int des_key_sched(unsigned INT8 *k, unsigned INT32 *s);
+extern int des_ecb_encrypt(unsigned INT8 *s, unsigned INT8 *d, unsigned INT32 *r, int e);
+
+#endif /*  DES_H_INCLUDED */
diff --git a/include/idea.h b/include/idea.h
new file mode 100644 (file)
index 0000000..27cfefa
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * $Id$
+ */
+
+#ifndef IDEA_H_INCLUDED
+#define IDEA_H_INCLUDED
+
+#define IDEA_KEYSIZE 16
+#define IDEA_BLOCKSIZE 8
+
+#define IDEA_ROUNDS 8
+#define IDEA_KEYLEN (6*IDEA_ROUNDS+4)
+
+#include "crypto_types.h"
+
+void idea_expand(unsigned INT16 *ctx,
+                const unsigned INT8 *key);
+
+void idea_invert(unsigned INT16 *d,
+                const unsigned INT16 *e);
+
+void idea_crypt(const unsigned INT16 *ctx,
+               unsigned INT8 *dest,
+               const unsigned INT8 *src);
+
+#endif /* IDEA_H_INCLUDED */
diff --git a/include/md5.h b/include/md5.h
new file mode 100644 (file)
index 0000000..3e7e9f3
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * $Id$
+ */
+
+#include "crypto_types.h"
+
+#define MD5_DATASIZE    64
+#define MD5_DATALEN     16
+#define MD5_DIGESTSIZE  16
+#define MD5_DIGESTLEN    4
+
+struct md5_ctx {
+  unsigned INT32 digest[MD5_DIGESTLEN]; /* Digest */
+  unsigned INT32 count_l, count_h;      /* Block count */
+  unsigned INT8 block[MD5_DATASIZE];   /* One block buffer */
+  int index;                            /* index into buffer */
+};
+
+void md5_init(struct md5_ctx *ctx);
+void md5_update(struct md5_ctx *ctx, unsigned INT8 *buffer, unsigned INT32 len);
+void md5_final(struct md5_ctx *ctx);
+void md5_digest(struct md5_ctx *ctx, INT8 *s);
+void md5_copy(struct md5_ctx *dest, struct md5_ctx *src);
diff --git a/include/rc4.h b/include/rc4.h
new file mode 100644 (file)
index 0000000..57a46a9
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * $Id$
+ */
+
+#ifndef RC4_H_INCLUDED
+#define RC4_H_INCLUDED
+
+#include "crypto_types.h"
+
+struct rc4_ctx {
+  unsigned INT8 S[256];
+  unsigned INT8 i, j;
+};
+
+#if 0
+void rc4_init(struct rc4_ctx *ctx);
+#endif
+
+void rc4_set_key(struct rc4_ctx *ctx, const unsigned INT8 *key, INT32 len);
+void rc4_crypt(struct rc4_ctx *ctx, unsigned INT8 *dest, const unsigned INT8 *src, INT32 len);
+
+#endif /* RC4_H_INCLUDED */
diff --git a/include/sha.h b/include/sha.h
new file mode 100644 (file)
index 0000000..96f4d78
--- /dev/null
@@ -0,0 +1,26 @@
+/* 
+ * $Id$
+ */
+
+#include "crypto_types.h"
+
+/* The SHA block size and message digest sizes, in bytes */
+
+#define SHA_DATASIZE    64
+#define SHA_DATALEN     16
+#define SHA_DIGESTSIZE  20
+#define SHA_DIGESTLEN    5
+/* The structure for storing SHA info */
+
+struct sha_ctx {
+  unsigned INT32 digest[SHA_DIGESTLEN];  /* Message digest */
+  unsigned INT32 count_l, count_h;       /* 64-bit block count */
+  unsigned INT8 block[SHA_DATASIZE];     /* SHA data buffer */
+  int index;                             /* index into buffer */
+};
+
+void sha_init(struct sha_ctx *ctx);
+void sha_update(struct sha_ctx *ctx, unsigned INT8 *buffer, unsigned INT32 len);
+void sha_final(struct sha_ctx *ctx);
+void sha_digest(struct sha_ctx *ctx, INT8 *s);
+void sha_copy(struct sha_ctx *dest, struct sha_ctx *src);
diff --git a/install-sh b/install-sh
new file mode 100755 (executable)
index 0000000..6bfa7aa
--- /dev/null
@@ -0,0 +1,241 @@
+#! /bin/sh
+#
+# $Id$
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd="$cpprog"
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd="$stripprog"
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+       else
+               instcmd=mkdir
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f $src -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d $dst ]
+       then
+               dst="$dst"/`basename $src`
+       else
+               true
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='   
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp="${pathcomp}${1}"
+       shift
+
+       if [ ! -d "${pathcomp}" ] ;
+        then
+               $mkdirprog "${pathcomp}"
+       else
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               dstfile=`basename $dst $transformbasename | 
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ] 
+       then
+               dstfile=`basename $dst`
+       else
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
+
diff --git a/md5.c b/md5.c
new file mode 100644 (file)
index 0000000..3620f86
--- /dev/null
+++ b/md5.c
@@ -0,0 +1,243 @@
+/*
+ * $Id$
+ *
+ *  md5.c :  Implementation of the MD5 hash function
+ *
+ * Part of the Python Cryptography Toolkit, version 1.0.1
+ * Colin Plumb's original code modified by A.M. Kuchling
+ *
+ * Further hacked and adapted to pike by Niels Möller
+ */
+
+#include "crypto_types.h"
+#include "md5.h"
+
+void md5_copy(struct md5_ctx *dest, struct md5_ctx *src)
+{
+  int i;
+  dest->count_l=src->count_l;
+  dest->count_h=src->count_h;
+  for(i=0; i<MD5_DIGESTLEN; i++)
+    dest->digest[i]=src->digest[i];
+  for(i=0; i < src->index; i++)
+    dest->block[i] = src->block[i];
+  dest->index = src->index;
+}
+
+void md5_init(struct md5_ctx *ctx)
+{
+  ctx->digest[0] = 0x67452301;
+  ctx->digest[1] = 0xefcdab89;
+  ctx->digest[2] = 0x98badcfe;
+  ctx->digest[3] = 0x10325476;
+  
+  ctx->count_l = ctx->count_h = 0;
+  ctx->index = 0;
+}
+
+/* MD5 functions */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+#define ROUND(f, w, x, y, z, data, s) \
+( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
+  
+/* Perform the MD5 transformation on one full block of 16 32-bit words. */
+   
+static void md5_transform(struct md5_ctx *ctx, unsigned INT32 *data)
+{
+  unsigned INT32 a, b, c, d;
+  a = ctx->digest[0];
+  b = ctx->digest[1];
+  c = ctx->digest[2];
+  d = ctx->digest[3];
+
+  ROUND(F1, a, b, c, d, data[ 0] + 0xd76aa478, 7);
+  ROUND(F1, d, a, b, c, data[ 1] + 0xe8c7b756, 12);
+  ROUND(F1, c, d, a, b, data[ 2] + 0x242070db, 17);
+  ROUND(F1, b, c, d, a, data[ 3] + 0xc1bdceee, 22);
+  ROUND(F1, a, b, c, d, data[ 4] + 0xf57c0faf, 7);
+  ROUND(F1, d, a, b, c, data[ 5] + 0x4787c62a, 12);
+  ROUND(F1, c, d, a, b, data[ 6] + 0xa8304613, 17);
+  ROUND(F1, b, c, d, a, data[ 7] + 0xfd469501, 22);
+  ROUND(F1, a, b, c, d, data[ 8] + 0x698098d8, 7);
+  ROUND(F1, d, a, b, c, data[ 9] + 0x8b44f7af, 12);
+  ROUND(F1, c, d, a, b, data[10] + 0xffff5bb1, 17);
+  ROUND(F1, b, c, d, a, data[11] + 0x895cd7be, 22);
+  ROUND(F1, a, b, c, d, data[12] + 0x6b901122, 7);
+  ROUND(F1, d, a, b, c, data[13] + 0xfd987193, 12);
+  ROUND(F1, c, d, a, b, data[14] + 0xa679438e, 17);
+  ROUND(F1, b, c, d, a, data[15] + 0x49b40821, 22);
+
+  ROUND(F2, a, b, c, d, data[ 1] + 0xf61e2562, 5);
+  ROUND(F2, d, a, b, c, data[ 6] + 0xc040b340, 9);
+  ROUND(F2, c, d, a, b, data[11] + 0x265e5a51, 14);
+  ROUND(F2, b, c, d, a, data[ 0] + 0xe9b6c7aa, 20);
+  ROUND(F2, a, b, c, d, data[ 5] + 0xd62f105d, 5);
+  ROUND(F2, d, a, b, c, data[10] + 0x02441453, 9);
+  ROUND(F2, c, d, a, b, data[15] + 0xd8a1e681, 14);
+  ROUND(F2, b, c, d, a, data[ 4] + 0xe7d3fbc8, 20);
+  ROUND(F2, a, b, c, d, data[ 9] + 0x21e1cde6, 5);
+  ROUND(F2, d, a, b, c, data[14] + 0xc33707d6, 9);
+  ROUND(F2, c, d, a, b, data[ 3] + 0xf4d50d87, 14);
+  ROUND(F2, b, c, d, a, data[ 8] + 0x455a14ed, 20);
+  ROUND(F2, a, b, c, d, data[13] + 0xa9e3e905, 5);
+  ROUND(F2, d, a, b, c, data[ 2] + 0xfcefa3f8, 9);
+  ROUND(F2, c, d, a, b, data[ 7] + 0x676f02d9, 14);
+  ROUND(F2, b, c, d, a, data[12] + 0x8d2a4c8a, 20);
+
+  ROUND(F3, a, b, c, d, data[ 5] + 0xfffa3942, 4);
+  ROUND(F3, d, a, b, c, data[ 8] + 0x8771f681, 11);
+  ROUND(F3, c, d, a, b, data[11] + 0x6d9d6122, 16);
+  ROUND(F3, b, c, d, a, data[14] + 0xfde5380c, 23);
+  ROUND(F3, a, b, c, d, data[ 1] + 0xa4beea44, 4);
+  ROUND(F3, d, a, b, c, data[ 4] + 0x4bdecfa9, 11);
+  ROUND(F3, c, d, a, b, data[ 7] + 0xf6bb4b60, 16);
+  ROUND(F3, b, c, d, a, data[10] + 0xbebfbc70, 23);
+  ROUND(F3, a, b, c, d, data[13] + 0x289b7ec6, 4);
+  ROUND(F3, d, a, b, c, data[ 0] + 0xeaa127fa, 11);
+  ROUND(F3, c, d, a, b, data[ 3] + 0xd4ef3085, 16);
+  ROUND(F3, b, c, d, a, data[ 6] + 0x04881d05, 23);
+  ROUND(F3, a, b, c, d, data[ 9] + 0xd9d4d039, 4);
+  ROUND(F3, d, a, b, c, data[12] + 0xe6db99e5, 11);
+  ROUND(F3, c, d, a, b, data[15] + 0x1fa27cf8, 16);
+  ROUND(F3, b, c, d, a, data[ 2] + 0xc4ac5665, 23);
+
+  ROUND(F4, a, b, c, d, data[ 0] + 0xf4292244, 6);
+  ROUND(F4, d, a, b, c, data[ 7] + 0x432aff97, 10);
+  ROUND(F4, c, d, a, b, data[14] + 0xab9423a7, 15);
+  ROUND(F4, b, c, d, a, data[ 5] + 0xfc93a039, 21);
+  ROUND(F4, a, b, c, d, data[12] + 0x655b59c3, 6);
+  ROUND(F4, d, a, b, c, data[ 3] + 0x8f0ccc92, 10);
+  ROUND(F4, c, d, a, b, data[10] + 0xffeff47d, 15);
+  ROUND(F4, b, c, d, a, data[ 1] + 0x85845dd1, 21);
+  ROUND(F4, a, b, c, d, data[ 8] + 0x6fa87e4f, 6);
+  ROUND(F4, d, a, b, c, data[15] + 0xfe2ce6e0, 10);
+  ROUND(F4, c, d, a, b, data[ 6] + 0xa3014314, 15);
+  ROUND(F4, b, c, d, a, data[13] + 0x4e0811a1, 21);
+  ROUND(F4, a, b, c, d, data[ 4] + 0xf7537e82, 6);
+  ROUND(F4, d, a, b, c, data[11] + 0xbd3af235, 10);
+  ROUND(F4, c, d, a, b, data[ 2] + 0x2ad7d2bb, 15);
+  ROUND(F4, b, c, d, a, data[ 9] + 0xeb86d391, 21);
+
+  ctx->digest[0] += a;
+  ctx->digest[1] += b;
+  ctx->digest[2] += c;
+  ctx->digest[3] += d;
+}
+
+#ifndef EXTRACT_UCHAR
+#define EXTRACT_UCHAR(p)  (*(unsigned char *)(p))
+#endif
+
+/* Note that MD5 uses little endian byteorder */
+#define STRING2INT(s) ((((((EXTRACT_UCHAR(s+3) << 8)    \
+                          | EXTRACT_UCHAR(s+2)) << 8)  \
+                        | EXTRACT_UCHAR(s+1)) << 8)    \
+                      | EXTRACT_UCHAR(s))
+  
+static void md5_block(struct md5_ctx *ctx, unsigned INT8 *block)
+{
+  unsigned INT32 data[MD5_DATALEN];
+  int i;
+  
+  /* Update block count */
+  if (!++ctx->count_l)
+    ++ctx->count_h;
+
+  /* Endian independent conversion */
+  for (i = 0; i<16; i++, block += 4)
+    data[i] = STRING2INT(block);
+
+  md5_transform(ctx, data);
+}
+
+void md5_update(struct md5_ctx *ctx,
+                     unsigned INT8 *buffer,
+                     unsigned INT32 len)
+{
+  if (ctx->index)
+  { /* Try to fill partial block */
+    unsigned left = MD5_DATASIZE - ctx->index;
+    if (len < left)
+    {
+      memcpy(ctx->block + ctx->index, buffer, len);
+      ctx->index += len;
+      return; /* Finished */
+    }
+    else
+    {
+      memcpy(ctx->block + ctx->index, buffer, left);
+      md5_block(ctx, ctx->block);
+      buffer += left;
+      len -= left;
+    }
+  }
+  while (len >= MD5_DATASIZE)
+  {
+    md5_block(ctx, buffer);
+    buffer += MD5_DATASIZE;
+    len -= MD5_DATASIZE;
+  }
+  if ((ctx->index = len))     /* This assignment is intended */
+    /* Buffer leftovers */
+    memcpy(ctx->block, buffer, len);
+}
+
+/* Final wrapup - pad to MD5_DATASIZE-byte boundary with the bit pattern
+   1 0* (64-bit count of bits processed, LSB-first) */
+
+void md5_final(struct md5_ctx *ctx)
+{
+  unsigned INT32 data[MD5_DATALEN];
+  int i;
+  int words;
+  
+  i = ctx->index;
+  /* Set the first char of padding to 0x80.  This is safe since there is
+     always at least one byte free */
+  ctx->block[i++] = 0x80;
+
+  /* Fill rest of word */
+  for( ; i & 3; i++)
+    ctx->block[i] = 0;
+
+  /* i is now a multiple of the word size 4 */
+  words = i >> 2;
+  for (i = 0; i < words; i++)
+    data[i] = STRING2INT(ctx->block + 4*i);
+  
+  if (words > (MD5_DATALEN-2))
+    { /* No room for length in this block. Process it and
+       * pad with another one */
+      for (i = words ; i < MD5_DATALEN; i++)
+       data[i] = 0;
+      md5_transform(ctx, data);
+      for (i = 0; i < (MD5_DATALEN-2); i++)
+       data[i] = 0;
+    }
+  else
+    for (i = words ; i < MD5_DATALEN - 2; i++)
+      data[i] = 0;
+  /* Theres 512 = 2^9 bits in one block 
+   * Little-endian order => Least significant word first */
+  data[MD5_DATALEN-1] = (ctx->count_h << 9) | (ctx->count_l >> 23);
+  data[MD5_DATALEN-2] = (ctx->count_l << 9) | (ctx->index << 3);
+  md5_transform(ctx, data);
+}
+
+void md5_digest(struct md5_ctx *ctx, INT8 *s)
+{
+  int i;
+
+  /* Little endian order */
+  for (i = 0; i < MD5_DIGESTLEN; i++)
+    {
+      *s++ = 0xff &  ctx->digest[i];
+      *s++ = 0xff & (ctx->digest[i] >> 8);
+      *s++ = 0xff & (ctx->digest[i] >> 16);
+      *s++ =         ctx->digest[i] >> 24;
+    }
+}
diff --git a/rc4.c b/rc4.c
new file mode 100644 (file)
index 0000000..0b30234
--- /dev/null
+++ b/rc4.c
@@ -0,0 +1,48 @@
+/* rc4.c
+ *
+ */
+
+#include "crypto_types.h"
+#include <rc4.h>
+
+#ifdef RCSID
+RCSID("$Id$");
+#endif
+
+#define SWAP(a,b) do { int _t = a; a = b; b = _t; } while(0)
+
+void rc4_set_key(struct rc4_ctx *ctx, const unsigned INT8 *key, INT32 len)
+{
+  register unsigned INT8 j; /* Depends on the eight-bitness of these variables. */
+  unsigned i;
+  INT32 k;
+
+  /* Initialize context */
+  i = 0;
+  do ctx->S[i] = i; while (++i < 256);
+
+  /* Expand key */
+  i = j = k = 0;
+  do {
+    j += ctx->S[i] + key[k];
+    SWAP(ctx->S[i], ctx->S[j]);
+    k = (k+1) % len; /* Repeat key if needed */
+  } while(++i < 256);
+  
+  ctx->i = ctx->j = 0;
+}
+
+void rc4_crypt(struct rc4_ctx *ctx, unsigned INT8 *dest, const unsigned INT8 *src, INT32 len)
+{
+  register unsigned INT8 i, j; /* Depends on the eight-bitness of these variables */
+
+  i = ctx->i; j = ctx->j;
+  while(len--)
+    {
+      i++;
+      j += ctx->S[i];
+      SWAP(ctx->S[i], ctx->S[j]);
+      *dest++ = *src++ ^ ctx->S[ (ctx->S[i] + ctx->S[j]) & 0xff ];
+    }
+  ctx->i = i; ctx->j = j;
+}
diff --git a/sha.c b/sha.c
new file mode 100644 (file)
index 0000000..6470da6
--- /dev/null
+++ b/sha.c
@@ -0,0 +1,366 @@
+/* sha.c - Implementation of the Secure Hash Algorithm
+ *
+ * Copyright (C) 1995, A.M. Kuchling
+ *
+ * Distribute and use freely; there are no restrictions on further 
+ * dissemination and usage except those imposed by the laws of your 
+ * country of residence.
+ *
+ * Adapted to pike and some cleanup by Niels Möller.
+ */
+
+/* $Id$ */
+
+/* SHA: NIST's Secure Hash Algorithm */
+
+/* Based on SHA code originally posted to sci.crypt by Peter Gutmann
+   in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
+   Modified to test for endianness on creation of SHA objects by AMK.
+   Also, the original specification of SHA was found to have a weakness
+   by NSA/NIST.  This code implements the fixed version of SHA.
+*/
+
+/* Here's the first paragraph of Peter Gutmann's posting:
+   
+The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
+SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
+what's changed in the new version.  The fix is a simple change which involves
+adding a single rotate in the initial expansion function.  It is unknown
+whether this is an optimal solution to the problem which was discovered in the
+SHA or whether it's simply a bandaid which fixes the problem with a minimum of
+effort (for example the reengineering of a great many Capstone chips).
+*/
+
+#include "crypto_types.h"
+/* #include "port.h" */
+#include "sha.h"
+
+void sha_copy(struct sha_ctx *dest, struct sha_ctx *src)
+{
+  int i;
+
+  dest->count_l=src->count_l;
+  dest->count_h=src->count_h;
+  for(i=0; i<SHA_DIGESTLEN; i++)
+    dest->digest[i]=src->digest[i];
+  for(i=0; i < src->index; i++)
+    dest->block[i] = src->block[i];
+  dest->index = src->index;
+}
+
+
+/* The SHA f()-functions.  The f1 and f3 functions can be optimized to
+   save one boolean operation each - thanks to Rich Schroeppel,
+   rcs@cs.arizona.edu for discovering this */
+
+/*#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) )          // Rounds  0-19 */
+#define f1(x,y,z)   ( z ^ ( x & ( y ^ z ) ) )           /* Rounds  0-19 */
+#define f2(x,y,z)   ( x ^ y ^ z )                       /* Rounds 20-39 */
+/*#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) )   // Rounds 40-59 */
+#define f3(x,y,z)   ( ( x & y ) | ( z & ( x | y ) ) )   /* Rounds 40-59 */
+#define f4(x,y,z)   ( x ^ y ^ z )                       /* Rounds 60-79 */
+
+/* The SHA Mysterious Constants */
+
+#define K1  0x5A827999L                                 /* Rounds  0-19 */
+#define K2  0x6ED9EBA1L                                 /* Rounds 20-39 */
+#define K3  0x8F1BBCDCL                                 /* Rounds 40-59 */
+#define K4  0xCA62C1D6L                                 /* Rounds 60-79 */
+
+/* SHA initial values */
+
+#define h0init  0x67452301L
+#define h1init  0xEFCDAB89L
+#define h2init  0x98BADCFEL
+#define h3init  0x10325476L
+#define h4init  0xC3D2E1F0L
+
+/* 32-bit rotate left - kludged with shifts */
+
+#define ROTL(n,X)  ( ( (X) << (n) ) | ( (X) >> ( 32 - (n) ) ) )
+
+/* The initial expanding function.  The hash function is defined over an
+   80-word expanded input array W, where the first 16 are copies of the input
+   data, and the remaining 64 are defined by
+
+        W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
+
+   This implementation generates these values on the fly in a circular
+   buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
+   optimization.
+
+   The updated SHA changes the expanding function by adding a rotate of 1
+   bit.  Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
+   for this information */
+
+#define expand(W,i) ( W[ i & 15 ] = \
+                     ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
+                                W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
+
+
+/* The prototype SHA sub-round.  The fundamental sub-round is:
+
+        a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
+        b' = a;
+        c' = ROTL( 30, b );
+        d' = c;
+        e' = d;
+
+   but this is implemented by unrolling the loop 5 times and renaming the
+   variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
+   This code is then replicated 20 times for each of the 4 functions, using
+   the next 20 values from the W[] array each time */
+
+#define subRound(a, b, c, d, e, f, k, data) \
+    ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
+
+/* Initialize the SHA values */
+
+void sha_init(struct sha_ctx *ctx)
+{
+  /* Set the h-vars to their initial values */
+  ctx->digest[ 0 ] = h0init;
+  ctx->digest[ 1 ] = h1init;
+  ctx->digest[ 2 ] = h2init;
+  ctx->digest[ 3 ] = h3init;
+  ctx->digest[ 4 ] = h4init;
+
+  /* Initialize bit count */
+  ctx->count_l = ctx->count_h = 0;
+  
+  /* Initialize buffer */
+  ctx->index = 0;
+}
+
+/* Perform the SHA transformation.  Note that this code, like MD5, seems to
+   break some optimizing compilers due to the complexity of the expressions
+   and the size of the basic block.  It may be necessary to split it into
+   sections, e.g. based on the four subrounds
+
+   Note that this function destroys the data area */
+
+static void sha_transform(struct sha_ctx *ctx, unsigned INT32 *data )
+{
+  unsigned INT32 A, B, C, D, E;     /* Local vars */
+
+  /* Set up first buffer and local data buffer */
+  A = ctx->digest[0];
+  B = ctx->digest[1];
+  C = ctx->digest[2];
+  D = ctx->digest[3];
+  E = ctx->digest[4];
+
+  /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
+  subRound( A, B, C, D, E, f1, K1, data[ 0] );
+  subRound( E, A, B, C, D, f1, K1, data[ 1] );
+  subRound( D, E, A, B, C, f1, K1, data[ 2] );
+  subRound( C, D, E, A, B, f1, K1, data[ 3] );
+  subRound( B, C, D, E, A, f1, K1, data[ 4] );
+  subRound( A, B, C, D, E, f1, K1, data[ 5] );
+  subRound( E, A, B, C, D, f1, K1, data[ 6] );
+  subRound( D, E, A, B, C, f1, K1, data[ 7] );
+  subRound( C, D, E, A, B, f1, K1, data[ 8] );
+  subRound( B, C, D, E, A, f1, K1, data[ 9] );
+  subRound( A, B, C, D, E, f1, K1, data[10] );
+  subRound( E, A, B, C, D, f1, K1, data[11] );
+  subRound( D, E, A, B, C, f1, K1, data[12] );
+  subRound( C, D, E, A, B, f1, K1, data[13] );
+  subRound( B, C, D, E, A, f1, K1, data[14] );
+  subRound( A, B, C, D, E, f1, K1, data[15] );
+  subRound( E, A, B, C, D, f1, K1, expand( data, 16 ) );
+  subRound( D, E, A, B, C, f1, K1, expand( data, 17 ) );
+  subRound( C, D, E, A, B, f1, K1, expand( data, 18 ) );
+  subRound( B, C, D, E, A, f1, K1, expand( data, 19 ) );
+
+  subRound( A, B, C, D, E, f2, K2, expand( data, 20 ) );
+  subRound( E, A, B, C, D, f2, K2, expand( data, 21 ) );
+  subRound( D, E, A, B, C, f2, K2, expand( data, 22 ) );
+  subRound( C, D, E, A, B, f2, K2, expand( data, 23 ) );
+  subRound( B, C, D, E, A, f2, K2, expand( data, 24 ) );
+  subRound( A, B, C, D, E, f2, K2, expand( data, 25 ) );
+  subRound( E, A, B, C, D, f2, K2, expand( data, 26 ) );
+  subRound( D, E, A, B, C, f2, K2, expand( data, 27 ) );
+  subRound( C, D, E, A, B, f2, K2, expand( data, 28 ) );
+  subRound( B, C, D, E, A, f2, K2, expand( data, 29 ) );
+  subRound( A, B, C, D, E, f2, K2, expand( data, 30 ) );
+  subRound( E, A, B, C, D, f2, K2, expand( data, 31 ) );
+  subRound( D, E, A, B, C, f2, K2, expand( data, 32 ) );
+  subRound( C, D, E, A, B, f2, K2, expand( data, 33 ) );
+  subRound( B, C, D, E, A, f2, K2, expand( data, 34 ) );
+  subRound( A, B, C, D, E, f2, K2, expand( data, 35 ) );
+  subRound( E, A, B, C, D, f2, K2, expand( data, 36 ) );
+  subRound( D, E, A, B, C, f2, K2, expand( data, 37 ) );
+  subRound( C, D, E, A, B, f2, K2, expand( data, 38 ) );
+  subRound( B, C, D, E, A, f2, K2, expand( data, 39 ) );
+
+  subRound( A, B, C, D, E, f3, K3, expand( data, 40 ) );
+  subRound( E, A, B, C, D, f3, K3, expand( data, 41 ) );
+  subRound( D, E, A, B, C, f3, K3, expand( data, 42 ) );
+  subRound( C, D, E, A, B, f3, K3, expand( data, 43 ) );
+  subRound( B, C, D, E, A, f3, K3, expand( data, 44 ) );
+  subRound( A, B, C, D, E, f3, K3, expand( data, 45 ) );
+  subRound( E, A, B, C, D, f3, K3, expand( data, 46 ) );
+  subRound( D, E, A, B, C, f3, K3, expand( data, 47 ) );
+  subRound( C, D, E, A, B, f3, K3, expand( data, 48 ) );
+  subRound( B, C, D, E, A, f3, K3, expand( data, 49 ) );
+  subRound( A, B, C, D, E, f3, K3, expand( data, 50 ) );
+  subRound( E, A, B, C, D, f3, K3, expand( data, 51 ) );
+  subRound( D, E, A, B, C, f3, K3, expand( data, 52 ) );
+  subRound( C, D, E, A, B, f3, K3, expand( data, 53 ) );
+  subRound( B, C, D, E, A, f3, K3, expand( data, 54 ) );
+  subRound( A, B, C, D, E, f3, K3, expand( data, 55 ) );
+  subRound( E, A, B, C, D, f3, K3, expand( data, 56 ) );
+  subRound( D, E, A, B, C, f3, K3, expand( data, 57 ) );
+  subRound( C, D, E, A, B, f3, K3, expand( data, 58 ) );
+  subRound( B, C, D, E, A, f3, K3, expand( data, 59 ) );
+
+  subRound( A, B, C, D, E, f4, K4, expand( data, 60 ) );
+  subRound( E, A, B, C, D, f4, K4, expand( data, 61 ) );
+  subRound( D, E, A, B, C, f4, K4, expand( data, 62 ) );
+  subRound( C, D, E, A, B, f4, K4, expand( data, 63 ) );
+  subRound( B, C, D, E, A, f4, K4, expand( data, 64 ) );
+  subRound( A, B, C, D, E, f4, K4, expand( data, 65 ) );
+  subRound( E, A, B, C, D, f4, K4, expand( data, 66 ) );
+  subRound( D, E, A, B, C, f4, K4, expand( data, 67 ) );
+  subRound( C, D, E, A, B, f4, K4, expand( data, 68 ) );
+  subRound( B, C, D, E, A, f4, K4, expand( data, 69 ) );
+  subRound( A, B, C, D, E, f4, K4, expand( data, 70 ) );
+  subRound( E, A, B, C, D, f4, K4, expand( data, 71 ) );
+  subRound( D, E, A, B, C, f4, K4, expand( data, 72 ) );
+  subRound( C, D, E, A, B, f4, K4, expand( data, 73 ) );
+  subRound( B, C, D, E, A, f4, K4, expand( data, 74 ) );
+  subRound( A, B, C, D, E, f4, K4, expand( data, 75 ) );
+  subRound( E, A, B, C, D, f4, K4, expand( data, 76 ) );
+  subRound( D, E, A, B, C, f4, K4, expand( data, 77 ) );
+  subRound( C, D, E, A, B, f4, K4, expand( data, 78 ) );
+  subRound( B, C, D, E, A, f4, K4, expand( data, 79 ) );
+
+  /* Build message digest */
+  ctx->digest[0] += A;
+  ctx->digest[1] += B;
+  ctx->digest[2] += C;
+  ctx->digest[3] += D;
+  ctx->digest[4] += E;
+}
+
+#if 1
+
+#ifndef EXTRACT_UCHAR
+#define EXTRACT_UCHAR(p)  (*(unsigned char *)(p))
+#endif
+
+#define STRING2INT(s) ((((((EXTRACT_UCHAR(s) << 8)    \
+                        | EXTRACT_UCHAR(s+1)) << 8)  \
+                        | EXTRACT_UCHAR(s+2)) << 8)  \
+                        | EXTRACT_UCHAR(s+3))
+#else
+unsigned INT32 STRING2INT(unsigned INT8 *s)
+{
+  unsigned INT32 r;
+  int i;
+  
+  for (i = 0, r = 0; i < 4; i++, s++)
+    r = (r << 8) | *s;
+  return r;
+}
+#endif
+
+static void sha_block(struct sha_ctx *ctx, unsigned INT8 *block)
+{
+  unsigned INT32 data[SHA_DATALEN];
+  int i;
+  
+  /* Update block count */
+  if (!++ctx->count_l)
+    ++ctx->count_h;
+
+  /* Endian independent conversion */
+  for (i = 0; i<SHA_DATALEN; i++, block += 4)
+    data[i] = STRING2INT(block);
+
+  sha_transform(ctx, data);
+}
+
+void sha_update(struct sha_ctx *ctx, unsigned INT8 *buffer, unsigned INT32 len)
+{
+  if (ctx->index)
+    { /* Try to fill partial block */
+      unsigned left = SHA_DATASIZE - ctx->index;
+      if (len < left)
+       {
+         memcpy(ctx->block + ctx->index, buffer, len);
+         ctx->index += len;
+         return; /* Finished */
+       }
+      else
+       {
+         memcpy(ctx->block + ctx->index, buffer, left);
+         sha_block(ctx, ctx->block);
+         buffer += left;
+         len -= left;
+       }
+    }
+  while (len >= SHA_DATASIZE)
+    {
+      sha_block(ctx, buffer);
+      buffer += SHA_DATASIZE;
+      len -= SHA_DATASIZE;
+    }
+  if ((ctx->index = len))     /* This assignment is intended */
+    /* Buffer leftovers */
+    memcpy(ctx->block, buffer, len);
+}
+         
+/* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern
+   1 0* (64-bit count of bits processed, MSB-first) */
+
+void sha_final(struct sha_ctx *ctx)
+{
+  unsigned INT32 data[SHA_DATALEN];
+  int i;
+  int words;
+  
+  i = ctx->index;
+  /* Set the first char of padding to 0x80.  This is safe since there is
+     always at least one byte free */
+  ctx->block[i++] = 0x80;
+
+  /* Fill rest of word */
+  for( ; i & 3; i++)
+    ctx->block[i] = 0;
+
+  /* i is now a multiple of the word size 4 */
+  words = i >> 2;
+  for (i = 0; i < words; i++)
+    data[i] = STRING2INT(ctx->block + 4*i);
+  
+  if (words > (SHA_DATALEN-2))
+    { /* No room for length in this block. Process it and
+       * pad with another one */
+      for (i = words ; i < SHA_DATALEN; i++)
+       data[i] = 0;
+      sha_transform(ctx, data);
+      for (i = 0; i < (SHA_DATALEN-2); i++)
+       data[i] = 0;
+    }
+  else
+    for (i = words ; i < SHA_DATALEN - 2; i++)
+      data[i] = 0;
+  /* Theres 512 = 2^9 bits in one block */
+  data[SHA_DATALEN-2] = (ctx->count_h << 9) | (ctx->count_l >> 23);
+  data[SHA_DATALEN-1] = (ctx->count_l << 9) | (ctx->index << 3);
+  sha_transform(ctx, data);
+}
+
+void sha_digest(struct sha_ctx *ctx, INT8 *s)
+{
+  int i;
+
+  for (i = 0; i < SHA_DIGESTLEN; i++)
+    {
+      *s++ =         ctx->digest[i] >> 24;
+      *s++ = 0xff & (ctx->digest[i] >> 16);
+      *s++ = 0xff & (ctx->digest[i] >> 8);
+      *s++ = 0xff &  ctx->digest[i];
+    }
+}