summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes2
-rw-r--r--.gitignore32
-rw-r--r--Makefile.in159
-rw-r--r--cast.c248
-rw-r--r--cast_sboxes.h545
-rwxr-xr-xconfigure.in10
-rw-r--r--desCode.h414
-rw-r--r--desKerb.c31
-rw-r--r--desQuick.c54
-rw-r--r--desTest.c186
-rw-r--r--desUtil.c168
-rw-r--r--descore.README313
-rw-r--r--desdata.c191
-rw-r--r--desinfo.h96
-rw-r--r--idea.c266
-rw-r--r--include/RCSID.h20
-rw-r--r--include/cast.h36
-rw-r--r--include/crypto_types.h17
-rw-r--r--include/des.h41
-rw-r--r--include/idea.h26
-rw-r--r--include/md5.h23
-rw-r--r--include/rc4.h22
-rw-r--r--include/sha.h26
-rwxr-xr-xinstall-sh241
-rw-r--r--md5.c243
-rw-r--r--rc4.c48
-rw-r--r--sha.c366
27 files changed, 3824 insertions, 0 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..a9279440
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+[attr]binary -text -crlf -diff -ident
+* text ident
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..645bd64b
--- /dev/null
+++ b/.gitignore
@@ -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
index 00000000..13441fdd
--- /dev/null
+++ b/Makefile.in
@@ -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
index 00000000..c2e467c0
--- /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
index 00000000..2e061aa7
--- /dev/null
+++ b/cast_sboxes.h
@@ -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
index 00000000..6f9bd700
--- /dev/null
+++ b/configure.in
@@ -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
index 00000000..c38e491f
--- /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
index 00000000..3e32b72f
--- /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
index 00000000..b5220c28
--- /dev/null
+++ b/desQuick.c
@@ -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
index 00000000..10b2aa8e
--- /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
index 00000000..bdf014b1
--- /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
index 00000000..d95d8f07
--- /dev/null
+++ b/descore.README
@@ -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
index 00000000..4089be76
--- /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
index 00000000..8c90ff81
--- /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
index 00000000..59a0a143
--- /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
index 00000000..15ca429a
--- /dev/null
+++ b/include/RCSID.h
@@ -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
index 00000000..65ce86cd
--- /dev/null
+++ b/include/cast.h
@@ -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
index 00000000..9429902a
--- /dev/null
+++ b/include/crypto_types.h
@@ -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
index 00000000..911eaefe
--- /dev/null
+++ b/include/des.h
@@ -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
index 00000000..27cfefae
--- /dev/null
+++ b/include/idea.h
@@ -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
index 00000000..3e7e9f3e
--- /dev/null
+++ b/include/md5.h
@@ -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
index 00000000..57a46a97
--- /dev/null
+++ b/include/rc4.h
@@ -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
index 00000000..96f4d782
--- /dev/null
+++ b/include/sha.h
@@ -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
index 00000000..6bfa7aa9
--- /dev/null
+++ b/install-sh
@@ -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
index 00000000..3620f866
--- /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
index 00000000..0b302341
--- /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
index 00000000..6470da63
--- /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];
+ }
+}