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