aboutsummaryrefslogtreecommitdiff
path: root/openssl/crypto/rc4
diff options
context:
space:
mode:
Diffstat (limited to 'openssl/crypto/rc4')
-rw-r--r--openssl/crypto/rc4/Makefile125
-rw-r--r--openssl/crypto/rc4/asm/rc4-586.pl230
-rw-r--r--openssl/crypto/rc4/asm/rc4-ia64.S159
-rw-r--r--openssl/crypto/rc4/asm/rc4-x86_64.pl366
-rw-r--r--openssl/crypto/rc4/rc4.c193
-rw-r--r--openssl/crypto/rc4/rc4.h90
-rw-r--r--openssl/crypto/rc4/rc4_enc.c315
-rw-r--r--openssl/crypto/rc4/rc4_fblk.c75
-rw-r--r--openssl/crypto/rc4/rc4_locl.h5
-rw-r--r--openssl/crypto/rc4/rc4_skey.c165
-rw-r--r--openssl/crypto/rc4/rc4s.cpp73
-rw-r--r--openssl/crypto/rc4/rc4speed.c253
-rw-r--r--openssl/crypto/rc4/rc4test.c236
-rw-r--r--openssl/crypto/rc4/rrc4.doc278
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
+
+