crypto: blowfish - add x86_64 assembly implementation
[linux-3.10.git] / arch / x86 / crypto / blowfish-x86_64-asm_64.S
1 /*
2  * Blowfish Cipher Algorithm (x86_64)
3  *
4  * Copyright (C) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
19  * USA
20  *
21  */
22
23 .file "blowfish-x86_64-asm.S"
24 .text
25
26 /* structure of crypto context */
27 #define p       0
28 #define s0      ((16 + 2) * 4)
29 #define s1      ((16 + 2 + (1 * 256)) * 4)
30 #define s2      ((16 + 2 + (2 * 256)) * 4)
31 #define s3      ((16 + 2 + (3 * 256)) * 4)
32
33 /* register macros */
34 #define CTX %rdi
35 #define RIO %rsi
36
37 #define RX0 %rax
38 #define RX1 %rbx
39 #define RX2 %rcx
40 #define RX3 %rdx
41
42 #define RX0d %eax
43 #define RX1d %ebx
44 #define RX2d %ecx
45 #define RX3d %edx
46
47 #define RX0bl %al
48 #define RX1bl %bl
49 #define RX2bl %cl
50 #define RX3bl %dl
51
52 #define RX0bh %ah
53 #define RX1bh %bh
54 #define RX2bh %ch
55 #define RX3bh %dh
56
57 #define RT0 %rbp
58 #define RT1 %rsi
59
60 #define RT0d %ebp
61 #define RT1d %esi
62
63 #define RK0 %r8
64 #define RK1 %r9
65 #define RK2 %r10
66 #define RK3 %r11
67
68 #define RK0d %r8d
69 #define RK1d %r9d
70 #define RK2d %r10d
71 #define RK3d %r11d
72
73 #define RKEY %r12
74
75 /***********************************************************************
76  * 1-way blowfish
77  ***********************************************************************/
78 #define F(x, k) \
79         rorq $16,               x; \
80         movzbl x ## bh,         RT0d; \
81         movzbl x ## bl,         RT1d; \
82         rolq $16,               x; \
83         movl s0(CTX,RT0,4),     k ## d; \
84         addl s1(CTX,RT1,4),     k ## d; \
85         movzbl x ## bh,         RT0d; \
86         movzbl x ## bl,         RT1d; \
87         rolq $32,               x; \
88         xorl s2(CTX,RT0,4),     k ## d; \
89         addl s3(CTX,RT1,4),     k ## d; \
90         xorq k,                 x;
91
92 #define add_roundkey_enc(n) \
93         xorq p+4*(n)(CTX),      RX0;
94
95 #define round_enc(n) \
96         add_roundkey_enc(n); \
97         \
98         F(RX0, RK0); \
99         F(RX0, RK0);
100
101 #define round_final_enc(n) \
102         xorq p+4*(n)(CTX),      RX0;
103
104 #define add_roundkey_dec(n) \
105         movq p+4*(n-1)(CTX),    RT0; \
106         rorq $32,               RT0; \
107         xorq RT0,               RX0;
108
109 #define round_dec(n) \
110         add_roundkey_dec(n); \
111         \
112         F(RX0, RK0); \
113         F(RX0, RK0); \
114
115 #define read_block() \
116         movq (RIO),             RX0; \
117         rorq $32,               RX0; \
118         bswapq                  RX0;
119
120 #define write_block() \
121         bswapq                  RX0; \
122         movq RX0,               (RIO);
123
124 #define xor_block() \
125         bswapq                  RX0; \
126         xorq RX0,               (RIO);
127
128 .align 8
129 .global __blowfish_enc_blk
130 .type   __blowfish_enc_blk,@function;
131
132 __blowfish_enc_blk:
133         // input:
134         //      %rdi: ctx, CTX
135         //      %rsi: dst
136         //      %rdx: src
137         //      %rcx: bool xor
138         pushq %rbp;
139         pushq %rbx;
140
141         pushq %rsi;
142         pushq %rcx;
143         movq %rdx, RIO;
144
145         read_block();
146
147         round_enc(0);
148         round_enc(2);
149         round_enc(4);
150         round_enc(6);
151         round_enc(8);
152         round_enc(10);
153         round_enc(12);
154         round_enc(14);
155         add_roundkey_enc(16);
156
157         popq %rbp;
158         popq RIO;
159
160         test %bpl, %bpl;
161         jnz __enc_xor;
162
163         write_block();
164
165 __enc_ret:
166         popq %rbx;
167         popq %rbp;
168
169         ret;
170
171 __enc_xor:
172         xor_block();
173
174         jmp __enc_ret;
175
176 .align 8
177 .global blowfish_dec_blk
178 .type   blowfish_dec_blk,@function;
179
180 blowfish_dec_blk:
181         // input:
182         //      %rdi: ctx, CTX
183         //      %rsi: dst
184         //      %rdx: src
185         pushq %rbp;
186         pushq %rbx;
187
188         pushq %rsi;
189         movq %rdx, RIO;
190
191         read_block();
192
193         round_dec(17);
194         round_dec(15);
195         round_dec(13);
196         round_dec(11);
197         round_dec(9);
198         round_dec(7);
199         round_dec(5);
200         round_dec(3);
201         add_roundkey_dec(1);
202
203         popq RIO;
204         write_block();
205
206         popq %rbx;
207         popq %rbp;
208
209         ret;
210
211 /**********************************************************************
212   4-way blowfish, four blocks parallel
213  **********************************************************************/
214 #define add_preloaded_roundkey4() \
215         xorq RKEY,              RX0; \
216         xorq RKEY,              RX1; \
217         xorq RKEY,              RX2; \
218         xorq RKEY,              RX3;
219
220 #define preload_roundkey_enc(n) \
221         movq p+4*(n)(CTX),      RKEY;
222
223 #define add_roundkey_enc4(n) \
224         add_preloaded_roundkey4(); \
225         preload_roundkey_enc(n + 2);
226
227 #define round_enc4(n) \
228         add_roundkey_enc4(n); \
229         \
230         F(RX0, RK0); \
231         F(RX1, RK1); \
232         F(RX2, RK2); \
233         F(RX3, RK3); \
234         \
235         F(RX0, RK0); \
236         F(RX1, RK1); \
237         F(RX2, RK2); \
238         F(RX3, RK3);
239
240 #define preload_roundkey_dec(n) \
241         movq p+4*((n)-1)(CTX),  RKEY; \
242         rorq $32,               RKEY;
243
244 #define add_roundkey_dec4(n) \
245         add_preloaded_roundkey4(); \
246         preload_roundkey_dec(n - 2);
247
248 #define round_dec4(n) \
249         add_roundkey_dec4(n); \
250         \
251         F(RX0, RK0); \
252         F(RX1, RK1); \
253         F(RX2, RK2); \
254         F(RX3, RK3); \
255         \
256         F(RX0, RK0); \
257         F(RX1, RK1); \
258         F(RX2, RK2); \
259         F(RX3, RK3);
260
261 #define read_block4() \
262         movq (RIO),             RX0; \
263         rorq $32,               RX0; \
264         bswapq                  RX0; \
265         \
266         movq 8(RIO),            RX1; \
267         rorq $32,               RX1; \
268         bswapq                  RX1; \
269         \
270         movq 16(RIO),           RX2; \
271         rorq $32,               RX2; \
272         bswapq                  RX2; \
273         \
274         movq 24(RIO),           RX3; \
275         rorq $32,               RX3; \
276         bswapq                  RX3;
277
278 #define write_block4() \
279         bswapq                  RX0; \
280         movq RX0,               (RIO); \
281         \
282         bswapq                  RX1; \
283         movq RX1,               8(RIO); \
284         \
285         bswapq                  RX2; \
286         movq RX2,               16(RIO); \
287         \
288         bswapq                  RX3; \
289         movq RX3,               24(RIO);
290
291 #define xor_block4() \
292         bswapq                  RX0; \
293         xorq RX0,               (RIO); \
294         \
295         bswapq                  RX1; \
296         xorq RX1,               8(RIO); \
297         \
298         bswapq                  RX2; \
299         xorq RX2,               16(RIO); \
300         \
301         bswapq                  RX3; \
302         xorq RX3,               24(RIO);
303
304 .align 8
305 .global __blowfish_enc_blk_4way
306 .type   __blowfish_enc_blk_4way,@function;
307
308 __blowfish_enc_blk_4way:
309         // input:
310         //      %rdi: ctx, CTX
311         //      %rsi: dst
312         //      %rdx: src
313         //      %rcx: bool xor
314         pushq %rbp;
315         pushq %rbx;
316         pushq RKEY;
317         preload_roundkey_enc(0);
318
319         pushq %rsi;
320         pushq %rcx;
321         movq %rdx, RIO;
322
323         read_block4();
324
325         round_enc4(0);
326         round_enc4(2);
327         round_enc4(4);
328         round_enc4(6);
329         round_enc4(8);
330         round_enc4(10);
331         round_enc4(12);
332         round_enc4(14);
333         add_preloaded_roundkey4();
334
335         popq %rbp;
336         popq RIO;
337
338         test %bpl, %bpl;
339         jnz __enc_xor4;
340
341         write_block4();
342
343 __enc_ret4:
344         popq RKEY;
345         popq %rbx;
346         popq %rbp;
347
348         ret;
349
350 __enc_xor4:
351         xor_block4();
352
353         jmp __enc_ret4;
354
355 .align 8
356 .global blowfish_dec_blk_4way
357 .type   blowfish_dec_blk_4way,@function;
358
359 blowfish_dec_blk_4way:
360         // input:
361         //      %rdi: ctx, CTX
362         //      %rsi: dst
363         //      %rdx: src
364         pushq %rbp;
365         pushq %rbx;
366         pushq RKEY;
367         preload_roundkey_dec(17);
368
369         pushq %rsi;
370         movq %rdx, RIO;
371
372         read_block4();
373
374         round_dec4(17);
375         round_dec4(15);
376         round_dec4(13);
377         round_dec4(11);
378         round_dec4(9);
379         round_dec4(7);
380         round_dec4(5);
381         round_dec4(3);
382         add_preloaded_roundkey4();
383
384         popq RIO;
385         write_block4();
386
387         popq RKEY;
388         popq %rbx;
389         popq %rbp;
390
391         ret;
392