]>
Commit | Line | Data |
---|---|---|
58964a49 RE |
1 | #!/usr/local/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. | |
26 | sub 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")); | |
6f7ac8e1 AP |
149 | &call(&label("PIC_point")); |
150 | &set_label("PIC_point"); | |
151 | &blindpop("edx"); | |
152 | &lea("ecx",&DWP(&label("cbc_enc_jmp_table")."-".&label("PIC_point"),"edx")); | |
68d2cf51 | 153 | &mov($count,&DWP(0,"ecx",$count,4)); |
6f7ac8e1 | 154 | &add($count,"edx"); |
58964a49 RE |
155 | &xor("ecx","ecx"); |
156 | &xor("edx","edx"); | |
6f7ac8e1 | 157 | #&mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4)); |
58964a49 RE |
158 | &jmp_ptr($count); |
159 | ||
160 | &set_label("ej7"); | |
58964a49 RE |
161 | &movb(&HB("edx"), &BP(6,$in,"",0)); |
162 | &shl("edx",8); | |
163 | &set_label("ej6"); | |
164 | &movb(&HB("edx"), &BP(5,$in,"",0)); | |
165 | &set_label("ej5"); | |
166 | &movb(&LB("edx"), &BP(4,$in,"",0)); | |
167 | &set_label("ej4"); | |
168 | &mov("ecx", &DWP(0,$in,"",0)); | |
169 | &jmp(&label("ejend")); | |
170 | &set_label("ej3"); | |
171 | &movb(&HB("ecx"), &BP(2,$in,"",0)); | |
58964a49 RE |
172 | &shl("ecx",8); |
173 | &set_label("ej2"); | |
174 | &movb(&HB("ecx"), &BP(1,$in,"",0)); | |
175 | &set_label("ej1"); | |
176 | &movb(&LB("ecx"), &BP(0,$in,"",0)); | |
177 | &set_label("ejend"); | |
178 | ||
179 | &xor("eax", "ecx"); | |
180 | &xor("ebx", "edx"); | |
181 | ||
182 | &bswap("eax") if $swap; | |
183 | &bswap("ebx") if $swap; | |
184 | ||
185 | &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call | |
186 | &mov(&DWP($data_off+4,"esp","",0), "ebx"); # | |
187 | ||
188 | &call($enc_func); | |
189 | ||
190 | &mov("eax", &DWP($data_off,"esp","",0)); | |
191 | &mov("ebx", &DWP($data_off+4,"esp","",0)); | |
192 | ||
193 | &bswap("eax") if $swap; | |
194 | &bswap("ebx") if $swap; | |
195 | ||
196 | &mov(&DWP(0,$out,"",0),"eax"); | |
197 | &mov(&DWP(4,$out,"",0),"ebx"); | |
198 | ||
199 | &jmp(&label("finish")); | |
200 | ||
201 | ############################################################# | |
202 | ############################################################# | |
203 | &set_label("decrypt",1); | |
204 | # decrypt start | |
205 | &and($count,0xfffffff8); | |
206 | # The next 2 instructions are only for if the jz is taken | |
207 | &mov("eax", &DWP($data_off+8,"esp","",0)); # get iv[0] | |
208 | &mov("ebx", &DWP($data_off+12,"esp","",0)); # get iv[1] | |
209 | &jz(&label("decrypt_finish")); | |
210 | ||
211 | &set_label("decrypt_loop"); | |
212 | &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes | |
213 | &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes | |
214 | ||
215 | &bswap("eax") if $swap; | |
216 | &bswap("ebx") if $swap; | |
217 | ||
218 | &mov(&DWP($data_off,"esp","",0), "eax"); # put back | |
219 | &mov(&DWP($data_off+4,"esp","",0), "ebx"); # | |
220 | ||
221 | &call($dec_func); | |
222 | ||
223 | &mov("eax", &DWP($data_off,"esp","",0)); # get return | |
224 | &mov("ebx", &DWP($data_off+4,"esp","",0)); # | |
225 | ||
226 | &bswap("eax") if $swap; | |
227 | &bswap("ebx") if $swap; | |
228 | ||
229 | &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0] | |
230 | &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1] | |
231 | ||
232 | &xor("ecx", "eax"); | |
233 | &xor("edx", "ebx"); | |
234 | ||
235 | &mov("eax", &DWP(0,$in,"",0)); # get old cipher text, | |
236 | &mov("ebx", &DWP(4,$in,"",0)); # next iv actually | |
237 | ||
238 | &mov(&DWP(0,$out,"",0),"ecx"); | |
239 | &mov(&DWP(4,$out,"",0),"edx"); | |
240 | ||
241 | &mov(&DWP($data_off+8,"esp","",0), "eax"); # save iv | |
242 | &mov(&DWP($data_off+12,"esp","",0), "ebx"); # | |
243 | ||
244 | &add($in, 8); | |
245 | &add($out, 8); | |
246 | ||
247 | &sub($count, 8); | |
248 | &jnz(&label("decrypt_loop")); | |
249 | ############################ ENDIT #######################3 | |
250 | &set_label("decrypt_finish"); | |
251 | &mov($count, &wparam(2)); # length | |
252 | &and($count, 7); | |
253 | &jz(&label("finish")); | |
254 | ||
255 | &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes | |
256 | &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes | |
257 | ||
258 | &bswap("eax") if $swap; | |
259 | &bswap("ebx") if $swap; | |
260 | ||
261 | &mov(&DWP($data_off,"esp","",0), "eax"); # put back | |
262 | &mov(&DWP($data_off+4,"esp","",0), "ebx"); # | |
263 | ||
264 | &call($dec_func); | |
265 | ||
266 | &mov("eax", &DWP($data_off,"esp","",0)); # get return | |
267 | &mov("ebx", &DWP($data_off+4,"esp","",0)); # | |
268 | ||
269 | &bswap("eax") if $swap; | |
270 | &bswap("ebx") if $swap; | |
271 | ||
272 | &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0] | |
273 | &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1] | |
274 | ||
275 | &xor("ecx", "eax"); | |
276 | &xor("edx", "ebx"); | |
277 | ||
278 | # this is for when we exit | |
279 | &mov("eax", &DWP(0,$in,"",0)); # get old cipher text, | |
280 | &mov("ebx", &DWP(4,$in,"",0)); # next iv actually | |
281 | ||
282 | &set_label("dj7"); | |
283 | &rotr("edx", 16); | |
284 | &movb(&BP(6,$out,"",0), &LB("edx")); | |
285 | &shr("edx",16); | |
286 | &set_label("dj6"); | |
287 | &movb(&BP(5,$out,"",0), &HB("edx")); | |
288 | &set_label("dj5"); | |
289 | &movb(&BP(4,$out,"",0), &LB("edx")); | |
290 | &set_label("dj4"); | |
291 | &mov(&DWP(0,$out,"",0), "ecx"); | |
292 | &jmp(&label("djend")); | |
293 | &set_label("dj3"); | |
294 | &rotr("ecx", 16); | |
295 | &movb(&BP(2,$out,"",0), &LB("ecx")); | |
296 | &shl("ecx",16); | |
297 | &set_label("dj2"); | |
298 | &movb(&BP(1,$in,"",0), &HB("ecx")); | |
299 | &set_label("dj1"); | |
300 | &movb(&BP(0,$in,"",0), &LB("ecx")); | |
301 | &set_label("djend"); | |
302 | ||
303 | # final iv is still in eax:ebx | |
304 | &jmp(&label("finish")); | |
305 | ||
306 | ||
307 | ############################ FINISH #######################3 | |
308 | &set_label("finish",1); | |
309 | &mov("ecx", &wparam($iv_off)); # Get iv ptr | |
310 | ||
311 | ################################################# | |
312 | $total=16+4; | |
313 | $total+=4 if ($p1 > 0); | |
314 | $total+=4 if ($p2 > 0); | |
315 | $total+=4 if ($p3 > 0); | |
316 | &add("esp",$total); | |
317 | ||
318 | &mov(&DWP(0,"ecx","",0), "eax"); # save iv | |
319 | &mov(&DWP(4,"ecx","",0), "ebx"); # save iv | |
320 | ||
321 | &function_end_A($name); | |
322 | ||
e19e5490 AP |
323 | &align(64); |
324 | &set_label("cbc_enc_jmp_table"); | |
58964a49 | 325 | &data_word("0"); |
6f7ac8e1 AP |
326 | &data_word(&label("ej1")."-".&label("PIC_point")); |
327 | &data_word(&label("ej2")."-".&label("PIC_point")); | |
328 | &data_word(&label("ej3")."-".&label("PIC_point")); | |
329 | &data_word(&label("ej4")."-".&label("PIC_point")); | |
330 | &data_word(&label("ej5")."-".&label("PIC_point")); | |
331 | &data_word(&label("ej6")."-".&label("PIC_point")); | |
332 | &data_word(&label("ej7")."-".&label("PIC_point")); | |
333 | # not used | |
334 | #&set_label("cbc_dec_jmp_table",1); | |
335 | #&data_word("0"); | |
336 | #&data_word(&label("dj1")."-".&label("PIC_point")); | |
337 | #&data_word(&label("dj2")."-".&label("PIC_point")); | |
338 | #&data_word(&label("dj3")."-".&label("PIC_point")); | |
339 | #&data_word(&label("dj4")."-".&label("PIC_point")); | |
340 | #&data_word(&label("dj5")."-".&label("PIC_point")); | |
341 | #&data_word(&label("dj6")."-".&label("PIC_point")); | |
342 | #&data_word(&label("dj7")."-".&label("PIC_point")); | |
e19e5490 | 343 | &align(64); |
58964a49 RE |
344 | |
345 | &function_end_B($name); | |
346 | ||
347 | } | |
348 | ||
349 | 1; |