1 /***************************************************************************
2 * Copyright (C) 2006 by Joachim Fritschi, <jfritschi@freenet.de> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
20 .file "twofish-x86_64-asm.S"
23 #include <linux/linkage.h>
24 #include <asm/asm-offsets.h>
31 /* Structure of the crypto context struct*/
33 #define s0 0 /* S0 Array 256 Words each */
34 #define s1 1024 /* S1 Array */
35 #define s2 2048 /* S2 Array */
36 #define s3 3072 /* S3 Array */
37 #define w 4096 /* 8 whitening keys (word) */
38 #define k 4128 /* key 1-32 ( word ) */
40 /* define a few register aliases to allow macro substitution */
63 /* performs input whitening */
64 #define input_whitening(src,context,offset)\
65 xor w+offset(context), src;
67 /* performs input whitening */
68 #define output_whitening(src,context,offset)\
69 xor w+16+offset(context), src;
73 * a input register containing a (rotated 16)
74 * b input register containing b
75 * c input register containing c
76 * d input register containing d (already rol $1)
77 * operations on a and b are interleaved to increase performance
79 #define encrypt_round(a,b,c,d,round)\
81 mov s1(%r11,%rdi,4),%r8d;\
83 mov s2(%r11,%rdi,4),%r9d;\
86 xor s2(%r11,%rdi,4),%r8d;\
89 xor s3(%r11,%rdi,4),%r9d;\
91 xor s3(%r11,%rdi,4),%r8d;\
93 xor (%r11,%rdi,4), %r9d;\
96 xor (%r11,%rdi,4), %r8d;\
98 xor s1(%r11,%rdi,4),%r9d;\
101 add k+round(%r11), %r9d;\
104 add k+4+round(%r11),%r8d;\
108 * a input register containing a(rotated 16)
109 * b input register containing b
110 * c input register containing c
111 * d input register containing d (already rol $1)
112 * operations on a and b are interleaved to increase performance
113 * during the round a and b are prepared for the output whitening
115 #define encrypt_last_round(a,b,c,d,round)\
119 mov s1(%r11,%rdi,4),%r8d;\
121 mov s2(%r11,%rdi,4),%r9d;\
124 xor s2(%r11,%rdi,4),%r8d;\
127 xor s3(%r11,%rdi,4),%r9d;\
129 xor s3(%r11,%rdi,4),%r8d;\
131 xor (%r11,%rdi,4), %r9d;\
134 xor (%r11,%rdi,4), %r8d;\
136 xor s1(%r11,%rdi,4),%r9d;\
139 add k+round(%r11), %r9d;\
142 add k+4+round(%r11),%r8d;\
146 * a input register containing a
147 * b input register containing b (rotated 16)
148 * c input register containing c (already rol $1)
149 * d input register containing d
150 * operations on a and b are interleaved to increase performance
152 #define decrypt_round(a,b,c,d,round)\
154 mov (%r11,%rdi,4), %r9d;\
156 mov s3(%r11,%rdi,4),%r8d;\
159 xor s1(%r11,%rdi,4),%r9d;\
162 xor (%r11,%rdi,4), %r8d;\
164 xor s2(%r11,%rdi,4),%r9d;\
166 xor s1(%r11,%rdi,4),%r8d;\
169 xor s3(%r11,%rdi,4),%r9d;\
171 xor s2(%r11,%rdi,4),%r8d;\
174 add k+round(%r11), %r9d;\
176 add k+4+round(%r11),%r8d;\
181 * a input register containing a
182 * b input register containing b
183 * c input register containing c (already rol $1)
184 * d input register containing d
185 * operations on a and b are interleaved to increase performance
186 * during the round a and b are prepared for the output whitening
188 #define decrypt_last_round(a,b,c,d,round)\
190 mov (%r11,%rdi,4), %r9d;\
192 mov s3(%r11,%rdi,4),%r8d;\
195 xor (%r11,%rdi,4), %r8d;\
201 xor s1(%r11,%rdi,4),%r9d;\
203 xor s1(%r11,%rdi,4),%r8d;\
205 xor s2(%r11,%rdi,4),%r9d;\
207 xor s2(%r11,%rdi,4),%r8d;\
209 xor s3(%r11,%rdi,4),%r9d;\
212 add k+round(%r11), %r9d;\
214 add k+4+round(%r11),%r8d;\
218 ENTRY(twofish_enc_blk)
221 /* %rdi contains the ctx address */
222 /* %rsi contains the output address */
223 /* %rdx contains the input address */
224 /* ctx address is moved to free one non-rex register
225 as target for the 8bit high operations */
230 input_whitening(R1,%r11,a_offset)
231 input_whitening(R3,%r11,c_offset)
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);
257 output_whitening(%r10,%r11,a_offset)
263 output_whitening(R1,%r11,c_offset)
269 ENDPROC(twofish_enc_blk)
271 ENTRY(twofish_dec_blk)
274 /* %rdi contains the ctx address */
275 /* %rsi contains the output address */
276 /* %rdx contains the input address */
277 /* ctx address is moved to free one non-rex register
278 as target for the 8bit high operations */
283 output_whitening(R1,%r11,a_offset)
284 output_whitening(R3,%r11,c_offset)
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);
309 input_whitening(%r10,%r11,a_offset)
315 input_whitening(R1,%r11,c_offset)
321 ENDPROC(twofish_dec_blk)