summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/perlasm
diff options
context:
space:
mode:
authorryker <>1998-10-05 20:13:14 +0000
committerryker <>1998-10-05 20:13:14 +0000
commitaeeae06a79815dc190061534d47236cec09f9e32 (patch)
tree851692b9c2f9c04f077666855641900f19fdb217 /src/lib/libcrypto/perlasm
parenta4f79641824cbf9f60ca9d1168d1fcc46717a82a (diff)
downloadopenbsd-aeeae06a79815dc190061534d47236cec09f9e32.tar.gz
openbsd-aeeae06a79815dc190061534d47236cec09f9e32.tar.bz2
openbsd-aeeae06a79815dc190061534d47236cec09f9e32.zip
Import of SSLeay-0.9.0b with RSA and IDEA stubbed + OpenBSD build
functionality for shared libs. Note that routines such as sslv2_init and friends that use RSA will not work due to lack of RSA in this library. Needs documentation and help from ports for easy upgrade to full functionality where legally possible.
Diffstat (limited to 'src/lib/libcrypto/perlasm')
-rw-r--r--src/lib/libcrypto/perlasm/cbc.pl342
-rw-r--r--src/lib/libcrypto/perlasm/readme124
-rw-r--r--src/lib/libcrypto/perlasm/x86asm.pl113
3 files changed, 579 insertions, 0 deletions
diff --git a/src/lib/libcrypto/perlasm/cbc.pl b/src/lib/libcrypto/perlasm/cbc.pl
new file mode 100644
index 0000000000..2789305790
--- /dev/null
+++ b/src/lib/libcrypto/perlasm/cbc.pl
@@ -0,0 +1,342 @@
1#!/usr/bin/perl
2
3# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
4# des_cblock (*input);
5# des_cblock (*output);
6# long length;
7# des_key_schedule schedule;
8# des_cblock (*ivec);
9# int enc;
10#
11# calls
12# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
13#
14
15#&cbc("des_ncbc_encrypt","des_encrypt",0);
16#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",
17# 1,4,5,3,5,-1);
18#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",
19# 0,4,5,3,5,-1);
20#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",
21# 0,6,7,3,4,5);
22#
23# When doing a cipher that needs bigendian order,
24# for encrypt, the iv is kept in bigendian form,
25# while for decrypt, it is kept in little endian.
26sub cbc
27 {
28 local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_;
29 # name is the function name
30 # enc_func and dec_func and the functions to call for encrypt/decrypt
31 # swap is true if byte order needs to be reversed
32 # iv_off is parameter number for the iv
33 # enc_off is parameter number for the encrypt/decrypt flag
34 # p1,p2,p3 are the offsets for parameters to be passed to the
35 # underlying calls.
36
37 &function_begin_B($name,"");
38 &comment("");
39
40 $in="esi";
41 $out="edi";
42 $count="ebp";
43
44 &push("ebp");
45 &push("ebx");
46 &push("esi");
47 &push("edi");
48
49 $data_off=4;
50 $data_off+=4 if ($p1 > 0);
51 $data_off+=4 if ($p2 > 0);
52 $data_off+=4 if ($p3 > 0);
53
54 &mov($count, &wparam(2)); # length
55
56 &comment("getting iv ptr from parameter $iv_off");
57 &mov("ebx", &wparam($iv_off)); # Get iv ptr
58
59 &mov($in, &DWP(0,"ebx","",0));# iv[0]
60 &mov($out, &DWP(4,"ebx","",0));# iv[1]
61
62 &push($out);
63 &push($in);
64 &push($out); # used in decrypt for iv[1]
65 &push($in); # used in decrypt for iv[0]
66
67 &mov("ebx", "esp"); # This is the address of tin[2]
68
69 &mov($in, &wparam(0)); # in
70 &mov($out, &wparam(1)); # out
71
72 # We have loaded them all, how lets push things
73 &comment("getting encrypt flag from parameter $enc_off");
74 &mov("ecx", &wparam($enc_off)); # Get enc flag
75 if ($p3 > 0)
76 {
77 &comment("get and push parameter $p3");
78 if ($enc_off != $p3)
79 { &mov("eax", &wparam($p3)); &push("eax"); }
80 else { &push("ecx"); }
81 }
82 if ($p2 > 0)
83 {
84 &comment("get and push parameter $p2");
85 if ($enc_off != $p2)
86 { &mov("eax", &wparam($p2)); &push("eax"); }
87 else { &push("ecx"); }
88 }
89 if ($p1 > 0)
90 {
91 &comment("get and push parameter $p1");
92 if ($enc_off != $p1)
93 { &mov("eax", &wparam($p1)); &push("eax"); }
94 else { &push("ecx"); }
95 }
96 &push("ebx"); # push data/iv
97
98 &cmp("ecx",0);
99 &jz(&label("decrypt"));
100
101 &and($count,0xfffffff8);
102 &mov("eax", &DWP($data_off,"esp","",0)); # load iv[0]
103 &mov("ebx", &DWP($data_off+4,"esp","",0)); # load iv[1]
104
105 &jz(&label("encrypt_finish"));
106
107 #############################################################
108
109 &set_label("encrypt_loop");
110 # encrypt start
111 # "eax" and "ebx" hold iv (or the last cipher text)
112
113 &mov("ecx", &DWP(0,$in,"",0)); # load first 4 bytes
114 &mov("edx", &DWP(4,$in,"",0)); # second 4 bytes
115
116 &xor("eax", "ecx");
117 &xor("ebx", "edx");
118
119 &bswap("eax") if $swap;
120 &bswap("ebx") if $swap;
121
122 &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call
123 &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
124
125 &call($enc_func);
126
127 &mov("eax", &DWP($data_off,"esp","",0));
128 &mov("ebx", &DWP($data_off+4,"esp","",0));
129
130 &bswap("eax") if $swap;
131 &bswap("ebx") if $swap;
132
133 &mov(&DWP(0,$out,"",0),"eax");
134 &mov(&DWP(4,$out,"",0),"ebx");
135
136 # eax and ebx are the next iv.
137
138 &add($in, 8);
139 &add($out, 8);
140
141 &sub($count, 8);
142 &jnz(&label("encrypt_loop"));
143
144###################################################################3
145 &set_label("encrypt_finish");
146 &mov($count, &wparam(2)); # length
147 &and($count, 7);
148 &jz(&label("finish"));
149 &xor("ecx","ecx");
150 &xor("edx","edx");
151 &mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4));
152 &jmp_ptr($count);
153
154&set_label("ej7");
155 &xor("edx", "edx") if $ppro; # ppro friendly
156 &movb(&HB("edx"), &BP(6,$in,"",0));
157 &shl("edx",8);
158&set_label("ej6");
159 &movb(&HB("edx"), &BP(5,$in,"",0));
160&set_label("ej5");
161 &movb(&LB("edx"), &BP(4,$in,"",0));
162&set_label("ej4");
163 &mov("ecx", &DWP(0,$in,"",0));
164 &jmp(&label("ejend"));
165&set_label("ej3");
166 &movb(&HB("ecx"), &BP(2,$in,"",0));
167 &xor("ecx", "ecx") if $ppro; # ppro friendly
168 &shl("ecx",8);
169&set_label("ej2");
170 &movb(&HB("ecx"), &BP(1,$in,"",0));
171&set_label("ej1");
172 &movb(&LB("ecx"), &BP(0,$in,"",0));
173&set_label("ejend");
174
175 &xor("eax", "ecx");
176 &xor("ebx", "edx");
177
178 &bswap("eax") if $swap;
179 &bswap("ebx") if $swap;
180
181 &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call
182 &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
183
184 &call($enc_func);
185
186 &mov("eax", &DWP($data_off,"esp","",0));
187 &mov("ebx", &DWP($data_off+4,"esp","",0));
188
189 &bswap("eax") if $swap;
190 &bswap("ebx") if $swap;
191
192 &mov(&DWP(0,$out,"",0),"eax");
193 &mov(&DWP(4,$out,"",0),"ebx");
194
195 &jmp(&label("finish"));
196
197 #############################################################
198 #############################################################
199 &set_label("decrypt",1);
200 # decrypt start
201 &and($count,0xfffffff8);
202 # The next 2 instructions are only for if the jz is taken
203 &mov("eax", &DWP($data_off+8,"esp","",0)); # get iv[0]
204 &mov("ebx", &DWP($data_off+12,"esp","",0)); # get iv[1]
205 &jz(&label("decrypt_finish"));
206
207 &set_label("decrypt_loop");
208 &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes
209 &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes
210
211 &bswap("eax") if $swap;
212 &bswap("ebx") if $swap;
213
214 &mov(&DWP($data_off,"esp","",0), "eax"); # put back
215 &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
216
217 &call($dec_func);
218
219 &mov("eax", &DWP($data_off,"esp","",0)); # get return
220 &mov("ebx", &DWP($data_off+4,"esp","",0)); #
221
222 &bswap("eax") if $swap;
223 &bswap("ebx") if $swap;
224
225 &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0]
226 &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1]
227
228 &xor("ecx", "eax");
229 &xor("edx", "ebx");
230
231 &mov("eax", &DWP(0,$in,"",0)); # get old cipher text,
232 &mov("ebx", &DWP(4,$in,"",0)); # next iv actually
233
234 &mov(&DWP(0,$out,"",0),"ecx");
235 &mov(&DWP(4,$out,"",0),"edx");
236
237 &mov(&DWP($data_off+8,"esp","",0), "eax"); # save iv
238 &mov(&DWP($data_off+12,"esp","",0), "ebx"); #
239
240 &add($in, 8);
241 &add($out, 8);
242
243 &sub($count, 8);
244 &jnz(&label("decrypt_loop"));
245############################ ENDIT #######################3
246 &set_label("decrypt_finish");
247 &mov($count, &wparam(2)); # length
248 &and($count, 7);
249 &jz(&label("finish"));
250
251 &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes
252 &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes
253
254 &bswap("eax") if $swap;
255 &bswap("ebx") if $swap;
256
257 &mov(&DWP($data_off,"esp","",0), "eax"); # put back
258 &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
259
260 &call($dec_func);
261
262 &mov("eax", &DWP($data_off,"esp","",0)); # get return
263 &mov("ebx", &DWP($data_off+4,"esp","",0)); #
264
265 &bswap("eax") if $swap;
266 &bswap("ebx") if $swap;
267
268 &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0]
269 &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1]
270
271 &xor("ecx", "eax");
272 &xor("edx", "ebx");
273
274 # this is for when we exit
275 &mov("eax", &DWP(0,$in,"",0)); # get old cipher text,
276 &mov("ebx", &DWP(4,$in,"",0)); # next iv actually
277
278&set_label("dj7");
279 &rotr("edx", 16);
280 &movb(&BP(6,$out,"",0), &LB("edx"));
281 &shr("edx",16);
282&set_label("dj6");
283 &movb(&BP(5,$out,"",0), &HB("edx"));
284&set_label("dj5");
285 &movb(&BP(4,$out,"",0), &LB("edx"));
286&set_label("dj4");
287 &mov(&DWP(0,$out,"",0), "ecx");
288 &jmp(&label("djend"));
289&set_label("dj3");
290 &rotr("ecx", 16);
291 &movb(&BP(2,$out,"",0), &LB("ecx"));
292 &shl("ecx",16);
293&set_label("dj2");
294 &movb(&BP(1,$in,"",0), &HB("ecx"));
295&set_label("dj1");
296 &movb(&BP(0,$in,"",0), &LB("ecx"));
297&set_label("djend");
298
299 # final iv is still in eax:ebx
300 &jmp(&label("finish"));
301
302
303############################ FINISH #######################3
304 &set_label("finish",1);
305 &mov("ecx", &wparam($iv_off)); # Get iv ptr
306
307 #################################################
308 $total=16+4;
309 $total+=4 if ($p1 > 0);
310 $total+=4 if ($p2 > 0);
311 $total+=4 if ($p3 > 0);
312 &add("esp",$total);
313
314 &mov(&DWP(0,"ecx","",0), "eax"); # save iv
315 &mov(&DWP(4,"ecx","",0), "ebx"); # save iv
316
317 &function_end_A($name);
318
319 &set_label("cbc_enc_jmp_table",1);
320 &data_word("0");
321 &data_word(&label("ej1"));
322 &data_word(&label("ej2"));
323 &data_word(&label("ej3"));
324 &data_word(&label("ej4"));
325 &data_word(&label("ej5"));
326 &data_word(&label("ej6"));
327 &data_word(&label("ej7"));
328 &set_label("cbc_dec_jmp_table",1);
329 &data_word("0");
330 &data_word(&label("dj1"));
331 &data_word(&label("dj2"));
332 &data_word(&label("dj3"));
333 &data_word(&label("dj4"));
334 &data_word(&label("dj5"));
335 &data_word(&label("dj6"));
336 &data_word(&label("dj7"));
337
338 &function_end_B($name);
339
340 }
341
3421;
diff --git a/src/lib/libcrypto/perlasm/readme b/src/lib/libcrypto/perlasm/readme
new file mode 100644
index 0000000000..f02bbee75a
--- /dev/null
+++ b/src/lib/libcrypto/perlasm/readme
@@ -0,0 +1,124 @@
1The perl scripts in this directory are my 'hack' to generate
2multiple different assembler formats via the one origional script.
3
4The way to use this library is to start with adding the path to this directory
5and then include it.
6
7push(@INC,"perlasm","../../perlasm");
8require "x86asm.pl";
9
10The first thing we do is setup the file and type of assember
11
12&asm_init($ARGV[0],$0);
13
14The first argument is the 'type'. Currently
15'cpp', 'sol', 'a.out', 'elf' or 'win32'.
16Argument 2 is the file name.
17
18The reciprocal function is
19&asm_finish() which should be called at the end.
20
21There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler,
22and x86unix.pl which is the unix (gas) version.
23
24Functions of interest are:
25&external_label("des_SPtrans"); declare and external variable
26&LB(reg); Low byte for a register
27&HB(reg); High byte for a register
28&BP(off,base,index,scale) Byte pointer addressing
29&DWP(off,base,index,scale) Word pointer addressing
30&stack_push(num) Basically a 'sub esp, num*4' with extra
31&stack_pop(num) inverse of stack_push
32&function_begin(name,extra) Start a function with pushing of
33 edi, esi, ebx and ebp. extra is extra win32
34 external info that may be required.
35&function_begin_B(name,extra) Same as norma function_begin but no pushing.
36&function_end(name) Call at end of function.
37&function_end_A(name) Standard pop and ret, for use inside functions
38&function_end_B(name) Call at end but with poping or 'ret'.
39&swtmp(num) Address on stack temp word.
40&wparam(num) Parameter number num, that was push
41 in C convention. This all works over pushes
42 and pops.
43&comment("hello there") Put in a comment.
44&label("loop") Refer to a label, normally a jmp target.
45&set_label("loop") Set a label at this point.
46&data_word(word) Put in a word of data.
47
48So how does this all hold together? Given
49
50int calc(int len, int *data)
51 {
52 int i,j=0;
53
54 for (i=0; i<len; i++)
55 {
56 j+=other(data[i]);
57 }
58 }
59
60So a very simple version of this function could be coded as
61
62 push(@INC,"perlasm","../../perlasm");
63 require "x86asm.pl";
64
65 &asm_init($ARGV[0],"cacl.pl");
66
67 &external_label("other");
68
69 $tmp1= "eax";
70 $j= "edi";
71 $data= "esi";
72 $i= "ebp";
73
74 &comment("a simple function");
75 &function_begin("calc");
76 &mov( $data, &wparam(1)); # data
77 &xor( $j, $j);
78 &xor( $i, $i);
79
80 &set_label("loop");
81 &cmp( $i, &wparam(0));
82 &jge( &label("end"));
83
84 &mov( $tmp1, &DWP(0,$data,$i,4));
85 &push( $tmp1);
86 &call( "other");
87 &add( $j, "eax");
88 &pop( $tmp1);
89 &inc( $i);
90 &jmp( &label("loop"));
91
92 &set_label("end");
93 &mov( "eax", $j);
94
95 &function_end("calc");
96
97 &asm_finish();
98
99The above example is very very unoptimised but gives an idea of how
100things work.
101
102There is also a cbc mode function generator in cbc.pl
103
104&cbc( $name,
105 $encrypt_function_name,
106 $decrypt_function_name,
107 $true_if_byte_swap_needed,
108 $parameter_number_for_iv,
109 $parameter_number_for_encrypt_flag,
110 $first_parameter_to_pass,
111 $second_parameter_to_pass,
112 $third_parameter_to_pass);
113
114So for example, given
115void BF_encrypt(BF_LONG *data,BF_KEY *key);
116void BF_decrypt(BF_LONG *data,BF_KEY *key);
117void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
118 BF_KEY *ks, unsigned char *iv, int enc);
119
120&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);
121
122&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
123&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
124
diff --git a/src/lib/libcrypto/perlasm/x86asm.pl b/src/lib/libcrypto/perlasm/x86asm.pl
new file mode 100644
index 0000000000..6a9156ae9a
--- /dev/null
+++ b/src/lib/libcrypto/perlasm/x86asm.pl
@@ -0,0 +1,113 @@
1#!/usr/bin/perl
2
3# require 'x86asm.pl';
4# &asm_init("cpp","des-586.pl");
5# XXX
6# XXX
7# main'asm_finish
8
9sub main'asm_finish
10 {
11 &file_end();
12 &asm_finish_cpp() if $cpp;
13 print &asm_get_output();
14 }
15
16sub main'asm_init
17 {
18 ($type,$fn)=@_;
19 $filename=$fn;
20
21 $cpp=$sol=$aout=$win32=0;
22 if ( ($type eq "elf"))
23 { require "x86unix.pl"; }
24 elsif ( ($type eq "a.out"))
25 { $aout=1; require "x86unix.pl"; }
26 elsif ( ($type eq "sol"))
27 { $sol=1; require "x86unix.pl"; }
28 elsif ( ($type eq "cpp"))
29 { $cpp=1; require "x86unix.pl"; }
30 elsif ( ($type eq "win32"))
31 { $win32=1; require "x86ms.pl"; }
32 else
33 {
34 print STDERR <<"EOF";
35Pick one target type from
36 elf - linux, FreeBSD etc
37 a.out - old linux
38 sol - x86 solaris
39 cpp - format so x86unix.cpp can be used
40 win32 - Windows 95/Windows NT
41EOF
42 exit(1);
43 }
44
45 &asm_init_output();
46
47&comment("Don't even think of reading this code");
48&comment("It was automatically generated by $filename");
49&comment("Which is a perl program used to generate the x86 assember for");
50&comment("any of elf, a.out, BSDI,Win32, or Solaris");
51&comment("eric <eay\@cryptsoft.com>");
52&comment("");
53
54 $filename =~ s/\.pl$//;
55 &file($filename);
56 }
57
58sub asm_finish_cpp
59 {
60 return unless $cpp;
61
62 local($tmp,$i);
63 foreach $i (&get_labels())
64 {
65 $tmp.="#define $i _$i\n";
66 }
67 print <<"EOF";
68/* Run the C pre-processor over this file with one of the following defined
69 * ELF - elf object files,
70 * OUT - a.out object files,
71 * BSDI - BSDI style a.out object files
72 * SOL - Solaris style elf
73 */
74
75#define TYPE(a,b) .type a,b
76#define SIZE(a,b) .size a,b
77
78#if defined(OUT) || defined(BSDI)
79$tmp
80#endif
81
82#ifdef OUT
83#define OK 1
84#define ALIGN 4
85#endif
86
87#ifdef BSDI
88#define OK 1
89#define ALIGN 4
90#undef SIZE
91#undef TYPE
92#define SIZE(a,b)
93#define TYPE(a,b)
94#endif
95
96#if defined(ELF) || defined(SOL)
97#define OK 1
98#define ALIGN 16
99#endif
100
101#ifndef OK
102You need to define one of
103ELF - elf systems - linux-elf, NetBSD and DG-UX
104OUT - a.out systems - linux-a.out and FreeBSD
105SOL - solaris systems, which are elf with strange comment lines
106BSDI - a.out with a very primative version of as.
107#endif
108
109/* Let the Assembler begin :-) */
110EOF
111 }
112
1131;