diff options
-rw-r--r-- | .gitattributes | 2 | ||||
-rw-r--r-- | .gitignore | 32 | ||||
-rw-r--r-- | Makefile.in | 159 | ||||
-rw-r--r-- | cast.c | 248 | ||||
-rw-r--r-- | cast_sboxes.h | 545 | ||||
-rwxr-xr-x | configure.in | 10 | ||||
-rw-r--r-- | desCode.h | 414 | ||||
-rw-r--r-- | desKerb.c | 31 | ||||
-rw-r--r-- | desQuick.c | 54 | ||||
-rw-r--r-- | desTest.c | 186 | ||||
-rw-r--r-- | desUtil.c | 168 | ||||
-rw-r--r-- | descore.README | 313 | ||||
-rw-r--r-- | desdata.c | 191 | ||||
-rw-r--r-- | desinfo.h | 96 | ||||
-rw-r--r-- | idea.c | 266 | ||||
-rw-r--r-- | include/RCSID.h | 20 | ||||
-rw-r--r-- | include/cast.h | 36 | ||||
-rw-r--r-- | include/crypto_types.h | 17 | ||||
-rw-r--r-- | include/des.h | 41 | ||||
-rw-r--r-- | include/idea.h | 26 | ||||
-rw-r--r-- | include/md5.h | 23 | ||||
-rw-r--r-- | include/rc4.h | 22 | ||||
-rw-r--r-- | include/sha.h | 26 | ||||
-rwxr-xr-x | install-sh | 241 | ||||
-rw-r--r-- | md5.c | 243 | ||||
-rw-r--r-- | rc4.c | 48 | ||||
-rw-r--r-- | sha.c | 366 |
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 + @@ -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, +}; @@ -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 + @@ -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; + } +} @@ -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; +} @@ -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]; + } +} |