diff options
Diffstat (limited to 'openssl/crypto/rc4')
-rw-r--r-- | openssl/crypto/rc4/Makefile | 125 | ||||
-rw-r--r-- | openssl/crypto/rc4/asm/rc4-586.pl | 230 | ||||
-rw-r--r-- | openssl/crypto/rc4/asm/rc4-ia64.S | 159 | ||||
-rw-r--r-- | openssl/crypto/rc4/asm/rc4-x86_64.pl | 366 | ||||
-rw-r--r-- | openssl/crypto/rc4/rc4.c | 193 | ||||
-rw-r--r-- | openssl/crypto/rc4/rc4.h | 90 | ||||
-rw-r--r-- | openssl/crypto/rc4/rc4_enc.c | 315 | ||||
-rw-r--r-- | openssl/crypto/rc4/rc4_fblk.c | 75 | ||||
-rw-r--r-- | openssl/crypto/rc4/rc4_locl.h | 5 | ||||
-rw-r--r-- | openssl/crypto/rc4/rc4_skey.c | 165 | ||||
-rw-r--r-- | openssl/crypto/rc4/rc4s.cpp | 73 | ||||
-rw-r--r-- | openssl/crypto/rc4/rc4speed.c | 253 | ||||
-rw-r--r-- | openssl/crypto/rc4/rc4test.c | 236 | ||||
-rw-r--r-- | openssl/crypto/rc4/rrc4.doc | 278 |
14 files changed, 2563 insertions, 0 deletions
diff --git a/openssl/crypto/rc4/Makefile b/openssl/crypto/rc4/Makefile new file mode 100644 index 000000000..f0bd7678f --- /dev/null +++ b/openssl/crypto/rc4/Makefile @@ -0,0 +1,125 @@ +# +# OpenSSL/crypto/rc4/Makefile +# + +DIR= rc4 +TOP= ../.. +CC= cc +CPP= $(CC) -E +INCLUDES= +CFLAG=-g +AR= ar r + +RC4_ENC=rc4_enc.o rc4_skey.o + +CFLAGS= $(INCLUDES) $(CFLAG) +ASFLAGS= $(INCLUDES) $(ASFLAG) +AFLAGS= $(ASFLAGS) + +GENERAL=Makefile +TEST=rc4test.c +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC=rc4_skey.c rc4_enc.c rc4_fblk.c +LIBOBJ=$(RC4_ENC) rc4_fblk.o + +SRC= $(LIBSRC) + +EXHEADER= rc4.h +HEADER= $(EXHEADER) rc4_locl.h + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + $(ARX) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) || echo Never mind. + @touch lib + +# ELF +rx86-elf.s: asm/rc4-586.pl ../perlasm/x86asm.pl + (cd asm; $(PERL) rc4-586.pl elf $(CFLAGS) > ../$@) +# COFF +rx86-cof.s: asm/rc4-586.pl ../perlasm/x86asm.pl + (cd asm; $(PERL) rc4-586.pl coff $(CFLAGS) > ../$@) +# a.out +rx86-out.s: asm/rc4-586.pl ../perlasm/x86asm.pl + (cd asm; $(PERL) rc4-586.pl a.out $(CFLAGS) > ../$@) + +rc4-x86_64.s: asm/rc4-x86_64.pl; $(PERL) asm/rc4-x86_64.pl $@ + +rc4-ia64.s: asm/rc4-ia64.S + @case `awk '/^#define RC4_INT/{print$$NF}' $(TOP)/include/openssl/opensslconf.h` in \ + int) set -x; $(CC) $(CFLAGS) -DSZ=4 -E asm/rc4-ia64.S > $@ ;; \ + char) set -x; $(CC) $(CFLAGS) -DSZ=1 -E asm/rc4-ia64.S > $@ ;; \ + *) exit 1 ;; \ + esac + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: + @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile... + @headerlist="$(EXHEADER)"; for i in $$headerlist ; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile... + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +rc4_enc.o: ../../e_os.h ../../include/openssl/bio.h +rc4_enc.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +rc4_enc.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +rc4_enc.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h +rc4_enc.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +rc4_enc.o: ../../include/openssl/rc4.h ../../include/openssl/safestack.h +rc4_enc.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +rc4_enc.o: ../cryptlib.h rc4_enc.c rc4_locl.h +rc4_fblk.o: ../../e_os.h ../../include/openssl/bio.h +rc4_fblk.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +rc4_fblk.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +rc4_fblk.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +rc4_fblk.o: ../../include/openssl/opensslconf.h +rc4_fblk.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +rc4_fblk.o: ../../include/openssl/rc4.h ../../include/openssl/safestack.h +rc4_fblk.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +rc4_fblk.o: ../cryptlib.h rc4_fblk.c rc4_locl.h +rc4_skey.o: ../../e_os.h ../../include/openssl/bio.h +rc4_skey.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +rc4_skey.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h +rc4_skey.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +rc4_skey.o: ../../include/openssl/opensslconf.h +rc4_skey.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +rc4_skey.o: ../../include/openssl/rc4.h ../../include/openssl/safestack.h +rc4_skey.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +rc4_skey.o: ../cryptlib.h rc4_locl.h rc4_skey.c diff --git a/openssl/crypto/rc4/asm/rc4-586.pl b/openssl/crypto/rc4/asm/rc4-586.pl new file mode 100644 index 000000000..ef7eee766 --- /dev/null +++ b/openssl/crypto/rc4/asm/rc4-586.pl @@ -0,0 +1,230 @@ +#!/usr/local/bin/perl + +# At some point it became apparent that the original SSLeay RC4 +# assembler implementation performs suboptimaly on latest IA-32 +# microarchitectures. After re-tuning performance has changed as +# following: +# +# Pentium +0% +# Pentium III +17% +# AMD +52%(*) +# P4 +180%(**) +# +# (*) This number is actually a trade-off:-) It's possible to +# achieve +72%, but at the cost of -48% off PIII performance. +# In other words code performing further 13% faster on AMD +# would perform almost 2 times slower on Intel PIII... +# For reference! This code delivers ~80% of rc4-amd64.pl +# performance on the same Opteron machine. +# (**) This number requires compressed key schedule set up by +# RC4_set_key and therefore doesn't apply to 0.9.7 [option for +# compressed key schedule is implemented in 0.9.8 and later, +# see commentary section in rc4_skey.c for further details]. +# +# <appro@fy.chalmers.se> + +push(@INC,"perlasm","../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"rc4-586.pl"); + +$x="eax"; +$y="ebx"; +$tx="ecx"; +$ty="edx"; +$in="esi"; +$out="edi"; +$d="ebp"; + +&RC4("RC4"); + +&asm_finish(); + +sub RC4_loop + { + local($n,$p,$char)=@_; + + &comment("Round $n"); + + if ($char) + { + if ($p >= 0) + { + &mov($ty, &swtmp(2)); + &cmp($ty, $in); + &jbe(&label("finished")); + &inc($in); + } + else + { + &add($ty, 8); + &inc($in); + &cmp($ty, $in); + &jb(&label("finished")); + &mov(&swtmp(2), $ty); + } + } + # Moved out + # &mov( $tx, &DWP(0,$d,$x,4)) if $p < 0; + + &add( &LB($y), &LB($tx)); + &mov( $ty, &DWP(0,$d,$y,4)); + # XXX + &mov( &DWP(0,$d,$x,4),$ty); + &add( $ty, $tx); + &mov( &DWP(0,$d,$y,4),$tx); + &and( $ty, 0xff); + &inc( &LB($x)); # NEXT ROUND + &mov( $tx, &DWP(0,$d,$x,4)) if $p < 1; # NEXT ROUND + &mov( $ty, &DWP(0,$d,$ty,4)); + + if (!$char) + { + #moved up into last round + if ($p >= 1) + { + &add( $out, 8) + } + &movb( &BP($n,"esp","",0), &LB($ty)); + } + else + { + # Note in+=8 has occured + &movb( &HB($ty), &BP(-1,$in,"",0)); + # XXX + &xorb(&LB($ty), &HB($ty)); + # XXX + &movb(&BP($n,$out,"",0),&LB($ty)); + } + } + + +sub RC4 + { + local($name)=@_; + + &function_begin_B($name,""); + + &mov($ty,&wparam(1)); # len + &cmp($ty,0); + &jne(&label("proceed")); + &ret(); + &set_label("proceed"); + + &comment(""); + + &push("ebp"); + &push("ebx"); + &push("esi"); + &xor( $x, $x); # avoid partial register stalls + &push("edi"); + &xor( $y, $y); # avoid partial register stalls + &mov( $d, &wparam(0)); # key + &mov( $in, &wparam(2)); + + &movb( &LB($x), &BP(0,$d,"",1)); + &movb( &LB($y), &BP(4,$d,"",1)); + + &mov( $out, &wparam(3)); + &inc( &LB($x)); + + &stack_push(3); # 3 temp variables + &add( $d, 8); + + # detect compressed schedule, see commentary section in rc4_skey.c... + # in 0.9.7 context ~50 bytes below RC4_CHAR label remain redundant, + # as compressed key schedule is set up in 0.9.8 and later. + &cmp(&DWP(256,$d),-1); + &je(&label("RC4_CHAR")); + + &lea( $ty, &DWP(-8,$ty,$in)); + + # check for 0 length input + + &mov( &swtmp(2), $ty); # this is now address to exit at + &mov( $tx, &DWP(0,$d,$x,4)); + + &cmp( $ty, $in); + &jb( &label("end")); # less than 8 bytes + + &set_label("start"); + + # filling DELAY SLOT + &add( $in, 8); + + &RC4_loop(0,-1,0); + &RC4_loop(1,0,0); + &RC4_loop(2,0,0); + &RC4_loop(3,0,0); + &RC4_loop(4,0,0); + &RC4_loop(5,0,0); + &RC4_loop(6,0,0); + &RC4_loop(7,1,0); + + &comment("apply the cipher text"); + # xor the cipher data with input + + #&add( $out, 8); #moved up into last round + + &mov( $tx, &swtmp(0)); + &mov( $ty, &DWP(-8,$in,"",0)); + &xor( $tx, $ty); + &mov( $ty, &DWP(-4,$in,"",0)); + &mov( &DWP(-8,$out,"",0), $tx); + &mov( $tx, &swtmp(1)); + &xor( $tx, $ty); + &mov( $ty, &swtmp(2)); # load end ptr; + &mov( &DWP(-4,$out,"",0), $tx); + &mov( $tx, &DWP(0,$d,$x,4)); + &cmp($in, $ty); + &jbe(&label("start")); + + &set_label("end"); + + # There is quite a bit of extra crap in RC4_loop() for this + # first round + &RC4_loop(0,-1,1); + &RC4_loop(1,0,1); + &RC4_loop(2,0,1); + &RC4_loop(3,0,1); + &RC4_loop(4,0,1); + &RC4_loop(5,0,1); + &RC4_loop(6,1,1); + + &jmp(&label("finished")); + + &align(16); + # this is essentially Intel P4 specific codepath, see rc4_skey.c, + # and is engaged in 0.9.8 and later context... + &set_label("RC4_CHAR"); + + &lea ($ty,&DWP(0,$in,$ty)); + &mov (&swtmp(2),$ty); + &movz ($tx,&BP(0,$d,$x)); + + # strangely enough unrolled loop performs over 20% slower... + &set_label("RC4_CHAR_loop"); + &add (&LB($y),&LB($tx)); + &movz ($ty,&BP(0,$d,$y)); + &movb (&BP(0,$d,$y),&LB($tx)); + &movb (&BP(0,$d,$x),&LB($ty)); + &add (&LB($ty),&LB($tx)); + &movz ($ty,&BP(0,$d,$ty)); + &add (&LB($x),1); + &xorb (&LB($ty),&BP(0,$in)); + &lea ($in,&DWP(1,$in)); + &movz ($tx,&BP(0,$d,$x)); + &cmp ($in,&swtmp(2)); + &movb (&BP(0,$out),&LB($ty)); + &lea ($out,&DWP(1,$out)); + &jb (&label("RC4_CHAR_loop")); + + &set_label("finished"); + &dec( $x); + &stack_pop(3); + &movb( &BP(-4,$d,"",0),&LB($y)); + &movb( &BP(-8,$d,"",0),&LB($x)); + + &function_end($name); + } + diff --git a/openssl/crypto/rc4/asm/rc4-ia64.S b/openssl/crypto/rc4/asm/rc4-ia64.S new file mode 100644 index 000000000..8210c47d0 --- /dev/null +++ b/openssl/crypto/rc4/asm/rc4-ia64.S @@ -0,0 +1,159 @@ +// ==================================================================== +// Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL +// project. +// +// Rights for redistribution and usage in source and binary forms are +// granted according to the OpenSSL license. Warranty of any kind is +// disclaimed. +// ==================================================================== + +.ident "rc4-ia64.S, Version 2.0" +.ident "IA-64 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>" + +// What's wrong with compiler generated code? Because of the nature of +// C language, compiler doesn't [dare to] reorder load and stores. But +// being memory-bound, RC4 should benefit from reorder [on in-order- +// execution core such as IA-64]. But what can we reorder? At the very +// least we can safely reorder references to key schedule in respect +// to input and output streams. Secondly, from the first [close] glance +// it appeared that it's possible to pull up some references to +// elements of the key schedule itself. Original rationale ["prior +// loads are not safe only for "degenerated" key schedule, when some +// elements equal to the same value"] was kind of sloppy. I should have +// formulated as it really was: if we assume that pulling up reference +// to key[x+1] is not safe, then it would mean that key schedule would +// "degenerate," which is never the case. The problem is that this +// holds true in respect to references to key[x], but not to key[y]. +// Legitimate "collisions" do occur within every 256^2 bytes window. +// Fortunately there're enough free instruction slots to keep prior +// reference to key[x+1], detect "collision" and compensate for it. +// All this without sacrificing a single clock cycle:-) Throughput is +// ~210MBps on 900MHz CPU, which is is >3x faster than gcc generated +// code and +30% - if compared to HP-UX C. Unrolling loop below should +// give >30% on top of that... + +.text +.explicit + +#if defined(_HPUX_SOURCE) && !defined(_LP64) +# define ADDP addp4 +#else +# define ADDP add +#endif + +#ifndef SZ +#define SZ 4 // this is set to sizeof(RC4_INT) +#endif +// SZ==4 seems to be optimal. At least SZ==8 is not any faster, not for +// assembler implementation, while SZ==1 code is ~30% slower. +#if SZ==1 // RC4_INT is unsigned char +# define LDKEY ld1 +# define STKEY st1 +# define OFF 0 +#elif SZ==4 // RC4_INT is unsigned int +# define LDKEY ld4 +# define STKEY st4 +# define OFF 2 +#elif SZ==8 // RC4_INT is unsigned long +# define LDKEY ld8 +# define STKEY st8 +# define OFF 3 +#endif + +out=r8; // [expanded] output pointer +inp=r9; // [expanded] output pointer +prsave=r10; +key=r28; // [expanded] pointer to RC4_KEY +ksch=r29; // (key->data+255)[&~(sizeof(key->data)-1)] +xx=r30; +yy=r31; + +// void RC4(RC4_KEY *key,size_t len,const void *inp,void *out); +.global RC4# +.proc RC4# +.align 32 +.skip 16 +RC4: + .prologue + .save ar.pfs,r2 +{ .mii; alloc r2=ar.pfs,4,12,0,16 + .save pr,prsave + mov prsave=pr + ADDP key=0,in0 };; +{ .mib; cmp.eq p6,p0=0,in1 // len==0? + .save ar.lc,r3 + mov r3=ar.lc +(p6) br.ret.spnt.many b0 };; // emergency exit + + .body + .rotr dat[4],key_x[4],tx[2],rnd[2],key_y[2],ty[1]; + +{ .mib; LDKEY xx=[key],SZ // load key->x + add in1=-1,in1 // adjust len for loop counter + nop.b 0 } +{ .mib; ADDP inp=0,in2 + ADDP out=0,in3 + brp.loop.imp .Ltop,.Lexit-16 };; +{ .mmi; LDKEY yy=[key] // load key->y + add ksch=SZ,key + mov ar.lc=in1 } +{ .mmi; mov key_y[1]=r0 // guarantee inequality + // in first iteration + add xx=1,xx + mov pr.rot=1<<16 };; +{ .mii; nop.m 0 + dep key_x[1]=xx,r0,OFF,8 + mov ar.ec=3 };; // note that epilogue counter + // is off by 1. I compensate + // for this at exit... +.Ltop: +// The loop is scheduled for 4*(n+2) spin-rate on Itanium 2, which +// theoretically gives asymptotic performance of clock frequency +// divided by 4 bytes per seconds, or 400MBps on 1.6GHz CPU. This is +// for sizeof(RC4_INT)==4. For smaller RC4_INT STKEY inadvertently +// splits the last bundle and you end up with 5*n spin-rate:-( +// Originally the loop was scheduled for 3*n and relied on key +// schedule to be aligned at 256*sizeof(RC4_INT) boundary. But +// *(out++)=dat, which maps to st1, had same effect [inadvertent +// bundle split] and holded the loop back. Rescheduling for 4*n +// made it possible to eliminate dependence on specific alignment +// and allow OpenSSH keep "abusing" our API. Reaching for 3*n would +// require unrolling, sticking to variable shift instruction for +// collecting output [to avoid starvation for integer shifter] and +// copying of key schedule to controlled place in stack [so that +// deposit instruction can serve as substitute for whole +// key->data+((x&255)<<log2(sizeof(key->data[0])))]... +{ .mmi; (p19) st1 [out]=dat[3],1 // *(out++)=dat + (p16) add xx=1,xx // x++ + (p18) dep rnd[1]=rnd[1],r0,OFF,8 } // ((tx+ty)&255)<<OFF +{ .mmi; (p16) add key_x[1]=ksch,key_x[1] // &key[xx&255] + (p17) add key_y[1]=ksch,key_y[1] };; // &key[yy&255] +{ .mmi; (p16) LDKEY tx[0]=[key_x[1]] // tx=key[xx] + (p17) LDKEY ty[0]=[key_y[1]] // ty=key[yy] + (p16) dep key_x[0]=xx,r0,OFF,8 } // (xx&255)<<OFF +{ .mmi; (p18) add rnd[1]=ksch,rnd[1] // &key[(tx+ty)&255] + (p16) cmp.ne.unc p20,p21=key_x[1],key_y[1] };; +{ .mmi; (p18) LDKEY rnd[1]=[rnd[1]] // rnd=key[(tx+ty)&255] + (p16) ld1 dat[0]=[inp],1 } // dat=*(inp++) +.pred.rel "mutex",p20,p21 +{ .mmi; (p21) add yy=yy,tx[1] // (p16) + (p20) add yy=yy,tx[0] // (p16) y+=tx + (p21) mov tx[0]=tx[1] };; // (p16) +{ .mmi; (p17) STKEY [key_y[1]]=tx[1] // key[yy]=tx + (p17) STKEY [key_x[2]]=ty[0] // key[xx]=ty + (p16) dep key_y[0]=yy,r0,OFF,8 } // &key[yy&255] +{ .mmb; (p17) add rnd[0]=tx[1],ty[0] // tx+=ty + (p18) xor dat[2]=dat[2],rnd[1] // dat^=rnd + br.ctop.sptk .Ltop };; +.Lexit: +{ .mib; STKEY [key]=yy,-SZ // save key->y + mov pr=prsave,0x1ffff + nop.b 0 } +{ .mib; st1 [out]=dat[3],1 // compensate for truncated + // epilogue counter + add xx=-1,xx + nop.b 0 };; +{ .mib; STKEY [key]=xx // save key->x + mov ar.lc=r3 + br.ret.sptk.many b0 };; +.endp RC4# diff --git a/openssl/crypto/rc4/asm/rc4-x86_64.pl b/openssl/crypto/rc4/asm/rc4-x86_64.pl new file mode 100644 index 000000000..00c6fa28a --- /dev/null +++ b/openssl/crypto/rc4/asm/rc4-x86_64.pl @@ -0,0 +1,366 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# 2.22x RC4 tune-up:-) It should be noted though that my hand [as in +# "hand-coded assembler"] doesn't stand for the whole improvement +# coefficient. It turned out that eliminating RC4_CHAR from config +# line results in ~40% improvement (yes, even for C implementation). +# Presumably it has everything to do with AMD cache architecture and +# RAW or whatever penalties. Once again! The module *requires* config +# line *without* RC4_CHAR! As for coding "secret," I bet on partial +# register arithmetics. For example instead of 'inc %r8; and $255,%r8' +# I simply 'inc %r8b'. Even though optimization manual discourages +# to operate on partial registers, it turned out to be the best bet. +# At least for AMD... How IA32E would perform remains to be seen... + +# As was shown by Marc Bevand reordering of couple of load operations +# results in even higher performance gain of 3.3x:-) At least on +# Opteron... For reference, 1x in this case is RC4_CHAR C-code +# compiled with gcc 3.3.2, which performs at ~54MBps per 1GHz clock. +# Latter means that if you want to *estimate* what to expect from +# *your* Opteron, then multiply 54 by 3.3 and clock frequency in GHz. + +# Intel P4 EM64T core was found to run the AMD64 code really slow... +# The only way to achieve comparable performance on P4 was to keep +# RC4_CHAR. Kind of ironic, huh? As it's apparently impossible to +# compose blended code, which would perform even within 30% marginal +# on either AMD and Intel platforms, I implement both cases. See +# rc4_skey.c for further details... + +# P4 EM64T core appears to be "allergic" to 64-bit inc/dec. Replacing +# those with add/sub results in 50% performance improvement of folded +# loop... + +# As was shown by Zou Nanhai loop unrolling can improve Intel EM64T +# performance by >30% [unlike P4 32-bit case that is]. But this is +# provided that loads are reordered even more aggressively! Both code +# pathes, AMD64 and EM64T, reorder loads in essentially same manner +# as my IA-64 implementation. On Opteron this resulted in modest 5% +# improvement [I had to test it], while final Intel P4 performance +# achieves respectful 432MBps on 2.8GHz processor now. For reference. +# If executed on Xeon, current RC4_CHAR code-path is 2.7x faster than +# RC4_INT code-path. While if executed on Opteron, it's only 25% +# slower than the RC4_INT one [meaning that if CPU µ-arch detection +# is not implemented, then this final RC4_CHAR code-path should be +# preferred, as it provides better *all-round* performance]. + +# Intel Core2 was observed to perform poorly on both code paths:-( It +# apparently suffers from some kind of partial register stall, which +# occurs in 64-bit mode only [as virtually identical 32-bit loop was +# observed to outperform 64-bit one by almost 50%]. Adding two movzb to +# cloop1 boosts its performance by 80%! This loop appears to be optimal +# fit for Core2 and therefore the code was modified to skip cloop8 on +# this CPU. + +$output=shift; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open STDOUT,"| $^X $xlate $output"; + +$dat="%rdi"; # arg1 +$len="%rsi"; # arg2 +$inp="%rdx"; # arg3 +$out="%rcx"; # arg4 + +@XX=("%r8","%r10"); +@TX=("%r9","%r11"); +$YY="%r12"; +$TY="%r13"; + +$code=<<___; +.text + +.globl RC4 +.type RC4,\@function,4 +.align 16 +RC4: or $len,$len + jne .Lentry + ret +.Lentry: + push %r12 + push %r13 + + add \$8,$dat + movl -8($dat),$XX[0]#d + movl -4($dat),$YY#d + cmpl \$-1,256($dat) + je .LRC4_CHAR + inc $XX[0]#b + movl ($dat,$XX[0],4),$TX[0]#d + test \$-8,$len + jz .Lloop1 + jmp .Lloop8 +.align 16 +.Lloop8: +___ +for ($i=0;$i<8;$i++) { +$code.=<<___; + add $TX[0]#b,$YY#b + mov $XX[0],$XX[1] + movl ($dat,$YY,4),$TY#d + ror \$8,%rax # ror is redundant when $i=0 + inc $XX[1]#b + movl ($dat,$XX[1],4),$TX[1]#d + cmp $XX[1],$YY + movl $TX[0]#d,($dat,$YY,4) + cmove $TX[0],$TX[1] + movl $TY#d,($dat,$XX[0],4) + add $TX[0]#b,$TY#b + movb ($dat,$TY,4),%al +___ +push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers +} +$code.=<<___; + ror \$8,%rax + sub \$8,$len + + xor ($inp),%rax + add \$8,$inp + mov %rax,($out) + add \$8,$out + + test \$-8,$len + jnz .Lloop8 + cmp \$0,$len + jne .Lloop1 +___ +$code.=<<___; +.Lexit: + sub \$1,$XX[0]#b + movl $XX[0]#d,-8($dat) + movl $YY#d,-4($dat) + + pop %r13 + pop %r12 + ret +.align 16 +.Lloop1: + add $TX[0]#b,$YY#b + movl ($dat,$YY,4),$TY#d + movl $TX[0]#d,($dat,$YY,4) + movl $TY#d,($dat,$XX[0],4) + add $TY#b,$TX[0]#b + inc $XX[0]#b + movl ($dat,$TX[0],4),$TY#d + movl ($dat,$XX[0],4),$TX[0]#d + xorb ($inp),$TY#b + inc $inp + movb $TY#b,($out) + inc $out + dec $len + jnz .Lloop1 + jmp .Lexit + +.align 16 +.LRC4_CHAR: + add \$1,$XX[0]#b + movzb ($dat,$XX[0]),$TX[0]#d + test \$-8,$len + jz .Lcloop1 + cmp \$0,260($dat) + jnz .Lcloop1 + push %rbx + jmp .Lcloop8 +.align 16 +.Lcloop8: + mov ($inp),%eax + mov 4($inp),%ebx +___ +# unroll 2x4-wise, because 64-bit rotates kill Intel P4... +for ($i=0;$i<4;$i++) { +$code.=<<___; + add $TX[0]#b,$YY#b + lea 1($XX[0]),$XX[1] + movzb ($dat,$YY),$TY#d + movzb $XX[1]#b,$XX[1]#d + movzb ($dat,$XX[1]),$TX[1]#d + movb $TX[0]#b,($dat,$YY) + cmp $XX[1],$YY + movb $TY#b,($dat,$XX[0]) + jne .Lcmov$i # Intel cmov is sloooow... + mov $TX[0],$TX[1] +.Lcmov$i: + add $TX[0]#b,$TY#b + xor ($dat,$TY),%al + ror \$8,%eax +___ +push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers +} +for ($i=4;$i<8;$i++) { +$code.=<<___; + add $TX[0]#b,$YY#b + lea 1($XX[0]),$XX[1] + movzb ($dat,$YY),$TY#d + movzb $XX[1]#b,$XX[1]#d + movzb ($dat,$XX[1]),$TX[1]#d + movb $TX[0]#b,($dat,$YY) + cmp $XX[1],$YY + movb $TY#b,($dat,$XX[0]) + jne .Lcmov$i # Intel cmov is sloooow... + mov $TX[0],$TX[1] +.Lcmov$i: + add $TX[0]#b,$TY#b + xor ($dat,$TY),%bl + ror \$8,%ebx +___ +push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers +} +$code.=<<___; + lea -8($len),$len + mov %eax,($out) + lea 8($inp),$inp + mov %ebx,4($out) + lea 8($out),$out + + test \$-8,$len + jnz .Lcloop8 + pop %rbx + cmp \$0,$len + jne .Lcloop1 + jmp .Lexit +___ +$code.=<<___; +.align 16 +.Lcloop1: + add $TX[0]#b,$YY#b + movzb ($dat,$YY),$TY#d + movb $TX[0]#b,($dat,$YY) + movb $TY#b,($dat,$XX[0]) + add $TX[0]#b,$TY#b + add \$1,$XX[0]#b + movzb $TY#b,$TY#d + movzb $XX[0]#b,$XX[0]#d + movzb ($dat,$TY),$TY#d + movzb ($dat,$XX[0]),$TX[0]#d + xorb ($inp),$TY#b + lea 1($inp),$inp + movb $TY#b,($out) + lea 1($out),$out + sub \$1,$len + jnz .Lcloop1 + jmp .Lexit +.size RC4,.-RC4 +___ + +$idx="%r8"; +$ido="%r9"; + +$code.=<<___; +.extern OPENSSL_ia32cap_P +.globl RC4_set_key +.type RC4_set_key,\@function,3 +.align 16 +RC4_set_key: + lea 8($dat),$dat + lea ($inp,$len),$inp + neg $len + mov $len,%rcx + xor %eax,%eax + xor $ido,$ido + xor %r10,%r10 + xor %r11,%r11 + + mov OPENSSL_ia32cap_P(%rip),$idx#d + bt \$20,$idx#d + jnc .Lw1stloop + bt \$30,$idx#d + setc $ido#b + mov $ido#d,260($dat) + jmp .Lc1stloop + +.align 16 +.Lw1stloop: + mov %eax,($dat,%rax,4) + add \$1,%al + jnc .Lw1stloop + + xor $ido,$ido + xor $idx,$idx +.align 16 +.Lw2ndloop: + mov ($dat,$ido,4),%r10d + add ($inp,$len,1),$idx#b + add %r10b,$idx#b + add \$1,$len + mov ($dat,$idx,4),%r11d + cmovz %rcx,$len + mov %r10d,($dat,$idx,4) + mov %r11d,($dat,$ido,4) + add \$1,$ido#b + jnc .Lw2ndloop + jmp .Lexit_key + +.align 16 +.Lc1stloop: + mov %al,($dat,%rax) + add \$1,%al + jnc .Lc1stloop + + xor $ido,$ido + xor $idx,$idx +.align 16 +.Lc2ndloop: + mov ($dat,$ido),%r10b + add ($inp,$len),$idx#b + add %r10b,$idx#b + add \$1,$len + mov ($dat,$idx),%r11b + jnz .Lcnowrap + mov %rcx,$len +.Lcnowrap: + mov %r10b,($dat,$idx) + mov %r11b,($dat,$ido) + add \$1,$ido#b + jnc .Lc2ndloop + movl \$-1,256($dat) + +.align 16 +.Lexit_key: + xor %eax,%eax + mov %eax,-8($dat) + mov %eax,-4($dat) + ret +.size RC4_set_key,.-RC4_set_key + +.globl RC4_options +.type RC4_options,\@function,0 +.align 16 +RC4_options: + .picmeup %rax + lea .Lopts-.(%rax),%rax + mov OPENSSL_ia32cap_P(%rip),%edx + bt \$20,%edx + jnc .Ldone + add \$12,%rax + bt \$30,%edx + jnc .Ldone + add \$13,%rax +.Ldone: + ret +.align 64 +.Lopts: +.asciz "rc4(8x,int)" +.asciz "rc4(8x,char)" +.asciz "rc4(1x,char)" +.asciz "RC4 for x86_64, CRYPTOGAMS by <appro\@openssl.org>" +.align 64 +.size RC4_options,.-RC4_options +___ + +$code =~ s/#([bwd])/$1/gm; + +$code =~ s/RC4_set_key/private_RC4_set_key/g if ($ENV{FIPSCANLIB} ne ""); + +print $code; + +close STDOUT; diff --git a/openssl/crypto/rc4/rc4.c b/openssl/crypto/rc4/rc4.c new file mode 100644 index 000000000..c900b2605 --- /dev/null +++ b/openssl/crypto/rc4/rc4.c @@ -0,0 +1,193 @@ +/* crypto/rc4/rc4.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <openssl/rc4.h> +#include <openssl/evp.h> + +char *usage[]={ +"usage: rc4 args\n", +"\n", +" -in arg - input file - default stdin\n", +" -out arg - output file - default stdout\n", +" -key key - password\n", +NULL +}; + +int main(int argc, char *argv[]) + { + FILE *in=NULL,*out=NULL; + char *infile=NULL,*outfile=NULL,*keystr=NULL; + RC4_KEY key; + char buf[BUFSIZ]; + int badops=0,i; + char **pp; + unsigned char md[MD5_DIGEST_LENGTH]; + + argc--; + argv++; + while (argc >= 1) + { + if (strcmp(*argv,"-in") == 0) + { + if (--argc < 1) goto bad; + infile= *(++argv); + } + else if (strcmp(*argv,"-out") == 0) + { + if (--argc < 1) goto bad; + outfile= *(++argv); + } + else if (strcmp(*argv,"-key") == 0) + { + if (--argc < 1) goto bad; + keystr= *(++argv); + } + else + { + fprintf(stderr,"unknown option %s\n",*argv); + badops=1; + break; + } + argc--; + argv++; + } + + if (badops) + { +bad: + for (pp=usage; (*pp != NULL); pp++) + fprintf(stderr,"%s",*pp); + exit(1); + } + + if (infile == NULL) + in=stdin; + else + { + in=fopen(infile,"r"); + if (in == NULL) + { + perror("open"); + exit(1); + } + + } + if (outfile == NULL) + out=stdout; + else + { + out=fopen(outfile,"w"); + if (out == NULL) + { + perror("open"); + exit(1); + } + } + +#ifdef OPENSSL_SYS_MSDOS + /* This should set the file to binary mode. */ + { +#include <fcntl.h> + setmode(fileno(in),O_BINARY); + setmode(fileno(out),O_BINARY); + } +#endif + + if (keystr == NULL) + { /* get key */ + i=EVP_read_pw_string(buf,BUFSIZ,"Enter RC4 password:",0); + if (i != 0) + { + OPENSSL_cleanse(buf,BUFSIZ); + fprintf(stderr,"bad password read\n"); + exit(1); + } + keystr=buf; + } + + EVP_Digest((unsigned char *)keystr,strlen(keystr),md,NULL,EVP_md5(),NULL); + OPENSSL_cleanse(keystr,strlen(keystr)); + RC4_set_key(&key,MD5_DIGEST_LENGTH,md); + + for(;;) + { + i=fread(buf,1,BUFSIZ,in); + if (i == 0) break; + if (i < 0) + { + perror("read"); + exit(1); + } + RC4(&key,(unsigned int)i,(unsigned char *)buf, + (unsigned char *)buf); + i=fwrite(buf,(unsigned int)i,1,out); + if (i != 1) + { + perror("write"); + exit(1); + } + } + fclose(out); + fclose(in); + exit(0); + return(1); + } + diff --git a/openssl/crypto/rc4/rc4.h b/openssl/crypto/rc4/rc4.h new file mode 100644 index 000000000..2d8620d33 --- /dev/null +++ b/openssl/crypto/rc4/rc4.h @@ -0,0 +1,90 @@ +/* crypto/rc4/rc4.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RC4_H +#define HEADER_RC4_H + +#include <openssl/opensslconf.h> /* OPENSSL_NO_RC4, RC4_INT */ +#ifdef OPENSSL_NO_RC4 +#error RC4 is disabled. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc4_key_st + { + RC4_INT x,y; + RC4_INT data[256]; + } RC4_KEY; + + +const char *RC4_options(void); +#ifdef OPENSSL_FIPS +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +#endif +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata, + unsigned char *outdata); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openssl/crypto/rc4/rc4_enc.c b/openssl/crypto/rc4/rc4_enc.c new file mode 100644 index 000000000..0660ea60a --- /dev/null +++ b/openssl/crypto/rc4/rc4_enc.c @@ -0,0 +1,315 @@ +/* crypto/rc4/rc4_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <openssl/rc4.h> +#include "rc4_locl.h" + +/* RC4 as implemented from a posting from + * Newsgroups: sci.crypt + * From: sterndark@netcom.com (David Sterndark) + * Subject: RC4 Algorithm revealed. + * Message-ID: <sternCvKL4B.Hyy@netcom.com> + * Date: Wed, 14 Sep 1994 06:35:31 GMT + */ + +void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata, + unsigned char *outdata) + { + register RC4_INT *d; + register RC4_INT x,y,tx,ty; + int i; + + x=key->x; + y=key->y; + d=key->data; + +#if defined(RC4_CHUNK) + /* + * The original reason for implementing this(*) was the fact that + * pre-21164a Alpha CPUs don't have byte load/store instructions + * and e.g. a byte store has to be done with 64-bit load, shift, + * and, or and finally 64-bit store. Peaking data and operating + * at natural word size made it possible to reduce amount of + * instructions as well as to perform early read-ahead without + * suffering from RAW (read-after-write) hazard. This resulted + * in ~40%(**) performance improvement on 21064 box with gcc. + * But it's not only Alpha users who win here:-) Thanks to the + * early-n-wide read-ahead this implementation also exhibits + * >40% speed-up on SPARC and 20-30% on 64-bit MIPS (depending + * on sizeof(RC4_INT)). + * + * (*) "this" means code which recognizes the case when input + * and output pointers appear to be aligned at natural CPU + * word boundary + * (**) i.e. according to 'apps/openssl speed rc4' benchmark, + * crypto/rc4/rc4speed.c exhibits almost 70% speed-up... + * + * Cavets. + * + * - RC4_CHUNK="unsigned long long" should be a #1 choice for + * UltraSPARC. Unfortunately gcc generates very slow code + * (2.5-3 times slower than one generated by Sun's WorkShop + * C) and therefore gcc (at least 2.95 and earlier) should + * always be told that RC4_CHUNK="unsigned long". + * + * <appro@fy.chalmers.se> + */ + +# define RC4_STEP ( \ + x=(x+1) &0xff, \ + tx=d[x], \ + y=(tx+y)&0xff, \ + ty=d[y], \ + d[y]=tx, \ + d[x]=ty, \ + (RC4_CHUNK)d[(tx+ty)&0xff]\ + ) + + if ( ( ((unsigned long)indata & (sizeof(RC4_CHUNK)-1)) | + ((unsigned long)outdata & (sizeof(RC4_CHUNK)-1)) ) == 0 ) + { + RC4_CHUNK ichunk,otp; + const union { long one; char little; } is_endian = {1}; + + /* + * I reckon we can afford to implement both endian + * cases and to decide which way to take at run-time + * because the machine code appears to be very compact + * and redundant 1-2KB is perfectly tolerable (i.e. + * in case the compiler fails to eliminate it:-). By + * suggestion from Terrel Larson <terr@terralogic.net> + * who also stands for the is_endian union:-) + * + * Special notes. + * + * - is_endian is declared automatic as doing otherwise + * (declaring static) prevents gcc from eliminating + * the redundant code; + * - compilers (those I've tried) don't seem to have + * problems eliminating either the operators guarded + * by "if (sizeof(RC4_CHUNK)==8)" or the condition + * expressions themselves so I've got 'em to replace + * corresponding #ifdefs from the previous version; + * - I chose to let the redundant switch cases when + * sizeof(RC4_CHUNK)!=8 be (were also #ifdefed + * before); + * - in case you wonder "&(sizeof(RC4_CHUNK)*8-1)" in + * [LB]ESHFT guards against "shift is out of range" + * warnings when sizeof(RC4_CHUNK)!=8 + * + * <appro@fy.chalmers.se> + */ + if (!is_endian.little) + { /* BIG-ENDIAN CASE */ +# define BESHFT(c) (((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1)) + for (;len&~(sizeof(RC4_CHUNK)-1);len-=sizeof(RC4_CHUNK)) + { + ichunk = *(RC4_CHUNK *)indata; + otp = RC4_STEP<<BESHFT(0); + otp |= RC4_STEP<<BESHFT(1); + otp |= RC4_STEP<<BESHFT(2); + otp |= RC4_STEP<<BESHFT(3); + if (sizeof(RC4_CHUNK)==8) + { + otp |= RC4_STEP<<BESHFT(4); + otp |= RC4_STEP<<BESHFT(5); + otp |= RC4_STEP<<BESHFT(6); + otp |= RC4_STEP<<BESHFT(7); + } + *(RC4_CHUNK *)outdata = otp^ichunk; + indata += sizeof(RC4_CHUNK); + outdata += sizeof(RC4_CHUNK); + } + if (len) + { + RC4_CHUNK mask=(RC4_CHUNK)-1, ochunk; + + ichunk = *(RC4_CHUNK *)indata; + ochunk = *(RC4_CHUNK *)outdata; + otp = 0; + i = BESHFT(0); + mask <<= (sizeof(RC4_CHUNK)-len)<<3; + switch (len&(sizeof(RC4_CHUNK)-1)) + { + case 7: otp = RC4_STEP<<i, i-=8; + case 6: otp |= RC4_STEP<<i, i-=8; + case 5: otp |= RC4_STEP<<i, i-=8; + case 4: otp |= RC4_STEP<<i, i-=8; + case 3: otp |= RC4_STEP<<i, i-=8; + case 2: otp |= RC4_STEP<<i, i-=8; + case 1: otp |= RC4_STEP<<i, i-=8; + case 0: ; /* + * it's never the case, + * but it has to be here + * for ultrix? + */ + } + ochunk &= ~mask; + ochunk |= (otp^ichunk) & mask; + *(RC4_CHUNK *)outdata = ochunk; + } + key->x=x; + key->y=y; + return; + } + else + { /* LITTLE-ENDIAN CASE */ +# define LESHFT(c) (((c)*8)&(sizeof(RC4_CHUNK)*8-1)) + for (;len&~(sizeof(RC4_CHUNK)-1);len-=sizeof(RC4_CHUNK)) + { + ichunk = *(RC4_CHUNK *)indata; + otp = RC4_STEP; + otp |= RC4_STEP<<8; + otp |= RC4_STEP<<16; + otp |= RC4_STEP<<24; + if (sizeof(RC4_CHUNK)==8) + { + otp |= RC4_STEP<<LESHFT(4); + otp |= RC4_STEP<<LESHFT(5); + otp |= RC4_STEP<<LESHFT(6); + otp |= RC4_STEP<<LESHFT(7); + } + *(RC4_CHUNK *)outdata = otp^ichunk; + indata += sizeof(RC4_CHUNK); + outdata += sizeof(RC4_CHUNK); + } + if (len) + { + RC4_CHUNK mask=(RC4_CHUNK)-1, ochunk; + + ichunk = *(RC4_CHUNK *)indata; + ochunk = *(RC4_CHUNK *)outdata; + otp = 0; + i = 0; + mask >>= (sizeof(RC4_CHUNK)-len)<<3; + switch (len&(sizeof(RC4_CHUNK)-1)) + { + case 7: otp = RC4_STEP, i+=8; + case 6: otp |= RC4_STEP<<i, i+=8; + case 5: otp |= RC4_STEP<<i, i+=8; + case 4: otp |= RC4_STEP<<i, i+=8; + case 3: otp |= RC4_STEP<<i, i+=8; + case 2: otp |= RC4_STEP<<i, i+=8; + case 1: otp |= RC4_STEP<<i, i+=8; + case 0: ; /* + * it's never the case, + * but it has to be here + * for ultrix? + */ + } + ochunk &= ~mask; + ochunk |= (otp^ichunk) & mask; + *(RC4_CHUNK *)outdata = ochunk; + } + key->x=x; + key->y=y; + return; + } + } +#endif +#define LOOP(in,out) \ + x=((x+1)&0xff); \ + tx=d[x]; \ + y=(tx+y)&0xff; \ + d[x]=ty=d[y]; \ + d[y]=tx; \ + (out) = d[(tx+ty)&0xff]^ (in); + +#ifndef RC4_INDEX +#define RC4_LOOP(a,b,i) LOOP(*((a)++),*((b)++)) +#else +#define RC4_LOOP(a,b,i) LOOP(a[i],b[i]) +#endif + + i=(int)(len>>3L); + if (i) + { + for (;;) + { + RC4_LOOP(indata,outdata,0); + RC4_LOOP(indata,outdata,1); + RC4_LOOP(indata,outdata,2); + RC4_LOOP(indata,outdata,3); + RC4_LOOP(indata,outdata,4); + RC4_LOOP(indata,outdata,5); + RC4_LOOP(indata,outdata,6); + RC4_LOOP(indata,outdata,7); +#ifdef RC4_INDEX + indata+=8; + outdata+=8; +#endif + if (--i == 0) break; + } + } + i=(int)len&0x07; + if (i) + { + for (;;) + { + RC4_LOOP(indata,outdata,0); if (--i == 0) break; + RC4_LOOP(indata,outdata,1); if (--i == 0) break; + RC4_LOOP(indata,outdata,2); if (--i == 0) break; + RC4_LOOP(indata,outdata,3); if (--i == 0) break; + RC4_LOOP(indata,outdata,4); if (--i == 0) break; + RC4_LOOP(indata,outdata,5); if (--i == 0) break; + RC4_LOOP(indata,outdata,6); if (--i == 0) break; + } + } + key->x=x; + key->y=y; + } diff --git a/openssl/crypto/rc4/rc4_fblk.c b/openssl/crypto/rc4/rc4_fblk.c new file mode 100644 index 000000000..1b2a42979 --- /dev/null +++ b/openssl/crypto/rc4/rc4_fblk.c @@ -0,0 +1,75 @@ +/* crypto/rc4/rc4_fblk.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + + +#include <openssl/rc4.h> +#include "rc4_locl.h" +#include <openssl/opensslv.h> +#include <openssl/crypto.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif + +/* FIPS mode blocking for RC4 has to be done separately since RC4_set_key + * may be implemented in an assembly language file. + */ + +#ifdef OPENSSL_FIPS +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) + { + if (FIPS_mode()) + FIPS_BAD_ABORT(RC4) + private_RC4_set_key(key, len, data); + } +#endif + diff --git a/openssl/crypto/rc4/rc4_locl.h b/openssl/crypto/rc4/rc4_locl.h new file mode 100644 index 000000000..c712e1632 --- /dev/null +++ b/openssl/crypto/rc4/rc4_locl.h @@ -0,0 +1,5 @@ +#ifndef HEADER_RC4_LOCL_H +#define HEADER_RC4_LOCL_H +#include <openssl/opensslconf.h> +#include <cryptlib.h> +#endif diff --git a/openssl/crypto/rc4/rc4_skey.c b/openssl/crypto/rc4/rc4_skey.c new file mode 100644 index 000000000..4478d1a4b --- /dev/null +++ b/openssl/crypto/rc4/rc4_skey.c @@ -0,0 +1,165 @@ +/* crypto/rc4/rc4_skey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <openssl/rc4.h> +#include "rc4_locl.h" +#include <openssl/opensslv.h> +#include <openssl/crypto.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#endif + + +const char RC4_version[]="RC4" OPENSSL_VERSION_PTEXT; + +const char *RC4_options(void) + { +#ifdef RC4_INDEX + if (sizeof(RC4_INT) == 1) + return("rc4(idx,char)"); + else + return("rc4(idx,int)"); +#else + if (sizeof(RC4_INT) == 1) + return("rc4(ptr,char)"); + else + return("rc4(ptr,int)"); +#endif + } + +/* RC4 as implemented from a posting from + * Newsgroups: sci.crypt + * From: sterndark@netcom.com (David Sterndark) + * Subject: RC4 Algorithm revealed. + * Message-ID: <sternCvKL4B.Hyy@netcom.com> + * Date: Wed, 14 Sep 1994 06:35:31 GMT + */ + +#ifdef OPENSSL_FIPS +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) +#else +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) +#endif + { + register RC4_INT tmp; + register int id1,id2; + register RC4_INT *d; + unsigned int i; + + d= &(key->data[0]); + key->x = 0; + key->y = 0; + id1=id2=0; + +#define SK_LOOP(d,n) { \ + tmp=d[(n)]; \ + id2 = (data[id1] + tmp + id2) & 0xff; \ + if (++id1 == len) id1=0; \ + d[(n)]=d[id2]; \ + d[id2]=tmp; } + +#if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__INTEL__) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) + if (sizeof(RC4_INT) > 1) { + /* + * Unlike all other x86 [and x86_64] implementations, + * Intel P4 core [including EM64T] was found to perform + * poorly with wider RC4_INT. Performance improvement + * for IA-32 hand-coded assembler turned out to be 2.8x + * if re-coded for RC4_CHAR! It's however inappropriate + * to just switch to RC4_CHAR for x86[_64], as non-P4 + * implementations suffer from significant performance + * losses then, e.g. PIII exhibits >2x deterioration, + * and so does Opteron. In order to assure optimal + * all-round performance, we detect P4 at run-time by + * checking upon reserved bit 20 in CPU capability + * vector and set up compressed key schedule, which is + * recognized by correspondingly updated assembler + * module... Bit 20 is set up by OPENSSL_ia32_cpuid. + * + * <appro@fy.chalmers.se> + */ +#ifdef OPENSSL_FIPS + unsigned long *ia32cap_ptr = OPENSSL_ia32cap_loc(); + if (ia32cap_ptr && (*ia32cap_ptr & (1<<28))) { +#else + if (OPENSSL_ia32cap_P & (1<<28)) { +#endif + unsigned char *cp=(unsigned char *)d; + + for (i=0;i<256;i++) cp[i]=i; + for (i=0;i<256;i++) SK_LOOP(cp,i); + /* mark schedule as compressed! */ + d[256/sizeof(RC4_INT)]=-1; + return; + } + } +# endif +#endif + for (i=0; i < 256; i++) d[i]=i; + for (i=0; i < 256; i+=4) + { + SK_LOOP(d,i+0); + SK_LOOP(d,i+1); + SK_LOOP(d,i+2); + SK_LOOP(d,i+3); + } + } + diff --git a/openssl/crypto/rc4/rc4s.cpp b/openssl/crypto/rc4/rc4s.cpp new file mode 100644 index 000000000..3814fde99 --- /dev/null +++ b/openssl/crypto/rc4/rc4s.cpp @@ -0,0 +1,73 @@ +// +// gettsc.inl +// +// gives access to the Pentium's (secret) cycle counter +// +// This software was written by Leonard Janke (janke@unixg.ubc.ca) +// in 1996-7 and is entered, by him, into the public domain. + +#if defined(__WATCOMC__) +void GetTSC(unsigned long&); +#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax]; +#elif defined(__GNUC__) +inline +void GetTSC(unsigned long& tsc) +{ + asm volatile(".byte 15, 49\n\t" + : "=eax" (tsc) + : + : "%edx", "%eax"); +} +#elif defined(_MSC_VER) +inline +void GetTSC(unsigned long& tsc) +{ + unsigned long a; + __asm _emit 0fh + __asm _emit 31h + __asm mov a, eax; + tsc=a; +} +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <openssl/rc4.h> + +void main(int argc,char *argv[]) + { + unsigned char buffer[1024]; + RC4_KEY ctx; + unsigned long s1,s2,e1,e2; + unsigned char k[16]; + unsigned long data[2]; + unsigned char iv[8]; + int i,num=64,numm; + int j=0; + + if (argc >= 2) + num=atoi(argv[1]); + + if (num == 0) num=256; + if (num > 1024-16) num=1024-16; + numm=num+8; + + for (j=0; j<6; j++) + { + for (i=0; i<10; i++) /**/ + { + RC4(&ctx,numm,buffer,buffer); + GetTSC(s1); + RC4(&ctx,numm,buffer,buffer); + GetTSC(e1); + GetTSC(s2); + RC4(&ctx,num,buffer,buffer); + GetTSC(e2); + RC4(&ctx,num,buffer,buffer); + } + + printf("RC4 (%d bytes) %d %d (%d) - 8 bytes\n",num, + e1-s1,e2-s2,(e1-s1)-(e2-s2)); + } + } + diff --git a/openssl/crypto/rc4/rc4speed.c b/openssl/crypto/rc4/rc4speed.c new file mode 100644 index 000000000..0ebd38123 --- /dev/null +++ b/openssl/crypto/rc4/rc4speed.c @@ -0,0 +1,253 @@ +/* crypto/rc4/rc4speed.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */ +/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */ + +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX) +#define TIMES +#endif + +#include <stdio.h> + +#include <openssl/e_os2.h> +#include OPENSSL_UNISTD_IO +OPENSSL_DECLARE_EXIT + +#ifndef OPENSSL_SYS_NETWARE +#include <signal.h> +#endif + +#ifndef _IRIX +#include <time.h> +#endif +#ifdef TIMES +#include <sys/types.h> +#include <sys/times.h> +#endif + +/* Depending on the VMS version, the tms structure is perhaps defined. + The __TMS macro will show if it was. If it wasn't defined, we should + undefine TIMES, since that tells the rest of the program how things + should be handled. -- Richard Levitte */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) +#undef TIMES +#endif + +#ifndef TIMES +#include <sys/timeb.h> +#endif + +#if defined(sun) || defined(__ultrix) +#define _POSIX_SOURCE +#include <limits.h> +#include <sys/param.h> +#endif + +#include <openssl/rc4.h> + +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +#ifndef CLK_TCK +#define HZ 100.0 +#else /* CLK_TCK */ +#define HZ ((double)CLK_TCK) +#endif +#endif + +#define BUFSIZE ((long)1024) +long run=0; + +double Time_F(int s); +#ifdef SIGALRM +#if defined(__STDC__) || defined(sgi) || defined(_AIX) +#define SIGRETTYPE void +#else +#define SIGRETTYPE int +#endif + +SIGRETTYPE sig_done(int sig); +SIGRETTYPE sig_done(int sig) + { + signal(SIGALRM,sig_done); + run=0; +#ifdef LINT + sig=sig; +#endif + } +#endif + +#define START 0 +#define STOP 1 + +double Time_F(int s) + { + double ret; +#ifdef TIMES + static struct tms tstart,tend; + + if (s == START) + { + times(&tstart); + return(0); + } + else + { + times(&tend); + ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ; + return((ret == 0.0)?1e-6:ret); + } +#else /* !times() */ + static struct timeb tstart,tend; + long i; + + if (s == START) + { + ftime(&tstart); + return(0); + } + else + { + ftime(&tend); + i=(long)tend.millitm-(long)tstart.millitm; + ret=((double)(tend.time-tstart.time))+((double)i)/1e3; + return((ret == 0.0)?1e-6:ret); + } +#endif + } + +int main(int argc, char **argv) + { + long count; + static unsigned char buf[BUFSIZE]; + static unsigned char key[] ={ + 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0, + 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, + }; + RC4_KEY sch; + double a,b,c,d; +#ifndef SIGALRM + long ca,cb,cc; +#endif + +#ifndef TIMES + printf("To get the most accurate results, try to run this\n"); + printf("program when this computer is idle.\n"); +#endif + +#ifndef SIGALRM + printf("First we calculate the approximate speed ...\n"); + RC4_set_key(&sch,16,key); + count=10; + do { + long i; + unsigned long data[2]; + + count*=2; + Time_F(START); + for (i=count; i; i--) + RC4(&sch,8,buf,buf); + d=Time_F(STOP); + } while (d < 3.0); + ca=count/512; + cc=count*8/BUFSIZE+1; + printf("Doing RC4_set_key %ld times\n",ca); +#define COND(d) (count != (d)) +#define COUNT(d) (d) +#else +#define COND(c) (run) +#define COUNT(d) (count) + signal(SIGALRM,sig_done); + printf("Doing RC4_set_key for 10 seconds\n"); + alarm(10); +#endif + + Time_F(START); + for (count=0,run=1; COND(ca); count+=4) + { + RC4_set_key(&sch,16,key); + RC4_set_key(&sch,16,key); + RC4_set_key(&sch,16,key); + RC4_set_key(&sch,16,key); + } + d=Time_F(STOP); + printf("%ld RC4_set_key's in %.2f seconds\n",count,d); + a=((double)COUNT(ca))/d; + +#ifdef SIGALRM + printf("Doing RC4 on %ld byte blocks for 10 seconds\n",BUFSIZE); + alarm(10); +#else + printf("Doing RC4 %ld times on %ld byte blocks\n",cc,BUFSIZE); +#endif + Time_F(START); + for (count=0,run=1; COND(cc); count++) + RC4(&sch,BUFSIZE,buf,buf); + d=Time_F(STOP); + printf("%ld RC4's of %ld byte blocks in %.2f second\n", + count,BUFSIZE,d); + c=((double)COUNT(cc)*BUFSIZE)/d; + + printf("RC4 set_key per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a); + printf("RC4 bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c); + exit(0); +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS) + return(0); +#endif + } + diff --git a/openssl/crypto/rc4/rc4test.c b/openssl/crypto/rc4/rc4test.c new file mode 100644 index 000000000..54b597fa2 --- /dev/null +++ b/openssl/crypto/rc4/rc4test.c @@ -0,0 +1,236 @@ +/* crypto/rc4/rc4test.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "../e_os.h" + +#ifdef OPENSSL_NO_RC4 +int main(int argc, char *argv[]) +{ + printf("No RC4 support\n"); + return(0); +} +#else +#include <openssl/rc4.h> +#include <openssl/sha.h> + +static unsigned char keys[7][30]={ + {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}, + {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}, + {8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {4,0xef,0x01,0x23,0x45}, + {8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}, + {4,0xef,0x01,0x23,0x45}, + }; + +static unsigned char data_len[7]={8,8,8,20,28,10}; +static unsigned char data[7][30]={ + {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xff}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0xff}, + {0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0, + 0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0, + 0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xF0, + 0x12,0x34,0x56,0x78,0xff}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff}, + {0}, + }; + +static unsigned char output[7][30]={ + {0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96,0x00}, + {0x74,0x94,0xc2,0xe7,0x10,0x4b,0x08,0x79,0x00}, + {0xde,0x18,0x89,0x41,0xa3,0x37,0x5d,0x3a,0x00}, + {0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf, + 0xbd,0x61,0x5a,0x11,0x62,0xe1,0xc7,0xba, + 0x36,0xb6,0x78,0x58,0x00}, + {0x66,0xa0,0x94,0x9f,0x8a,0xf7,0xd6,0x89, + 0x1f,0x7f,0x83,0x2b,0xa8,0x33,0xc0,0x0c, + 0x89,0x2e,0xbe,0x30,0x14,0x3c,0xe2,0x87, + 0x40,0x01,0x1e,0xcf,0x00}, + {0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,0xbd,0x61,0x00}, + {0}, + }; + +int main(int argc, char *argv[]) + { + int err=0; + unsigned int i, j; + unsigned char *p; + RC4_KEY key; + unsigned char obuf[512]; + + for (i=0; i<6; i++) + { + RC4_set_key(&key,keys[i][0],&(keys[i][1])); + memset(obuf,0x00,sizeof(obuf)); + RC4(&key,data_len[i],&(data[i][0]),obuf); + if (memcmp(obuf,output[i],data_len[i]+1) != 0) + { + printf("error calculating RC4\n"); + printf("output:"); + for (j=0; j<data_len[i]+1U; j++) + printf(" %02x",obuf[j]); + printf("\n"); + printf("expect:"); + p= &(output[i][0]); + for (j=0; j<data_len[i]+1U; j++) + printf(" %02x",*(p++)); + printf("\n"); + err++; + } + else + printf("test %d ok\n",i); + } + printf("test end processing "); + for (i=0; i<data_len[3]; i++) + { + RC4_set_key(&key,keys[3][0],&(keys[3][1])); + memset(obuf,0x00,sizeof(obuf)); + RC4(&key,i,&(data[3][0]),obuf); + if ((memcmp(obuf,output[3],i) != 0) || (obuf[i] != 0)) + { + printf("error in RC4 length processing\n"); + printf("output:"); + for (j=0; j<i+1; j++) + printf(" %02x",obuf[j]); + printf("\n"); + printf("expect:"); + p= &(output[3][0]); + for (j=0; j<i; j++) + printf(" %02x",*(p++)); + printf(" 00\n"); + err++; + } + else + { + printf("."); + fflush(stdout); + } + } + printf("done\n"); + printf("test multi-call "); + for (i=0; i<data_len[3]; i++) + { + RC4_set_key(&key,keys[3][0],&(keys[3][1])); + memset(obuf,0x00,sizeof(obuf)); + RC4(&key,i,&(data[3][0]),obuf); + RC4(&key,data_len[3]-i,&(data[3][i]),&(obuf[i])); + if (memcmp(obuf,output[3],data_len[3]+1) != 0) + { + printf("error in RC4 multi-call processing\n"); + printf("output:"); + for (j=0; j<data_len[3]+1U; j++) + printf(" %02x",obuf[j]); + printf("\n"); + printf("expect:"); + p= &(output[3][0]); + for (j=0; j<data_len[3]+1U; j++) + printf(" %02x",*(p++)); + err++; + } + else + { + printf("."); + fflush(stdout); + } + } + printf("done\n"); + printf("bulk test "); + { unsigned char buf[513]; + SHA_CTX c; + unsigned char md[SHA_DIGEST_LENGTH]; + static unsigned char expected[]={ + 0xa4,0x7b,0xcc,0x00,0x3d,0xd0,0xbd,0xe1,0xac,0x5f, + 0x12,0x1e,0x45,0xbc,0xfb,0x1a,0xa1,0xf2,0x7f,0xc5 }; + + RC4_set_key(&key,keys[0][0],&(keys[3][1])); + memset(buf,'\0',sizeof(buf)); + SHA1_Init(&c); + for (i=0;i<2571;i++) { + RC4(&key,sizeof(buf),buf,buf); + SHA1_Update(&c,buf,sizeof(buf)); + } + SHA1_Final(md,&c); + + if (memcmp(md,expected,sizeof(md))) { + printf("error in RC4 bulk test\n"); + printf("output:"); + for (j=0; j<sizeof(md); j++) + printf(" %02x",md[j]); + printf("\n"); + printf("expect:"); + for (j=0; j<sizeof(md); j++) + printf(" %02x",expected[j]); + printf("\n"); + err++; + } + else printf("ok\n"); + } +#ifdef OPENSSL_SYS_NETWARE + if (err) printf("ERROR: %d\n", err); +#endif + EXIT(err); + return(0); + } +#endif diff --git a/openssl/crypto/rc4/rrc4.doc b/openssl/crypto/rc4/rrc4.doc new file mode 100644 index 000000000..2f9a953c1 --- /dev/null +++ b/openssl/crypto/rc4/rrc4.doc @@ -0,0 +1,278 @@ +Newsgroups: sci.crypt,alt.security,comp.security.misc,alt.privacy +Path: ghost.dsi.unimi.it!univ-lyon1.fr!jussieu.fr!zaphod.crihan.fr!warwick!clyde.open.ac.uk!strath-cs!bnr.co.uk!bt!pipex!howland.reston.ans.net!europa.eng.gtefsd.com!MathWorks.Com!yeshua.marcam.com!charnel.ecst.csuchico.edu!csusac!csus.edu!netcom.com!sterndark +From: sterndark@netcom.com (David Sterndark) +Subject: RC4 Algorithm revealed. +Message-ID: <sternCvKL4B.Hyy@netcom.com> +Sender: sterndark@netcom.com +Organization: NETCOM On-line Communication Services (408 261-4700 guest) +X-Newsreader: TIN [version 1.2 PL1] +Date: Wed, 14 Sep 1994 06:35:31 GMT +Lines: 263 +Xref: ghost.dsi.unimi.it sci.crypt:27332 alt.security:14732 comp.security.misc:11701 alt.privacy:16026 + +I am shocked, shocked, I tell you, shocked, to discover +that the cypherpunks have illegaly and criminally revealed +a crucial RSA trade secret and harmed the security of +America by reverse engineering the RC4 algorithm and +publishing it to the world. + +On Saturday morning an anonymous cypherpunk wrote: + + + SUBJECT: RC4 Source Code + + + I've tested this. It is compatible with the RC4 object module + that comes in the various RSA toolkits. + + /* rc4.h */ + typedef struct rc4_key + { + unsigned char state[256]; + unsigned char x; + unsigned char y; + } rc4_key; + void prepare_key(unsigned char *key_data_ptr,int key_data_len, + rc4_key *key); + void rc4(unsigned char *buffer_ptr,int buffer_len,rc4_key * key); + + + /*rc4.c */ + #include "rc4.h" + static void swap_byte(unsigned char *a, unsigned char *b); + void prepare_key(unsigned char *key_data_ptr, int key_data_len, + rc4_key *key) + { + unsigned char swapByte; + unsigned char index1; + unsigned char index2; + unsigned char* state; + short counter; + + state = &key->state[0]; + for(counter = 0; counter < 256; counter++) + state[counter] = counter; + key->x = 0; + key->y = 0; + index1 = 0; + index2 = 0; + for(counter = 0; counter < 256; counter++) + { + index2 = (key_data_ptr[index1] + state[counter] + + index2) % 256; + swap_byte(&state[counter], &state[index2]); + + index1 = (index1 + 1) % key_data_len; + } + } + + void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key *key) + { + unsigned char x; + unsigned char y; + unsigned char* state; + unsigned char xorIndex; + short counter; + + x = key->x; + y = key->y; + + state = &key->state[0]; + for(counter = 0; counter < buffer_len; counter ++) + { + x = (x + 1) % 256; + y = (state[x] + y) % 256; + swap_byte(&state[x], &state[y]); + + xorIndex = (state[x] + state[y]) % 256; + + buffer_ptr[counter] ^= state[xorIndex]; + } + key->x = x; + key->y = y; + } + + static void swap_byte(unsigned char *a, unsigned char *b) + { + unsigned char swapByte; + + swapByte = *a; + *a = *b; + *b = swapByte; + } + + + +Another cypherpunk, this one not anonymous, tested the +output from this algorithm against the output from +official RC4 object code + + + Date: Tue, 13 Sep 94 18:37:56 PDT + From: ekr@eit.COM (Eric Rescorla) + Message-Id: <9409140137.AA17743@eitech.eit.com> + Subject: RC4 compatibility testing + Cc: cypherpunks@toad.com + + One data point: + + I can't say anything about the internals of RC4 versus the + algorithm that Bill Sommerfeld is rightly calling 'Alleged RC4', + since I don't know anything about RC4's internals. + + However, I do have a (legitimately acquired) copy of BSAFE2 and + so I'm able to compare the output of this algorithm to the output + of genuine RC4 as found in BSAFE. I chose a set of test vectors + and ran them through both algorithms. The algorithms appear to + give identical results, at least with these key/plaintext pairs. + + I note that this is the algorithm _without_ Hal Finney's + proposed modification + + (see <199409130605.XAA24133@jobe.shell.portal.com>). + + The vectors I used (together with the ciphertext they produce) + follow at the end of this message. + + -Ekr + + Disclaimer: This posting does not reflect the opinions of EIT. + + --------------------results follow-------------- + Test vector 0 + Key: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef + Input: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef + 0 Output: 0x75 0xb7 0x87 0x80 0x99 0xe0 0xc5 0x96 + + Test vector 1 + Key: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef + Input: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0 Output: 0x74 0x94 0xc2 0xe7 0x10 0x4b 0x08 0x79 + + Test vector 2 + Key: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + Input: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0 Output: 0xde 0x18 0x89 0x41 0xa3 0x37 0x5d 0x3a + + Test vector 3 + Key: 0xef 0x01 0x23 0x45 + Input: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0 Output: 0xd6 0xa1 0x41 0xa7 0xec 0x3c 0x38 0xdf 0xbd 0x61 + + Test vector 4 + Key: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef + Input: 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 + 0 Output: 0x75 0x95 0xc3 0xe6 0x11 0x4a 0x09 0x78 0x0c 0x4a 0xd4 + 0x52 0x33 0x8e 0x1f 0xfd 0x9a 0x1b 0xe9 0x49 0x8f + 0x81 0x3d 0x76 0x53 0x34 0x49 0xb6 0x77 0x8d 0xca + 0xd8 0xc7 0x8a 0x8d 0x2b 0xa9 0xac 0x66 0x08 0x5d + 0x0e 0x53 0xd5 0x9c 0x26 0xc2 0xd1 0xc4 0x90 0xc1 + 0xeb 0xbe 0x0c 0xe6 0x6d 0x1b 0x6b 0x1b 0x13 0xb6 + 0xb9 0x19 0xb8 0x47 0xc2 0x5a 0x91 0x44 0x7a 0x95 + 0xe7 0x5e 0x4e 0xf1 0x67 0x79 0xcd 0xe8 0xbf 0x0a + 0x95 0x85 0x0e 0x32 0xaf 0x96 0x89 0x44 0x4f 0xd3 + 0x77 0x10 0x8f 0x98 0xfd 0xcb 0xd4 0xe7 0x26 0x56 + 0x75 0x00 0x99 0x0b 0xcc 0x7e 0x0c 0xa3 0xc4 0xaa + 0xa3 0x04 0xa3 0x87 0xd2 0x0f 0x3b 0x8f 0xbb 0xcd + 0x42 0xa1 0xbd 0x31 0x1d 0x7a 0x43 0x03 0xdd 0xa5 + 0xab 0x07 0x88 0x96 0xae 0x80 0xc1 0x8b 0x0a 0xf6 + 0x6d 0xff 0x31 0x96 0x16 0xeb 0x78 0x4e 0x49 0x5a + 0xd2 0xce 0x90 0xd7 0xf7 0x72 0xa8 0x17 0x47 0xb6 + 0x5f 0x62 0x09 0x3b 0x1e 0x0d 0xb9 0xe5 0xba 0x53 + 0x2f 0xaf 0xec 0x47 0x50 0x83 0x23 0xe6 0x71 0x32 + 0x7d 0xf9 0x44 0x44 0x32 0xcb 0x73 0x67 0xce 0xc8 + 0x2f 0x5d 0x44 0xc0 0xd0 0x0b 0x67 0xd6 0x50 0xa0 + 0x75 0xcd 0x4b 0x70 0xde 0xdd 0x77 0xeb 0x9b 0x10 + 0x23 0x1b 0x6b 0x5b 0x74 0x13 0x47 0x39 0x6d 0x62 + 0x89 0x74 0x21 0xd4 0x3d 0xf9 0xb4 0x2e 0x44 0x6e + 0x35 0x8e 0x9c 0x11 0xa9 0xb2 0x18 0x4e 0xcb 0xef + 0x0c 0xd8 0xe7 0xa8 0x77 0xef 0x96 0x8f 0x13 0x90 + 0xec 0x9b 0x3d 0x35 0xa5 0x58 0x5c 0xb0 0x09 0x29 + 0x0e 0x2f 0xcd 0xe7 0xb5 0xec 0x66 0xd9 0x08 0x4b + 0xe4 0x40 0x55 0xa6 0x19 0xd9 0xdd 0x7f 0xc3 0x16 + 0x6f 0x94 0x87 0xf7 0xcb 0x27 0x29 0x12 0x42 0x64 + 0x45 0x99 0x85 0x14 0xc1 0x5d 0x53 0xa1 0x8c 0x86 + 0x4c 0xe3 0xa2 0xb7 0x55 0x57 0x93 0x98 0x81 0x26 + 0x52 0x0e 0xac 0xf2 0xe3 0x06 0x6e 0x23 0x0c 0x91 + 0xbe 0xe4 0xdd 0x53 0x04 0xf5 0xfd 0x04 0x05 0xb3 + 0x5b 0xd9 0x9c 0x73 0x13 0x5d 0x3d 0x9b 0xc3 0x35 + 0xee 0x04 0x9e 0xf6 0x9b 0x38 0x67 0xbf 0x2d 0x7b + 0xd1 0xea 0xa5 0x95 0xd8 0xbf 0xc0 0x06 0x6f 0xf8 + 0xd3 0x15 0x09 0xeb 0x0c 0x6c 0xaa 0x00 0x6c 0x80 + 0x7a 0x62 0x3e 0xf8 0x4c 0x3d 0x33 0xc1 0x95 0xd2 + 0x3e 0xe3 0x20 0xc4 0x0d 0xe0 0x55 0x81 0x57 0xc8 + 0x22 0xd4 0xb8 0xc5 0x69 0xd8 0x49 0xae 0xd5 0x9d + 0x4e 0x0f 0xd7 0xf3 0x79 0x58 0x6b 0x4b 0x7f 0xf6 + 0x84 0xed 0x6a 0x18 0x9f 0x74 0x86 0xd4 0x9b 0x9c + 0x4b 0xad 0x9b 0xa2 0x4b 0x96 0xab 0xf9 0x24 0x37 + 0x2c 0x8a 0x8f 0xff 0xb1 0x0d 0x55 0x35 0x49 0x00 + 0xa7 0x7a 0x3d 0xb5 0xf2 0x05 0xe1 0xb9 0x9f 0xcd + 0x86 0x60 0x86 0x3a 0x15 0x9a 0xd4 0xab 0xe4 0x0f + 0xa4 0x89 0x34 0x16 0x3d 0xdd 0xe5 0x42 0xa6 0x58 + 0x55 0x40 0xfd 0x68 0x3c 0xbf 0xd8 0xc0 0x0f 0x12 + 0x12 0x9a 0x28 0x4d 0xea 0xcc 0x4c 0xde 0xfe 0x58 + 0xbe 0x71 0x37 0x54 0x1c 0x04 0x71 0x26 0xc8 0xd4 + 0x9e 0x27 0x55 0xab 0x18 0x1a 0xb7 0xe9 0x40 0xb0 + 0xc0 + + + +-- + --------------------------------------------------------------------- +We have the right to defend ourselves and our +property, because of the kind of animals that we James A. Donald +are. True law derives from this right, not from +the arbitrary power of the omnipotent state. jamesd@netcom.com + + |