1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20.file "twofish-i586-asm.S"
21.text
22
23#include <asm/asm-offsets.h>
24
25
26
27#define in_blk 12
28#define out_blk 8
29#define ctx 4
30
31#define a_offset 0
32#define b_offset 4
33#define c_offset 8
34#define d_offset 12
35
36
37
38#define s0 0
39#define s1 1024
40#define s2 2048
41#define s3 3072
42#define w 4096
43#define k 4128
44
45
46
47#define R0D %eax
48#define R0B %al
49#define R0H %ah
50
51#define R1D %ebx
52#define R1B %bl
53#define R1H %bh
54
55#define R2D %ecx
56#define R2B %cl
57#define R2H %ch
58
59#define R3D %edx
60#define R3B %dl
61#define R3H %dh
62
63
64
65#define input_whitening(src,context,offset)\
66 xor w+offset(context), src;
67
68
69#define output_whitening(src,context,offset)\
70 xor w+16+offset(context), src;
71
72
73
74
75
76
77
78
79#define encrypt_round(a,b,c,d,round)\
80 push d
81 movzx b
82 mov s1(%ebp,%edi,4),d
83 movzx a
84 mov s2(%ebp,%edi,4),%esi;\
85 movzx b
86 ror $16, b
87 xor s2(%ebp,%edi,4),d
88 movzx a
89 ror $16, a
90 xor s3(%ebp,%edi,4),%esi;\
91 movzx b
92 xor s3(%ebp,%edi,4),d
93 movzx a
94 xor (%ebp,%edi,4), %esi;\
95 movzx b
96 ror $15, b
97 xor (%ebp,%edi,4), d
98 movzx a
99 xor s1(%ebp,%edi,4),%esi;\
100 pop %edi;\
101 add d
102 add %esi, d
103 add k+round(%ebp), %esi;\
104 xor %esi, c
105 rol $15, c
106 add k+4+round(%ebp),d
107 xor %edi, d
108
109
110
111
112
113
114
115
116
117#define encrypt_last_round(a,b,c,d,round)\
118 push d
119 movzx b
120 mov s1(%ebp,%edi,4),d
121 movzx a
122 mov s2(%ebp,%edi,4),%esi;\
123 movzx b
124 ror $16, b
125 xor s2(%ebp,%edi,4),d
126 movzx a
127 ror $16, a
128 xor s3(%ebp,%edi,4),%esi;\
129 movzx b
130 xor s3(%ebp,%edi,4),d
131 movzx a
132 xor (%ebp,%edi,4), %esi;\
133 movzx b
134 ror $16, b
135 xor (%ebp,%edi,4), d
136 movzx a
137 xor s1(%ebp,%edi,4),%esi;\
138 pop %edi;\
139 add d
140 add %esi, d
141 add k+round(%ebp), %esi;\
142 xor %esi, c
143 ror $1, c
144 add k+4+round(%ebp),d
145 xor %edi, d
146
147
148
149
150
151
152
153
154#define decrypt_round(a,b,c,d,round)\
155 push c
156 movzx a
157 mov (%ebp,%edi,4), c
158 movzx b
159 mov s3(%ebp,%edi,4),%esi;\
160 movzx a
161 ror $16, a
162 xor s1(%ebp,%edi,4),c
163 movzx b
164 ror $16, b
165 xor (%ebp,%edi,4), %esi;\
166 movzx a
167 xor s2(%ebp,%edi,4),c
168 movzx b
169 xor s1(%ebp,%edi,4),%esi;\
170 movzx a
171 ror $15, a
172 xor s3(%ebp,%edi,4),c
173 movzx b
174 xor s2(%ebp,%edi,4),%esi;\
175 pop %edi;\
176 add %esi, c
177 add c
178 add k+round(%ebp), c
179 xor %edi, c
180 add k+4+round(%ebp),%esi;\
181 xor %esi, d
182 rol $15, d
183
184
185
186
187
188
189
190
191
192#define decrypt_last_round(a,b,c,d,round)\
193 push c
194 movzx a
195 mov (%ebp,%edi,4), c
196 movzx b
197 mov s3(%ebp,%edi,4),%esi;\
198 movzx a
199 ror $16, a
200 xor s1(%ebp,%edi,4),c
201 movzx b
202 ror $16, b
203 xor (%ebp,%edi,4), %esi;\
204 movzx a
205 xor s2(%ebp,%edi,4),c
206 movzx b
207 xor s1(%ebp,%edi,4),%esi;\
208 movzx a
209 ror $16, a
210 xor s3(%ebp,%edi,4),c
211 movzx b
212 xor s2(%ebp,%edi,4),%esi;\
213 pop %edi;\
214 add %esi, c
215 add c
216 add k+round(%ebp), c
217 xor %edi, c
218 add k+4+round(%ebp),%esi;\
219 xor %esi, d
220 ror $1, d
221
222.align 4
223.global twofish_enc_blk
224.global twofish_dec_blk
225
226twofish_enc_blk:
227 push %ebp
228 push %ebx
229 push %esi
230 push %edi
231
232 mov ctx + 16(%esp), %ebp
233
234 mov in_blk+16(%esp),%edi
235
236 mov (%edi), %eax
237 mov b_offset(%edi), %ebx
238 mov c_offset(%edi), %ecx
239 mov d_offset(%edi), %edx
240 input_whitening(%eax,%ebp,a_offset)
241 ror $16, %eax
242 input_whitening(%ebx,%ebp,b_offset)
243 input_whitening(%ecx,%ebp,c_offset)
244 input_whitening(%edx,%ebp,d_offset)
245 rol $1, %edx
246
247 encrypt_round(R0,R1,R2,R3,0);
248 encrypt_round(R2,R3,R0,R1,8);
249 encrypt_round(R0,R1,R2,R3,2*8);
250 encrypt_round(R2,R3,R0,R1,3*8);
251 encrypt_round(R0,R1,R2,R3,4*8);
252 encrypt_round(R2,R3,R0,R1,5*8);
253 encrypt_round(R0,R1,R2,R3,6*8);
254 encrypt_round(R2,R3,R0,R1,7*8);
255 encrypt_round(R0,R1,R2,R3,8*8);
256 encrypt_round(R2,R3,R0,R1,9*8);
257 encrypt_round(R0,R1,R2,R3,10*8);
258 encrypt_round(R2,R3,R0,R1,11*8);
259 encrypt_round(R0,R1,R2,R3,12*8);
260 encrypt_round(R2,R3,R0,R1,13*8);
261 encrypt_round(R0,R1,R2,R3,14*8);
262 encrypt_last_round(R2,R3,R0,R1,15*8);
263
264 output_whitening(%eax,%ebp,c_offset)
265 output_whitening(%ebx,%ebp,d_offset)
266 output_whitening(%ecx,%ebp,a_offset)
267 output_whitening(%edx,%ebp,b_offset)
268 mov out_blk+16(%esp),%edi;
269 mov %eax, c_offset(%edi)
270 mov %ebx, d_offset(%edi)
271 mov %ecx, (%edi)
272 mov %edx, b_offset(%edi)
273
274 pop %edi
275 pop %esi
276 pop %ebx
277 pop %ebp
278 mov $1, %eax
279 ret
280
281twofish_dec_blk:
282 push %ebp
283 push %ebx
284 push %esi
285 push %edi
286
287
288 mov ctx + 16(%esp), %ebp
289
290 mov in_blk+16(%esp),%edi
291
292 mov (%edi), %eax
293 mov b_offset(%edi), %ebx
294 mov c_offset(%edi), %ecx
295 mov d_offset(%edi), %edx
296 output_whitening(%eax,%ebp,a_offset)
297 output_whitening(%ebx,%ebp,b_offset)
298 ror $16, %ebx
299 output_whitening(%ecx,%ebp,c_offset)
300 output_whitening(%edx,%ebp,d_offset)
301 rol $1, %ecx
302
303 decrypt_round(R0,R1,R2,R3,15*8);
304 decrypt_round(R2,R3,R0,R1,14*8);
305 decrypt_round(R0,R1,R2,R3,13*8);
306 decrypt_round(R2,R3,R0,R1,12*8);
307 decrypt_round(R0,R1,R2,R3,11*8);
308 decrypt_round(R2,R3,R0,R1,10*8);
309 decrypt_round(R0,R1,R2,R3,9*8);
310 decrypt_round(R2,R3,R0,R1,8*8);
311 decrypt_round(R0,R1,R2,R3,7*8);
312 decrypt_round(R2,R3,R0,R1,6*8);
313 decrypt_round(R0,R1,R2,R3,5*8);
314 decrypt_round(R2,R3,R0,R1,4*8);
315 decrypt_round(R0,R1,R2,R3,3*8);
316 decrypt_round(R2,R3,R0,R1,2*8);
317 decrypt_round(R0,R1,R2,R3,1*8);
318 decrypt_last_round(R2,R3,R0,R1,0);
319
320 input_whitening(%eax,%ebp,c_offset)
321 input_whitening(%ebx,%ebp,d_offset)
322 input_whitening(%ecx,%ebp,a_offset)
323 input_whitening(%edx,%ebp,b_offset)
324 mov out_blk+16(%esp),%edi;
325 mov %eax, c_offset(%edi)
326 mov %ebx, d_offset(%edi)
327 mov %ecx, (%edi)
328 mov %edx, b_offset(%edi)
329
330 pop %edi
331 pop %esi
332 pop %ebx
333 pop %ebp
334 mov $1, %eax
335 ret
336