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