Add ARMv8/CE acceleration for AES-XTS
[libgcrypt.git] / cipher / des-amd64.S
1 /* des-amd64.S  -  AMD64 assembly implementation of 3DES cipher
2  *
3  * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #ifdef __x86_64
22 #include <config.h>
23 #if defined(USE_DES) && (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
24     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
25
26 #include "asm-common-amd64.h"
27
28 .text
29
30 #define s1 0
31 #define s2 ((s1) + (64*8))
32 #define s3 ((s2) + (64*8))
33 #define s4 ((s3) + (64*8))
34 #define s5 ((s4) + (64*8))
35 #define s6 ((s5) + (64*8))
36 #define s7 ((s6) + (64*8))
37 #define s8 ((s7) + (64*8))
38
39 /* register macros */
40 #define CTX %rdi
41 #define SBOXES %rbp
42
43 #define RL0 %r8
44 #define RL1 %r9
45 #define RL2 %r10
46
47 #define RL0d %r8d
48 #define RL1d %r9d
49 #define RL2d %r10d
50
51 #define RR0 %r11
52 #define RR1 %r12
53 #define RR2 %r13
54
55 #define RR0d %r11d
56 #define RR1d %r12d
57 #define RR2d %r13d
58
59 #define RW0 %rax
60 #define RW1 %rbx
61 #define RW2 %rcx
62
63 #define RW0d %eax
64 #define RW1d %ebx
65 #define RW2d %ecx
66
67 #define RW0bl %al
68 #define RW1bl %bl
69 #define RW2bl %cl
70
71 #define RW0bh %ah
72 #define RW1bh %bh
73 #define RW2bh %ch
74
75 #define RT0 %r15
76 #define RT1 %rsi
77 #define RT2 %r14
78 #define RT3 %rdx
79
80 #define RT0d %r15d
81 #define RT1d %esi
82 #define RT2d %r14d
83 #define RT3d %edx
84
85 /***********************************************************************
86  * 1-way 3DES
87  ***********************************************************************/
88 #define do_permutation(a, b, offset, mask) \
89         movl a, RT0d; \
90         shrl $(offset), RT0d; \
91         xorl b, RT0d; \
92         andl $(mask), RT0d; \
93         xorl RT0d, b; \
94         shll $(offset), RT0d; \
95         xorl RT0d, a;
96
97 #define expand_to_64bits(val, mask) \
98         movl val##d, RT0d; \
99         rorl $4, RT0d; \
100         shlq $32, RT0; \
101         orq RT0, val; \
102         andq mask, val;
103
104 #define compress_to_64bits(val) \
105         movq val, RT0; \
106         shrq $32, RT0; \
107         roll $4, RT0d; \
108         orl RT0d, val##d;
109
110 #define initial_permutation(left, right) \
111         do_permutation(left##d, right##d,  4, 0x0f0f0f0f); \
112         do_permutation(left##d, right##d, 16, 0x0000ffff); \
113         do_permutation(right##d, left##d,  2, 0x33333333); \
114         do_permutation(right##d, left##d,  8, 0x00ff00ff); \
115         movabs $0x3f3f3f3f3f3f3f3f, RT3; \
116         movl left##d, RW0d; \
117         roll $1, right##d; \
118         xorl right##d, RW0d; \
119         andl $0xaaaaaaaa, RW0d; \
120         xorl RW0d, left##d; \
121         xorl RW0d, right##d; \
122         roll $1, left##d; \
123         expand_to_64bits(right, RT3); \
124         expand_to_64bits(left, RT3);
125
126 #define final_permutation(left, right) \
127         compress_to_64bits(right); \
128         compress_to_64bits(left); \
129         movl right##d, RW0d; \
130         rorl $1, left##d; \
131         xorl left##d, RW0d; \
132         andl $0xaaaaaaaa, RW0d; \
133         xorl RW0d, right##d; \
134         xorl RW0d, left##d; \
135         rorl $1, right##d; \
136         do_permutation(right##d, left##d,  8, 0x00ff00ff); \
137         do_permutation(right##d, left##d,  2, 0x33333333); \
138         do_permutation(left##d, right##d, 16, 0x0000ffff); \
139         do_permutation(left##d, right##d,  4, 0x0f0f0f0f);
140
141 #define round1(n, from, to, load_next_key) \
142         xorq from, RW0; \
143         \
144         movzbl RW0bl, RT0d; \
145         movzbl RW0bh, RT1d; \
146         shrq $16, RW0; \
147         movzbl RW0bl, RT2d; \
148         movzbl RW0bh, RT3d; \
149         shrq $16, RW0; \
150         movq s8(SBOXES, RT0, 8), RT0; \
151         xorq s6(SBOXES, RT1, 8), to; \
152         movzbl RW0bl, RL1d; \
153         movzbl RW0bh, RT1d; \
154         shrl $16, RW0d; \
155         xorq s4(SBOXES, RT2, 8), RT0; \
156         xorq s2(SBOXES, RT3, 8), to; \
157         movzbl RW0bl, RT2d; \
158         movzbl RW0bh, RT3d; \
159         xorq s7(SBOXES, RL1, 8), RT0; \
160         xorq s5(SBOXES, RT1, 8), to; \
161         xorq s3(SBOXES, RT2, 8), RT0; \
162         load_next_key(n, RW0); \
163         xorq RT0, to; \
164         xorq s1(SBOXES, RT3, 8), to; \
165
166 #define load_next_key(n, RWx) \
167         movq (((n) + 1) * 8)(CTX), RWx;
168
169 #define dummy2(a, b) /*_*/
170
171 #define read_block(io, left, right) \
172         movl    (io), left##d; \
173         movl   4(io), right##d; \
174         bswapl left##d; \
175         bswapl right##d;
176
177 #define write_block(io, left, right) \
178         bswapl left##d; \
179         bswapl right##d; \
180         movl   left##d,   (io); \
181         movl   right##d, 4(io);
182
183 .align 8
184 .globl _gcry_3des_amd64_crypt_block
185 ELF(.type  _gcry_3des_amd64_crypt_block,@function;)
186
187 _gcry_3des_amd64_crypt_block:
188         /* input:
189          *      %rdi: round keys, CTX
190          *      %rsi: dst
191          *      %rdx: src
192          */
193         ENTER_SYSV_FUNC_PARAMS_0_4
194
195         pushq %rbp;
196         pushq %rbx;
197         pushq %r12;
198         pushq %r13;
199         pushq %r14;
200         pushq %r15;
201         pushq %rsi; /*dst*/
202
203         leaq .L_s1 rRIP, SBOXES;
204
205         read_block(%rdx, RL0, RR0);
206         initial_permutation(RL0, RR0);
207
208         movq (CTX), RW0;
209
210         round1(0, RR0, RL0, load_next_key);
211         round1(1, RL0, RR0, load_next_key);
212         round1(2, RR0, RL0, load_next_key);
213         round1(3, RL0, RR0, load_next_key);
214         round1(4, RR0, RL0, load_next_key);
215         round1(5, RL0, RR0, load_next_key);
216         round1(6, RR0, RL0, load_next_key);
217         round1(7, RL0, RR0, load_next_key);
218         round1(8, RR0, RL0, load_next_key);
219         round1(9, RL0, RR0, load_next_key);
220         round1(10, RR0, RL0, load_next_key);
221         round1(11, RL0, RR0, load_next_key);
222         round1(12, RR0, RL0, load_next_key);
223         round1(13, RL0, RR0, load_next_key);
224         round1(14, RR0, RL0, load_next_key);
225         round1(15, RL0, RR0, load_next_key);
226
227         round1(16+0, RL0, RR0, load_next_key);
228         round1(16+1, RR0, RL0, load_next_key);
229         round1(16+2, RL0, RR0, load_next_key);
230         round1(16+3, RR0, RL0, load_next_key);
231         round1(16+4, RL0, RR0, load_next_key);
232         round1(16+5, RR0, RL0, load_next_key);
233         round1(16+6, RL0, RR0, load_next_key);
234         round1(16+7, RR0, RL0, load_next_key);
235         round1(16+8, RL0, RR0, load_next_key);
236         round1(16+9, RR0, RL0, load_next_key);
237         round1(16+10, RL0, RR0, load_next_key);
238         round1(16+11, RR0, RL0, load_next_key);
239         round1(16+12, RL0, RR0, load_next_key);
240         round1(16+13, RR0, RL0, load_next_key);
241         round1(16+14, RL0, RR0, load_next_key);
242         round1(16+15, RR0, RL0, load_next_key);
243
244         round1(32+0, RR0, RL0, load_next_key);
245         round1(32+1, RL0, RR0, load_next_key);
246         round1(32+2, RR0, RL0, load_next_key);
247         round1(32+3, RL0, RR0, load_next_key);
248         round1(32+4, RR0, RL0, load_next_key);
249         round1(32+5, RL0, RR0, load_next_key);
250         round1(32+6, RR0, RL0, load_next_key);
251         round1(32+7, RL0, RR0, load_next_key);
252         round1(32+8, RR0, RL0, load_next_key);
253         round1(32+9, RL0, RR0, load_next_key);
254         round1(32+10, RR0, RL0, load_next_key);
255         round1(32+11, RL0, RR0, load_next_key);
256         round1(32+12, RR0, RL0, load_next_key);
257         round1(32+13, RL0, RR0, load_next_key);
258         round1(32+14, RR0, RL0, load_next_key);
259         round1(32+15, RL0, RR0, dummy2);
260
261         popq RW2; /*dst*/
262         final_permutation(RR0, RL0);
263         write_block(RW2, RR0, RL0);
264
265         popq %r15;
266         popq %r14;
267         popq %r13;
268         popq %r12;
269         popq %rbx;
270         popq %rbp;
271
272         EXIT_SYSV_FUNC
273         ret;
274 ELF(.size _gcry_3des_amd64_crypt_block,.-_gcry_3des_amd64_crypt_block;)
275
276 /***********************************************************************
277  * 3-way 3DES
278  ***********************************************************************/
279 #define expand_to_64bits(val, mask) \
280         movl val##d, RT0d; \
281         rorl $4, RT0d; \
282         shlq $32, RT0; \
283         orq RT0, val; \
284         andq mask, val;
285
286 #define compress_to_64bits(val) \
287         movq val, RT0; \
288         shrq $32, RT0; \
289         roll $4, RT0d; \
290         orl RT0d, val##d;
291
292 #define initial_permutation3(left, right) \
293         do_permutation(left##0d, right##0d,  4, 0x0f0f0f0f); \
294         do_permutation(left##0d, right##0d, 16, 0x0000ffff); \
295           do_permutation(left##1d, right##1d,  4, 0x0f0f0f0f); \
296           do_permutation(left##1d, right##1d, 16, 0x0000ffff); \
297             do_permutation(left##2d, right##2d,  4, 0x0f0f0f0f); \
298             do_permutation(left##2d, right##2d, 16, 0x0000ffff); \
299             \
300         do_permutation(right##0d, left##0d,  2, 0x33333333); \
301         do_permutation(right##0d, left##0d,  8, 0x00ff00ff); \
302           do_permutation(right##1d, left##1d,  2, 0x33333333); \
303           do_permutation(right##1d, left##1d,  8, 0x00ff00ff); \
304             do_permutation(right##2d, left##2d,  2, 0x33333333); \
305             do_permutation(right##2d, left##2d,  8, 0x00ff00ff); \
306             \
307         movabs $0x3f3f3f3f3f3f3f3f, RT3; \
308             \
309         movl left##0d, RW0d; \
310         roll $1, right##0d; \
311         xorl right##0d, RW0d; \
312         andl $0xaaaaaaaa, RW0d; \
313         xorl RW0d, left##0d; \
314         xorl RW0d, right##0d; \
315         roll $1, left##0d; \
316         expand_to_64bits(right##0, RT3); \
317         expand_to_64bits(left##0, RT3); \
318           movl left##1d, RW1d; \
319           roll $1, right##1d; \
320           xorl right##1d, RW1d; \
321           andl $0xaaaaaaaa, RW1d; \
322           xorl RW1d, left##1d; \
323           xorl RW1d, right##1d; \
324           roll $1, left##1d; \
325           expand_to_64bits(right##1, RT3); \
326           expand_to_64bits(left##1, RT3); \
327             movl left##2d, RW2d; \
328             roll $1, right##2d; \
329             xorl right##2d, RW2d; \
330             andl $0xaaaaaaaa, RW2d; \
331             xorl RW2d, left##2d; \
332             xorl RW2d, right##2d; \
333             roll $1, left##2d; \
334             expand_to_64bits(right##2, RT3); \
335             expand_to_64bits(left##2, RT3);
336
337 #define final_permutation3(left, right) \
338         compress_to_64bits(right##0); \
339         compress_to_64bits(left##0); \
340         movl right##0d, RW0d; \
341         rorl $1, left##0d; \
342         xorl left##0d, RW0d; \
343         andl $0xaaaaaaaa, RW0d; \
344         xorl RW0d, right##0d; \
345         xorl RW0d, left##0d; \
346         rorl $1, right##0d; \
347           compress_to_64bits(right##1); \
348           compress_to_64bits(left##1); \
349           movl right##1d, RW1d; \
350           rorl $1, left##1d; \
351           xorl left##1d, RW1d; \
352           andl $0xaaaaaaaa, RW1d; \
353           xorl RW1d, right##1d; \
354           xorl RW1d, left##1d; \
355           rorl $1, right##1d; \
356             compress_to_64bits(right##2); \
357             compress_to_64bits(left##2); \
358             movl right##2d, RW2d; \
359             rorl $1, left##2d; \
360             xorl left##2d, RW2d; \
361             andl $0xaaaaaaaa, RW2d; \
362             xorl RW2d, right##2d; \
363             xorl RW2d, left##2d; \
364             rorl $1, right##2d; \
365             \
366         do_permutation(right##0d, left##0d,  8, 0x00ff00ff); \
367         do_permutation(right##0d, left##0d,  2, 0x33333333); \
368           do_permutation(right##1d, left##1d,  8, 0x00ff00ff); \
369           do_permutation(right##1d, left##1d,  2, 0x33333333); \
370             do_permutation(right##2d, left##2d,  8, 0x00ff00ff); \
371             do_permutation(right##2d, left##2d,  2, 0x33333333); \
372             \
373         do_permutation(left##0d, right##0d, 16, 0x0000ffff); \
374         do_permutation(left##0d, right##0d,  4, 0x0f0f0f0f); \
375           do_permutation(left##1d, right##1d, 16, 0x0000ffff); \
376           do_permutation(left##1d, right##1d,  4, 0x0f0f0f0f); \
377             do_permutation(left##2d, right##2d, 16, 0x0000ffff); \
378             do_permutation(left##2d, right##2d,  4, 0x0f0f0f0f);
379
380 #define round3(n, from, to, load_next_key, do_movq) \
381         xorq from##0, RW0; \
382         movzbl RW0bl, RT3d; \
383         movzbl RW0bh, RT1d; \
384         shrq $16, RW0; \
385         xorq s8(SBOXES, RT3, 8), to##0; \
386         xorq s6(SBOXES, RT1, 8), to##0; \
387         movzbl RW0bl, RT3d; \
388         movzbl RW0bh, RT1d; \
389         shrq $16, RW0; \
390         xorq s4(SBOXES, RT3, 8), to##0; \
391         xorq s2(SBOXES, RT1, 8), to##0; \
392         movzbl RW0bl, RT3d; \
393         movzbl RW0bh, RT1d; \
394         shrl $16, RW0d; \
395         xorq s7(SBOXES, RT3, 8), to##0; \
396         xorq s5(SBOXES, RT1, 8), to##0; \
397         movzbl RW0bl, RT3d; \
398         movzbl RW0bh, RT1d; \
399         load_next_key(n, RW0); \
400         xorq s3(SBOXES, RT3, 8), to##0; \
401         xorq s1(SBOXES, RT1, 8), to##0; \
402                 xorq from##1, RW1; \
403                 movzbl RW1bl, RT3d; \
404                 movzbl RW1bh, RT1d; \
405                 shrq $16, RW1; \
406                 xorq s8(SBOXES, RT3, 8), to##1; \
407                 xorq s6(SBOXES, RT1, 8), to##1; \
408                 movzbl RW1bl, RT3d; \
409                 movzbl RW1bh, RT1d; \
410                 shrq $16, RW1; \
411                 xorq s4(SBOXES, RT3, 8), to##1; \
412                 xorq s2(SBOXES, RT1, 8), to##1; \
413                 movzbl RW1bl, RT3d; \
414                 movzbl RW1bh, RT1d; \
415                 shrl $16, RW1d; \
416                 xorq s7(SBOXES, RT3, 8), to##1; \
417                 xorq s5(SBOXES, RT1, 8), to##1; \
418                 movzbl RW1bl, RT3d; \
419                 movzbl RW1bh, RT1d; \
420                 do_movq(RW0, RW1); \
421                 xorq s3(SBOXES, RT3, 8), to##1; \
422                 xorq s1(SBOXES, RT1, 8), to##1; \
423                         xorq from##2, RW2; \
424                         movzbl RW2bl, RT3d; \
425                         movzbl RW2bh, RT1d; \
426                         shrq $16, RW2; \
427                         xorq s8(SBOXES, RT3, 8), to##2; \
428                         xorq s6(SBOXES, RT1, 8), to##2; \
429                         movzbl RW2bl, RT3d; \
430                         movzbl RW2bh, RT1d; \
431                         shrq $16, RW2; \
432                         xorq s4(SBOXES, RT3, 8), to##2; \
433                         xorq s2(SBOXES, RT1, 8), to##2; \
434                         movzbl RW2bl, RT3d; \
435                         movzbl RW2bh, RT1d; \
436                         shrl $16, RW2d; \
437                         xorq s7(SBOXES, RT3, 8), to##2; \
438                         xorq s5(SBOXES, RT1, 8), to##2; \
439                         movzbl RW2bl, RT3d; \
440                         movzbl RW2bh, RT1d; \
441                         do_movq(RW0, RW2); \
442                         xorq s3(SBOXES, RT3, 8), to##2; \
443                         xorq s1(SBOXES, RT1, 8), to##2;
444
445 #define __movq(src, dst) \
446         movq src, dst;
447
448 #define read_block(io, left, right) \
449         movl    (io), left##d; \
450         movl   4(io), right##d; \
451         bswapl left##d; \
452         bswapl right##d;
453
454 #define write_block(io, left, right) \
455         bswapl left##d; \
456         bswapl right##d; \
457         movl   left##d,   (io); \
458         movl   right##d, 4(io);
459
460 .align 8
461 ELF(.type  _gcry_3des_amd64_crypt_blk3,@function;)
462 _gcry_3des_amd64_crypt_blk3:
463         /* input:
464          *  %rdi: round keys, CTX
465          *  RL0d, RR0d, RL1d, RR1d, RL2d, RR2d: 3 input blocks
466          *  RR0d, RL0d, RR1d, RL1d, RR2d, RL2d: 3 output blocks
467          */
468
469         leaq .L_s1 rRIP, SBOXES;
470
471         initial_permutation3(RL, RR);
472
473         movq 0(CTX), RW0;
474         movq RW0, RW1;
475         movq RW0, RW2;
476
477         round3(0, RR, RL, load_next_key, __movq);
478         round3(1, RL, RR, load_next_key, __movq);
479         round3(2, RR, RL, load_next_key, __movq);
480         round3(3, RL, RR, load_next_key, __movq);
481         round3(4, RR, RL, load_next_key, __movq);
482         round3(5, RL, RR, load_next_key, __movq);
483         round3(6, RR, RL, load_next_key, __movq);
484         round3(7, RL, RR, load_next_key, __movq);
485         round3(8, RR, RL, load_next_key, __movq);
486         round3(9, RL, RR, load_next_key, __movq);
487         round3(10, RR, RL, load_next_key, __movq);
488         round3(11, RL, RR, load_next_key, __movq);
489         round3(12, RR, RL, load_next_key, __movq);
490         round3(13, RL, RR, load_next_key, __movq);
491         round3(14, RR, RL, load_next_key, __movq);
492         round3(15, RL, RR, load_next_key, __movq);
493
494         round3(16+0, RL, RR, load_next_key, __movq);
495         round3(16+1, RR, RL, load_next_key, __movq);
496         round3(16+2, RL, RR, load_next_key, __movq);
497         round3(16+3, RR, RL, load_next_key, __movq);
498         round3(16+4, RL, RR, load_next_key, __movq);
499         round3(16+5, RR, RL, load_next_key, __movq);
500         round3(16+6, RL, RR, load_next_key, __movq);
501         round3(16+7, RR, RL, load_next_key, __movq);
502         round3(16+8, RL, RR, load_next_key, __movq);
503         round3(16+9, RR, RL, load_next_key, __movq);
504         round3(16+10, RL, RR, load_next_key, __movq);
505         round3(16+11, RR, RL, load_next_key, __movq);
506         round3(16+12, RL, RR, load_next_key, __movq);
507         round3(16+13, RR, RL, load_next_key, __movq);
508         round3(16+14, RL, RR, load_next_key, __movq);
509         round3(16+15, RR, RL, load_next_key, __movq);
510
511         round3(32+0, RR, RL, load_next_key, __movq);
512         round3(32+1, RL, RR, load_next_key, __movq);
513         round3(32+2, RR, RL, load_next_key, __movq);
514         round3(32+3, RL, RR, load_next_key, __movq);
515         round3(32+4, RR, RL, load_next_key, __movq);
516         round3(32+5, RL, RR, load_next_key, __movq);
517         round3(32+6, RR, RL, load_next_key, __movq);
518         round3(32+7, RL, RR, load_next_key, __movq);
519         round3(32+8, RR, RL, load_next_key, __movq);
520         round3(32+9, RL, RR, load_next_key, __movq);
521         round3(32+10, RR, RL, load_next_key, __movq);
522         round3(32+11, RL, RR, load_next_key, __movq);
523         round3(32+12, RR, RL, load_next_key, __movq);
524         round3(32+13, RL, RR, load_next_key, __movq);
525         round3(32+14, RR, RL, load_next_key, __movq);
526         round3(32+15, RL, RR, dummy2, dummy2);
527
528         final_permutation3(RR, RL);
529
530         ret;
531 ELF(.size _gcry_3des_amd64_crypt_blk3,.-_gcry_3des_amd64_crypt_blk3;)
532
533 .align 8
534 .globl  _gcry_3des_amd64_cbc_dec
535 ELF(.type   _gcry_3des_amd64_cbc_dec,@function;)
536 _gcry_3des_amd64_cbc_dec:
537         /* input:
538          *      %rdi: ctx, CTX
539          *      %rsi: dst (3 blocks)
540          *      %rdx: src (3 blocks)
541          *      %rcx: iv (64bit)
542          */
543         ENTER_SYSV_FUNC_PARAMS_0_4
544
545         pushq %rbp;
546         pushq %rbx;
547         pushq %r12;
548         pushq %r13;
549         pushq %r14;
550         pushq %r15;
551
552         pushq %rsi; /*dst*/
553         pushq %rdx; /*src*/
554         pushq %rcx; /*iv*/
555
556         /* load input */
557         movl 0 * 4(%rdx), RL0d;
558         movl 1 * 4(%rdx), RR0d;
559         movl 2 * 4(%rdx), RL1d;
560         movl 3 * 4(%rdx), RR1d;
561         movl 4 * 4(%rdx), RL2d;
562         movl 5 * 4(%rdx), RR2d;
563
564         bswapl RL0d;
565         bswapl RR0d;
566         bswapl RL1d;
567         bswapl RR1d;
568         bswapl RL2d;
569         bswapl RR2d;
570
571         call _gcry_3des_amd64_crypt_blk3;
572
573         popq %rcx; /*iv*/
574         popq %rdx; /*src*/
575         popq %rsi; /*dst*/
576
577         bswapl RR0d;
578         bswapl RL0d;
579         bswapl RR1d;
580         bswapl RL1d;
581         bswapl RR2d;
582         bswapl RL2d;
583
584         movq 2 * 8(%rdx), RT0;
585         xorl 0 * 4(%rcx), RR0d;
586         xorl 1 * 4(%rcx), RL0d;
587         xorl 0 * 4(%rdx), RR1d;
588         xorl 1 * 4(%rdx), RL1d;
589         xorl 2 * 4(%rdx), RR2d;
590         xorl 3 * 4(%rdx), RL2d;
591         movq RT0, (%rcx); /* store new IV */
592
593         movl RR0d, 0 * 4(%rsi);
594         movl RL0d, 1 * 4(%rsi);
595         movl RR1d, 2 * 4(%rsi);
596         movl RL1d, 3 * 4(%rsi);
597         movl RR2d, 4 * 4(%rsi);
598         movl RL2d, 5 * 4(%rsi);
599
600         popq %r15;
601         popq %r14;
602         popq %r13;
603         popq %r12;
604         popq %rbx;
605         popq %rbp;
606
607         EXIT_SYSV_FUNC
608         ret;
609 ELF(.size _gcry_3des_amd64_cbc_dec,.-_gcry_3des_amd64_cbc_dec;)
610
611 .align 8
612 .globl  _gcry_3des_amd64_ctr_enc
613 ELF(.type   _gcry_3des_amd64_ctr_enc,@function;)
614 _gcry_3des_amd64_ctr_enc:
615         /* input:
616          *      %rdi: ctx, CTX
617          *      %rsi: dst (3 blocks)
618          *      %rdx: src (3 blocks)
619          *      %rcx: iv (64bit)
620          */
621         ENTER_SYSV_FUNC_PARAMS_0_4
622
623         pushq %rbp;
624         pushq %rbx;
625         pushq %r12;
626         pushq %r13;
627         pushq %r14;
628         pushq %r15;
629
630         pushq %rsi; /*dst*/
631         pushq %rdx; /*src*/
632         movq %rcx, RW2;
633
634         /* load IV and byteswap */
635         movq (RW2), RT0;
636         bswapq RT0;
637         movq RT0, RR0;
638
639         /* construct IVs */
640         leaq 1(RT0), RR1;
641         leaq 2(RT0), RR2;
642         leaq 3(RT0), RT0;
643         movq RR0, RL0;
644         movq RR1, RL1;
645         movq RR2, RL2;
646         bswapq RT0;
647         shrq $32, RL0;
648         shrq $32, RL1;
649         shrq $32, RL2;
650
651         /* store new IV */
652         movq RT0, (RW2);
653
654         call _gcry_3des_amd64_crypt_blk3;
655
656         popq %rdx; /*src*/
657         popq %rsi; /*dst*/
658
659         bswapl RR0d;
660         bswapl RL0d;
661         bswapl RR1d;
662         bswapl RL1d;
663         bswapl RR2d;
664         bswapl RL2d;
665
666         xorl 0 * 4(%rdx), RR0d;
667         xorl 1 * 4(%rdx), RL0d;
668         xorl 2 * 4(%rdx), RR1d;
669         xorl 3 * 4(%rdx), RL1d;
670         xorl 4 * 4(%rdx), RR2d;
671         xorl 5 * 4(%rdx), RL2d;
672
673         movl RR0d, 0 * 4(%rsi);
674         movl RL0d, 1 * 4(%rsi);
675         movl RR1d, 2 * 4(%rsi);
676         movl RL1d, 3 * 4(%rsi);
677         movl RR2d, 4 * 4(%rsi);
678         movl RL2d, 5 * 4(%rsi);
679
680         popq %r15;
681         popq %r14;
682         popq %r13;
683         popq %r12;
684         popq %rbx;
685         popq %rbp;
686
687         EXIT_SYSV_FUNC
688         ret;
689 ELF(.size _gcry_3des_amd64_cbc_dec,.-_gcry_3des_amd64_cbc_dec;)
690
691 .align 8
692 .globl  _gcry_3des_amd64_cfb_dec
693 ELF(.type   _gcry_3des_amd64_cfb_dec,@function;)
694 _gcry_3des_amd64_cfb_dec:
695         /* input:
696          *      %rdi: ctx, CTX
697          *      %rsi: dst (3 blocks)
698          *      %rdx: src (3 blocks)
699          *      %rcx: iv (64bit)
700          */
701         ENTER_SYSV_FUNC_PARAMS_0_4
702
703         pushq %rbp;
704         pushq %rbx;
705         pushq %r12;
706         pushq %r13;
707         pushq %r14;
708         pushq %r15;
709
710         pushq %rsi; /*dst*/
711         pushq %rdx; /*src*/
712         movq %rcx, RW2;
713
714         /* Load input */
715         movl 0 * 4(RW2), RL0d;
716         movl 1 * 4(RW2), RR0d;
717         movl 0 * 4(%rdx), RL1d;
718         movl 1 * 4(%rdx), RR1d;
719         movl 2 * 4(%rdx), RL2d;
720         movl 3 * 4(%rdx), RR2d;
721
722         bswapl RL0d;
723         bswapl RR0d;
724         bswapl RL1d;
725         bswapl RR1d;
726         bswapl RL2d;
727         bswapl RR2d;
728
729         /* Update IV */
730         movq 4 * 4(%rdx), RW0;
731         movq RW0, (RW2);
732
733         call _gcry_3des_amd64_crypt_blk3;
734
735         popq %rdx; /*src*/
736         popq %rsi; /*dst*/
737
738         bswapl RR0d;
739         bswapl RL0d;
740         bswapl RR1d;
741         bswapl RL1d;
742         bswapl RR2d;
743         bswapl RL2d;
744
745         xorl 0 * 4(%rdx), RR0d;
746         xorl 1 * 4(%rdx), RL0d;
747         xorl 2 * 4(%rdx), RR1d;
748         xorl 3 * 4(%rdx), RL1d;
749         xorl 4 * 4(%rdx), RR2d;
750         xorl 5 * 4(%rdx), RL2d;
751
752         movl RR0d, 0 * 4(%rsi);
753         movl RL0d, 1 * 4(%rsi);
754         movl RR1d, 2 * 4(%rsi);
755         movl RL1d, 3 * 4(%rsi);
756         movl RR2d, 4 * 4(%rsi);
757         movl RL2d, 5 * 4(%rsi);
758
759         popq %r15;
760         popq %r14;
761         popq %r13;
762         popq %r12;
763         popq %rbx;
764         popq %rbp;
765
766         EXIT_SYSV_FUNC
767         ret;
768 ELF(.size _gcry_3des_amd64_cfb_dec,.-_gcry_3des_amd64_cfb_dec;)
769
770 .align 16
771 .L_s1:
772         .quad 0x0010100001010400, 0x0000000000000000
773         .quad 0x0000100000010000, 0x0010100001010404
774         .quad 0x0010100001010004, 0x0000100000010404
775         .quad 0x0000000000000004, 0x0000100000010000
776         .quad 0x0000000000000400, 0x0010100001010400
777         .quad 0x0010100001010404, 0x0000000000000400
778         .quad 0x0010000001000404, 0x0010100001010004
779         .quad 0x0010000001000000, 0x0000000000000004
780         .quad 0x0000000000000404, 0x0010000001000400
781         .quad 0x0010000001000400, 0x0000100000010400
782         .quad 0x0000100000010400, 0x0010100001010000
783         .quad 0x0010100001010000, 0x0010000001000404
784         .quad 0x0000100000010004, 0x0010000001000004
785         .quad 0x0010000001000004, 0x0000100000010004
786         .quad 0x0000000000000000, 0x0000000000000404
787         .quad 0x0000100000010404, 0x0010000001000000
788         .quad 0x0000100000010000, 0x0010100001010404
789         .quad 0x0000000000000004, 0x0010100001010000
790         .quad 0x0010100001010400, 0x0010000001000000
791         .quad 0x0010000001000000, 0x0000000000000400
792         .quad 0x0010100001010004, 0x0000100000010000
793         .quad 0x0000100000010400, 0x0010000001000004
794         .quad 0x0000000000000400, 0x0000000000000004
795         .quad 0x0010000001000404, 0x0000100000010404
796         .quad 0x0010100001010404, 0x0000100000010004
797         .quad 0x0010100001010000, 0x0010000001000404
798         .quad 0x0010000001000004, 0x0000000000000404
799         .quad 0x0000100000010404, 0x0010100001010400
800         .quad 0x0000000000000404, 0x0010000001000400
801         .quad 0x0010000001000400, 0x0000000000000000
802         .quad 0x0000100000010004, 0x0000100000010400
803         .quad 0x0000000000000000, 0x0010100001010004
804 .L_s2:
805         .quad 0x0801080200100020, 0x0800080000000000
806         .quad 0x0000080000000000, 0x0001080200100020
807         .quad 0x0001000000100000, 0x0000000200000020
808         .quad 0x0801000200100020, 0x0800080200000020
809         .quad 0x0800000200000020, 0x0801080200100020
810         .quad 0x0801080000100000, 0x0800000000000000
811         .quad 0x0800080000000000, 0x0001000000100000
812         .quad 0x0000000200000020, 0x0801000200100020
813         .quad 0x0001080000100000, 0x0001000200100020
814         .quad 0x0800080200000020, 0x0000000000000000
815         .quad 0x0800000000000000, 0x0000080000000000
816         .quad 0x0001080200100020, 0x0801000000100000
817         .quad 0x0001000200100020, 0x0800000200000020
818         .quad 0x0000000000000000, 0x0001080000100000
819         .quad 0x0000080200000020, 0x0801080000100000
820         .quad 0x0801000000100000, 0x0000080200000020
821         .quad 0x0000000000000000, 0x0001080200100020
822         .quad 0x0801000200100020, 0x0001000000100000
823         .quad 0x0800080200000020, 0x0801000000100000
824         .quad 0x0801080000100000, 0x0000080000000000
825         .quad 0x0801000000100000, 0x0800080000000000
826         .quad 0x0000000200000020, 0x0801080200100020
827         .quad 0x0001080200100020, 0x0000000200000020
828         .quad 0x0000080000000000, 0x0800000000000000
829         .quad 0x0000080200000020, 0x0801080000100000
830         .quad 0x0001000000100000, 0x0800000200000020
831         .quad 0x0001000200100020, 0x0800080200000020
832         .quad 0x0800000200000020, 0x0001000200100020
833         .quad 0x0001080000100000, 0x0000000000000000
834         .quad 0x0800080000000000, 0x0000080200000020
835         .quad 0x0800000000000000, 0x0801000200100020
836         .quad 0x0801080200100020, 0x0001080000100000
837 .L_s3:
838         .quad 0x0000002000000208, 0x0000202008020200
839         .quad 0x0000000000000000, 0x0000200008020008
840         .quad 0x0000002008000200, 0x0000000000000000
841         .quad 0x0000202000020208, 0x0000002008000200
842         .quad 0x0000200000020008, 0x0000000008000008
843         .quad 0x0000000008000008, 0x0000200000020000
844         .quad 0x0000202008020208, 0x0000200000020008
845         .quad 0x0000200008020000, 0x0000002000000208
846         .quad 0x0000000008000000, 0x0000000000000008
847         .quad 0x0000202008020200, 0x0000002000000200
848         .quad 0x0000202000020200, 0x0000200008020000
849         .quad 0x0000200008020008, 0x0000202000020208
850         .quad 0x0000002008000208, 0x0000202000020200
851         .quad 0x0000200000020000, 0x0000002008000208
852         .quad 0x0000000000000008, 0x0000202008020208
853         .quad 0x0000002000000200, 0x0000000008000000
854         .quad 0x0000202008020200, 0x0000000008000000
855         .quad 0x0000200000020008, 0x0000002000000208
856         .quad 0x0000200000020000, 0x0000202008020200
857         .quad 0x0000002008000200, 0x0000000000000000
858         .quad 0x0000002000000200, 0x0000200000020008
859         .quad 0x0000202008020208, 0x0000002008000200
860         .quad 0x0000000008000008, 0x0000002000000200
861         .quad 0x0000000000000000, 0x0000200008020008
862         .quad 0x0000002008000208, 0x0000200000020000
863         .quad 0x0000000008000000, 0x0000202008020208
864         .quad 0x0000000000000008, 0x0000202000020208
865         .quad 0x0000202000020200, 0x0000000008000008
866         .quad 0x0000200008020000, 0x0000002008000208
867         .quad 0x0000002000000208, 0x0000200008020000
868         .quad 0x0000202000020208, 0x0000000000000008
869         .quad 0x0000200008020008, 0x0000202000020200
870 .L_s4:
871         .quad 0x1008020000002001, 0x1000020800002001
872         .quad 0x1000020800002001, 0x0000000800000000
873         .quad 0x0008020800002000, 0x1008000800000001
874         .quad 0x1008000000000001, 0x1000020000002001
875         .quad 0x0000000000000000, 0x0008020000002000
876         .quad 0x0008020000002000, 0x1008020800002001
877         .quad 0x1000000800000001, 0x0000000000000000
878         .quad 0x0008000800000000, 0x1008000000000001
879         .quad 0x1000000000000001, 0x0000020000002000
880         .quad 0x0008000000000000, 0x1008020000002001
881         .quad 0x0000000800000000, 0x0008000000000000
882         .quad 0x1000020000002001, 0x0000020800002000
883         .quad 0x1008000800000001, 0x1000000000000001
884         .quad 0x0000020800002000, 0x0008000800000000
885         .quad 0x0000020000002000, 0x0008020800002000
886         .quad 0x1008020800002001, 0x1000000800000001
887         .quad 0x0008000800000000, 0x1008000000000001
888         .quad 0x0008020000002000, 0x1008020800002001
889         .quad 0x1000000800000001, 0x0000000000000000
890         .quad 0x0000000000000000, 0x0008020000002000
891         .quad 0x0000020800002000, 0x0008000800000000
892         .quad 0x1008000800000001, 0x1000000000000001
893         .quad 0x1008020000002001, 0x1000020800002001
894         .quad 0x1000020800002001, 0x0000000800000000
895         .quad 0x1008020800002001, 0x1000000800000001
896         .quad 0x1000000000000001, 0x0000020000002000
897         .quad 0x1008000000000001, 0x1000020000002001
898         .quad 0x0008020800002000, 0x1008000800000001
899         .quad 0x1000020000002001, 0x0000020800002000
900         .quad 0x0008000000000000, 0x1008020000002001
901         .quad 0x0000000800000000, 0x0008000000000000
902         .quad 0x0000020000002000, 0x0008020800002000
903 .L_s5:
904         .quad 0x0000001000000100, 0x0020001002080100
905         .quad 0x0020000002080000, 0x0420001002000100
906         .quad 0x0000000000080000, 0x0000001000000100
907         .quad 0x0400000000000000, 0x0020000002080000
908         .quad 0x0400001000080100, 0x0000000000080000
909         .quad 0x0020001002000100, 0x0400001000080100
910         .quad 0x0420001002000100, 0x0420000002080000
911         .quad 0x0000001000080100, 0x0400000000000000
912         .quad 0x0020000002000000, 0x0400000000080000
913         .quad 0x0400000000080000, 0x0000000000000000
914         .quad 0x0400001000000100, 0x0420001002080100
915         .quad 0x0420001002080100, 0x0020001002000100
916         .quad 0x0420000002080000, 0x0400001000000100
917         .quad 0x0000000000000000, 0x0420000002000000
918         .quad 0x0020001002080100, 0x0020000002000000
919         .quad 0x0420000002000000, 0x0000001000080100
920         .quad 0x0000000000080000, 0x0420001002000100
921         .quad 0x0000001000000100, 0x0020000002000000
922         .quad 0x0400000000000000, 0x0020000002080000
923         .quad 0x0420001002000100, 0x0400001000080100
924         .quad 0x0020001002000100, 0x0400000000000000
925         .quad 0x0420000002080000, 0x0020001002080100
926         .quad 0x0400001000080100, 0x0000001000000100
927         .quad 0x0020000002000000, 0x0420000002080000
928         .quad 0x0420001002080100, 0x0000001000080100
929         .quad 0x0420000002000000, 0x0420001002080100
930         .quad 0x0020000002080000, 0x0000000000000000
931         .quad 0x0400000000080000, 0x0420000002000000
932         .quad 0x0000001000080100, 0x0020001002000100
933         .quad 0x0400001000000100, 0x0000000000080000
934         .quad 0x0000000000000000, 0x0400000000080000
935         .quad 0x0020001002080100, 0x0400001000000100
936 .L_s6:
937         .quad 0x0200000120000010, 0x0204000020000000
938         .quad 0x0000040000000000, 0x0204040120000010
939         .quad 0x0204000020000000, 0x0000000100000010
940         .quad 0x0204040120000010, 0x0004000000000000
941         .quad 0x0200040020000000, 0x0004040100000010
942         .quad 0x0004000000000000, 0x0200000120000010
943         .quad 0x0004000100000010, 0x0200040020000000
944         .quad 0x0200000020000000, 0x0000040100000010
945         .quad 0x0000000000000000, 0x0004000100000010
946         .quad 0x0200040120000010, 0x0000040000000000
947         .quad 0x0004040000000000, 0x0200040120000010
948         .quad 0x0000000100000010, 0x0204000120000010
949         .quad 0x0204000120000010, 0x0000000000000000
950         .quad 0x0004040100000010, 0x0204040020000000
951         .quad 0x0000040100000010, 0x0004040000000000
952         .quad 0x0204040020000000, 0x0200000020000000
953         .quad 0x0200040020000000, 0x0000000100000010
954         .quad 0x0204000120000010, 0x0004040000000000
955         .quad 0x0204040120000010, 0x0004000000000000
956         .quad 0x0000040100000010, 0x0200000120000010
957         .quad 0x0004000000000000, 0x0200040020000000
958         .quad 0x0200000020000000, 0x0000040100000010
959         .quad 0x0200000120000010, 0x0204040120000010
960         .quad 0x0004040000000000, 0x0204000020000000
961         .quad 0x0004040100000010, 0x0204040020000000
962         .quad 0x0000000000000000, 0x0204000120000010
963         .quad 0x0000000100000010, 0x0000040000000000
964         .quad 0x0204000020000000, 0x0004040100000010
965         .quad 0x0000040000000000, 0x0004000100000010
966         .quad 0x0200040120000010, 0x0000000000000000
967         .quad 0x0204040020000000, 0x0200000020000000
968         .quad 0x0004000100000010, 0x0200040120000010
969 .L_s7:
970         .quad 0x0002000000200000, 0x2002000004200002
971         .quad 0x2000000004000802, 0x0000000000000000
972         .quad 0x0000000000000800, 0x2000000004000802
973         .quad 0x2002000000200802, 0x0002000004200800
974         .quad 0x2002000004200802, 0x0002000000200000
975         .quad 0x0000000000000000, 0x2000000004000002
976         .quad 0x2000000000000002, 0x0000000004000000
977         .quad 0x2002000004200002, 0x2000000000000802
978         .quad 0x0000000004000800, 0x2002000000200802
979         .quad 0x2002000000200002, 0x0000000004000800
980         .quad 0x2000000004000002, 0x0002000004200000
981         .quad 0x0002000004200800, 0x2002000000200002
982         .quad 0x0002000004200000, 0x0000000000000800
983         .quad 0x2000000000000802, 0x2002000004200802
984         .quad 0x0002000000200800, 0x2000000000000002
985         .quad 0x0000000004000000, 0x0002000000200800
986         .quad 0x0000000004000000, 0x0002000000200800
987         .quad 0x0002000000200000, 0x2000000004000802
988         .quad 0x2000000004000802, 0x2002000004200002
989         .quad 0x2002000004200002, 0x2000000000000002
990         .quad 0x2002000000200002, 0x0000000004000000
991         .quad 0x0000000004000800, 0x0002000000200000
992         .quad 0x0002000004200800, 0x2000000000000802
993         .quad 0x2002000000200802, 0x0002000004200800
994         .quad 0x2000000000000802, 0x2000000004000002
995         .quad 0x2002000004200802, 0x0002000004200000
996         .quad 0x0002000000200800, 0x0000000000000000
997         .quad 0x2000000000000002, 0x2002000004200802
998         .quad 0x0000000000000000, 0x2002000000200802
999         .quad 0x0002000004200000, 0x0000000000000800
1000         .quad 0x2000000004000002, 0x0000000004000800
1001         .quad 0x0000000000000800, 0x2002000000200002
1002 .L_s8:
1003         .quad 0x0100010410001000, 0x0000010000001000
1004         .quad 0x0000000000040000, 0x0100010410041000
1005         .quad 0x0100000010000000, 0x0100010410001000
1006         .quad 0x0000000400000000, 0x0100000010000000
1007         .quad 0x0000000400040000, 0x0100000010040000
1008         .quad 0x0100010410041000, 0x0000010000041000
1009         .quad 0x0100010010041000, 0x0000010400041000
1010         .quad 0x0000010000001000, 0x0000000400000000
1011         .quad 0x0100000010040000, 0x0100000410000000
1012         .quad 0x0100010010001000, 0x0000010400001000
1013         .quad 0x0000010000041000, 0x0000000400040000
1014         .quad 0x0100000410040000, 0x0100010010041000
1015         .quad 0x0000010400001000, 0x0000000000000000
1016         .quad 0x0000000000000000, 0x0100000410040000
1017         .quad 0x0100000410000000, 0x0100010010001000
1018         .quad 0x0000010400041000, 0x0000000000040000
1019         .quad 0x0000010400041000, 0x0000000000040000
1020         .quad 0x0100010010041000, 0x0000010000001000
1021         .quad 0x0000000400000000, 0x0100000410040000
1022         .quad 0x0000010000001000, 0x0000010400041000
1023         .quad 0x0100010010001000, 0x0000000400000000
1024         .quad 0x0100000410000000, 0x0100000010040000
1025         .quad 0x0100000410040000, 0x0100000010000000
1026         .quad 0x0000000000040000, 0x0100010410001000
1027         .quad 0x0000000000000000, 0x0100010410041000
1028         .quad 0x0000000400040000, 0x0100000410000000
1029         .quad 0x0100000010040000, 0x0100010010001000
1030         .quad 0x0100010410001000, 0x0000000000000000
1031         .quad 0x0100010410041000, 0x0000010000041000
1032         .quad 0x0000010000041000, 0x0000010400001000
1033         .quad 0x0000010400001000, 0x0000000400040000
1034         .quad 0x0100000010000000, 0x0100010010041000
1035
1036 #endif
1037 #endif