OLD | NEW |
| (Empty) |
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")); | |
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
")); | |
153 &mov($count,&DWP(0,"ecx",$count,4)); | |
154 &add($count,"edx"); | |
155 &xor("ecx","ecx"); | |
156 &xor("edx","edx"); | |
157 #&mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4)); | |
158 &jmp_ptr($count); | |
159 | |
160 &set_label("ej7"); | |
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)); | |
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 | |
323 &align(64); | |
324 &set_label("cbc_enc_jmp_table"); | |
325 &data_word("0"); | |
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")); | |
343 &align(64); | |
344 | |
345 &function_end_B($name); | |
346 | |
347 } | |
348 | |
349 1; | |
OLD | NEW |