pubkey: Re-map all depreccated RSA algo numbers.
[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
25 #ifdef __PIC__
26 #  define RIP (%rip)
27 #else
28 #  define RIP
29 #endif
30
31 .text
32
33 #define s1 0
34 #define s2 ((s1) + (64*8))
35 #define s3 ((s2) + (64*8))
36 #define s4 ((s3) + (64*8))
37 #define s5 ((s4) + (64*8))
38 #define s6 ((s5) + (64*8))
39 #define s7 ((s6) + (64*8))
40 #define s8 ((s7) + (64*8))
41
42 /* register macros */
43 #define CTX %rdi
44 #define SBOXES %rbp
45
46 #define RL0 %r8
47 #define RL1 %r9
48 #define RL2 %r10
49
50 #define RL0d %r8d
51 #define RL1d %r9d
52 #define RL2d %r10d
53
54 #define RR0 %r11
55 #define RR1 %r12
56 #define RR2 %r13
57
58 #define RR0d %r11d
59 #define RR1d %r12d
60 #define RR2d %r13d
61
62 #define RW0 %rax
63 #define RW1 %rbx
64 #define RW2 %rcx
65
66 #define RW0d %eax
67 #define RW1d %ebx
68 #define RW2d %ecx
69
70 #define RW0bl %al
71 #define RW1bl %bl
72 #define RW2bl %cl
73
74 #define RW0bh %ah
75 #define RW1bh %bh
76 #define RW2bh %ch
77
78 #define RT0 %r15
79 #define RT1 %rsi
80 #define RT2 %r14
81 #define RT3 %rdx
82
83 #define RT0d %r15d
84 #define RT1d %esi
85 #define RT2d %r14d
86 #define RT3d %edx
87
88 /***********************************************************************
89  * 1-way 3DES
90  ***********************************************************************/
91 #define do_permutation(a, b, offset, mask) \
92         movl a, RT0d; \
93         shrl $(offset), RT0d; \
94         xorl b, RT0d; \
95         andl $(mask), RT0d; \
96         xorl RT0d, b; \
97         shll $(offset), RT0d; \
98         xorl RT0d, a;
99
100 #define expand_to_64bits(val, mask) \
101         movl val##d, RT0d; \
102         rorl $4, RT0d; \
103         shlq $32, RT0; \
104         orq RT0, val; \
105         andq mask, val;
106
107 #define compress_to_64bits(val) \
108         movq val, RT0; \
109         shrq $32, RT0; \
110         roll $4, RT0d; \
111         orl RT0d, val##d;
112
113 #define initial_permutation(left, right) \
114         do_permutation(left##d, right##d,  4, 0x0f0f0f0f); \
115         do_permutation(left##d, right##d, 16, 0x0000ffff); \
116         do_permutation(right##d, left##d,  2, 0x33333333); \
117         do_permutation(right##d, left##d,  8, 0x00ff00ff); \
118         movabs $0x3f3f3f3f3f3f3f3f, RT3; \
119         movl left##d, RW0d; \
120         roll $1, right##d; \
121         xorl right##d, RW0d; \
122         andl $0xaaaaaaaa, RW0d; \
123         xorl RW0d, left##d; \
124         xorl RW0d, right##d; \
125         roll $1, left##d; \
126         expand_to_64bits(right, RT3); \
127         expand_to_64bits(left, RT3);
128
129 #define final_permutation(left, right) \
130         compress_to_64bits(right); \
131         compress_to_64bits(left); \
132         movl right##d, RW0d; \
133         rorl $1, left##d; \
134         xorl left##d, RW0d; \
135         andl $0xaaaaaaaa, RW0d; \
136         xorl RW0d, right##d; \
137         xorl RW0d, left##d; \
138         rorl $1, right##d; \
139         do_permutation(right##d, left##d,  8, 0x00ff00ff); \
140         do_permutation(right##d, left##d,  2, 0x33333333); \
141         do_permutation(left##d, right##d, 16, 0x0000ffff); \
142         do_permutation(left##d, right##d,  4, 0x0f0f0f0f);
143
144 #define round1(n, from, to, load_next_key) \
145         xorq from, RW0; \
146         \
147         movzbl RW0bl, RT0d; \
148         movzbl RW0bh, RT1d; \
149         shrq $16, RW0; \
150         movzbl RW0bl, RT2d; \
151         movzbl RW0bh, RT3d; \
152         shrq $16, RW0; \
153         movq s8(SBOXES, RT0, 8), RT0; \
154         xorq s6(SBOXES, RT1, 8), to; \
155         movzbl RW0bl, RL1d; \
156         movzbl RW0bh, RT1d; \
157         shrl $16, RW0d; \
158         xorq s4(SBOXES, RT2, 8), RT0; \
159         xorq s2(SBOXES, RT3, 8), to; \
160         movzbl RW0bl, RT2d; \
161         movzbl RW0bh, RT3d; \
162         xorq s7(SBOXES, RL1, 8), RT0; \
163         xorq s5(SBOXES, RT1, 8), to; \
164         xorq s3(SBOXES, RT2, 8), RT0; \
165         load_next_key(n, RW0); \
166         xorq RT0, to; \
167         xorq s1(SBOXES, RT3, 8), to; \
168
169 #define load_next_key(n, RWx) \
170         movq (((n) + 1) * 8)(CTX), RWx;
171
172 #define dummy2(a, b) /*_*/
173
174 #define read_block(io, left, right) \
175         movl    (io), left##d; \
176         movl   4(io), right##d; \
177         bswapl left##d; \
178         bswapl right##d;
179
180 #define write_block(io, left, right) \
181         bswapl left##d; \
182         bswapl right##d; \
183         movl   left##d,   (io); \
184         movl   right##d, 4(io);
185
186 .align 8
187 .globl _gcry_3des_amd64_crypt_block
188 .type  _gcry_3des_amd64_crypt_block,@function;
189
190 _gcry_3des_amd64_crypt_block:
191         /* input:
192          *      %rdi: round keys, CTX
193          *      %rsi: dst
194          *      %rdx: src
195          */
196         pushq %rbp;
197         pushq %rbx;
198         pushq %r12;
199         pushq %r13;
200         pushq %r14;
201         pushq %r15;
202         pushq %rsi; /*dst*/
203
204         leaq .L_s1 RIP, SBOXES;
205
206         read_block(%rdx, RL0, RR0);
207         initial_permutation(RL0, RR0);
208
209         movq (CTX), RW0;
210
211         round1(0, RR0, RL0, load_next_key);
212         round1(1, RL0, RR0, load_next_key);
213         round1(2, RR0, RL0, load_next_key);
214         round1(3, RL0, RR0, load_next_key);
215         round1(4, RR0, RL0, load_next_key);
216         round1(5, RL0, RR0, load_next_key);
217         round1(6, RR0, RL0, load_next_key);
218         round1(7, RL0, RR0, load_next_key);
219         round1(8, RR0, RL0, load_next_key);
220         round1(9, RL0, RR0, load_next_key);
221         round1(10, RR0, RL0, load_next_key);
222         round1(11, RL0, RR0, load_next_key);
223         round1(12, RR0, RL0, load_next_key);
224         round1(13, RL0, RR0, load_next_key);
225         round1(14, RR0, RL0, load_next_key);
226         round1(15, RL0, RR0, load_next_key);
227
228         round1(16+0, RL0, RR0, load_next_key);
229         round1(16+1, RR0, RL0, load_next_key);
230         round1(16+2, RL0, RR0, load_next_key);
231         round1(16+3, RR0, RL0, load_next_key);
232         round1(16+4, RL0, RR0, load_next_key);
233         round1(16+5, RR0, RL0, load_next_key);
234         round1(16+6, RL0, RR0, load_next_key);
235         round1(16+7, RR0, RL0, load_next_key);
236         round1(16+8, RL0, RR0, load_next_key);
237         round1(16+9, RR0, RL0, load_next_key);
238         round1(16+10, RL0, RR0, load_next_key);
239         round1(16+11, RR0, RL0, load_next_key);
240         round1(16+12, RL0, RR0, load_next_key);
241         round1(16+13, RR0, RL0, load_next_key);
242         round1(16+14, RL0, RR0, load_next_key);
243         round1(16+15, RR0, RL0, load_next_key);
244
245         round1(32+0, RR0, RL0, load_next_key);
246         round1(32+1, RL0, RR0, load_next_key);
247         round1(32+2, RR0, RL0, load_next_key);
248         round1(32+3, RL0, RR0, load_next_key);
249         round1(32+4, RR0, RL0, load_next_key);
250         round1(32+5, RL0, RR0, load_next_key);
251         round1(32+6, RR0, RL0, load_next_key);
252         round1(32+7, RL0, RR0, load_next_key);
253         round1(32+8, RR0, RL0, load_next_key);
254         round1(32+9, RL0, RR0, load_next_key);
255         round1(32+10, RR0, RL0, load_next_key);
256         round1(32+11, RL0, RR0, load_next_key);
257         round1(32+12, RR0, RL0, load_next_key);
258         round1(32+13, RL0, RR0, load_next_key);
259         round1(32+14, RR0, RL0, load_next_key);
260         round1(32+15, RL0, RR0, dummy2);
261
262         popq RW2; /*dst*/
263         final_permutation(RR0, RL0);
264         write_block(RW2, RR0, RL0);
265
266         popq %r15;
267         popq %r14;
268         popq %r13;
269         popq %r12;
270         popq %rbx;
271         popq %rbp;
272
273         ret;
274 .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 .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 RIP, 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 .size _gcry_3des_amd64_crypt_blk3,.-_gcry_3des_amd64_crypt_blk3;
532
533 .align 8
534 .globl  _gcry_3des_amd64_cbc_dec
535 .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
544         pushq %rbp;
545         pushq %rbx;
546         pushq %r12;
547         pushq %r13;
548         pushq %r14;
549         pushq %r15;
550
551         pushq %rsi; /*dst*/
552         pushq %rdx; /*src*/
553         pushq %rcx; /*iv*/
554
555         /* load input */
556         movl 0 * 4(%rdx), RL0d;
557         movl 1 * 4(%rdx), RR0d;
558         movl 2 * 4(%rdx), RL1d;
559         movl 3 * 4(%rdx), RR1d;
560         movl 4 * 4(%rdx), RL2d;
561         movl 5 * 4(%rdx), RR2d;
562
563         bswapl RL0d;
564         bswapl RR0d;
565         bswapl RL1d;
566         bswapl RR1d;
567         bswapl RL2d;
568         bswapl RR2d;
569
570         call _gcry_3des_amd64_crypt_blk3;
571
572         popq %rcx; /*iv*/
573         popq %rdx; /*src*/
574         popq %rsi; /*dst*/
575
576         bswapl RR0d;
577         bswapl RL0d;
578         bswapl RR1d;
579         bswapl RL1d;
580         bswapl RR2d;
581         bswapl RL2d;
582
583         movq 2 * 8(%rdx), RT0;
584         xorl 0 * 4(%rcx), RR0d;
585         xorl 1 * 4(%rcx), RL0d;
586         xorl 0 * 4(%rdx), RR1d;
587         xorl 1 * 4(%rdx), RL1d;
588         xorl 2 * 4(%rdx), RR2d;
589         xorl 3 * 4(%rdx), RL2d;
590         movq RT0, (%rcx); /* store new IV */
591
592         movl RR0d, 0 * 4(%rsi);
593         movl RL0d, 1 * 4(%rsi);
594         movl RR1d, 2 * 4(%rsi);
595         movl RL1d, 3 * 4(%rsi);
596         movl RR2d, 4 * 4(%rsi);
597         movl RL2d, 5 * 4(%rsi);
598
599         popq %r15;
600         popq %r14;
601         popq %r13;
602         popq %r12;
603         popq %rbx;
604         popq %rbp;
605
606         ret;
607 .size _gcry_3des_amd64_cbc_dec,.-_gcry_3des_amd64_cbc_dec;
608
609 .align 8
610 .globl  _gcry_3des_amd64_ctr_enc
611 .type   _gcry_3des_amd64_ctr_enc,@function;
612 _gcry_3des_amd64_ctr_enc:
613         /* input:
614          *      %rdi: ctx, CTX
615          *      %rsi: dst (3 blocks)
616          *      %rdx: src (3 blocks)
617          *      %rcx: iv (64bit)
618          */
619
620         pushq %rbp;
621         pushq %rbx;
622         pushq %r12;
623         pushq %r13;
624         pushq %r14;
625         pushq %r15;
626
627         pushq %rsi; /*dst*/
628         pushq %rdx; /*src*/
629         movq %rcx, RW2;
630
631         /* load IV and byteswap */
632         movq (RW2), RT0;
633         bswapq RT0;
634         movq RT0, RR0;
635
636         /* construct IVs */
637         leaq 1(RT0), RR1;
638         leaq 2(RT0), RR2;
639         leaq 3(RT0), RT0;
640         movq RR0, RL0;
641         movq RR1, RL1;
642         movq RR2, RL2;
643         bswapq RT0;
644         shrq $32, RL0;
645         shrq $32, RL1;
646         shrq $32, RL2;
647
648         /* store new IV */
649         movq RT0, (RW2);
650
651         call _gcry_3des_amd64_crypt_blk3;
652
653         popq %rdx; /*src*/
654         popq %rsi; /*dst*/
655
656         bswapl RR0d;
657         bswapl RL0d;
658         bswapl RR1d;
659         bswapl RL1d;
660         bswapl RR2d;
661         bswapl RL2d;
662
663         xorl 0 * 4(%rdx), RR0d;
664         xorl 1 * 4(%rdx), RL0d;
665         xorl 2 * 4(%rdx), RR1d;
666         xorl 3 * 4(%rdx), RL1d;
667         xorl 4 * 4(%rdx), RR2d;
668         xorl 5 * 4(%rdx), RL2d;
669
670         movl RR0d, 0 * 4(%rsi);
671         movl RL0d, 1 * 4(%rsi);
672         movl RR1d, 2 * 4(%rsi);
673         movl RL1d, 3 * 4(%rsi);
674         movl RR2d, 4 * 4(%rsi);
675         movl RL2d, 5 * 4(%rsi);
676
677         popq %r15;
678         popq %r14;
679         popq %r13;
680         popq %r12;
681         popq %rbx;
682         popq %rbp;
683
684         ret;
685 .size _gcry_3des_amd64_cbc_dec,.-_gcry_3des_amd64_cbc_dec;
686
687 .align 8
688 .globl  _gcry_3des_amd64_cfb_dec
689 .type   _gcry_3des_amd64_cfb_dec,@function;
690 _gcry_3des_amd64_cfb_dec:
691         /* input:
692          *      %rdi: ctx, CTX
693          *      %rsi: dst (3 blocks)
694          *      %rdx: src (3 blocks)
695          *      %rcx: iv (64bit)
696          */
697         pushq %rbp;
698         pushq %rbx;
699         pushq %r12;
700         pushq %r13;
701         pushq %r14;
702         pushq %r15;
703
704         pushq %rsi; /*dst*/
705         pushq %rdx; /*src*/
706         movq %rcx, RW2;
707
708         /* Load input */
709         movl 0 * 4(RW2), RL0d;
710         movl 1 * 4(RW2), RR0d;
711         movl 0 * 4(%rdx), RL1d;
712         movl 1 * 4(%rdx), RR1d;
713         movl 2 * 4(%rdx), RL2d;
714         movl 3 * 4(%rdx), RR2d;
715
716         bswapl RL0d;
717         bswapl RR0d;
718         bswapl RL1d;
719         bswapl RR1d;
720         bswapl RL2d;
721         bswapl RR2d;
722
723         /* Update IV */
724         movq 4 * 4(%rdx), RW0;
725         movq RW0, (RW2);
726
727         call _gcry_3des_amd64_crypt_blk3;
728
729         popq %rdx; /*src*/
730         popq %rsi; /*dst*/
731
732         bswapl RR0d;
733         bswapl RL0d;
734         bswapl RR1d;
735         bswapl RL1d;
736         bswapl RR2d;
737         bswapl RL2d;
738
739         xorl 0 * 4(%rdx), RR0d;
740         xorl 1 * 4(%rdx), RL0d;
741         xorl 2 * 4(%rdx), RR1d;
742         xorl 3 * 4(%rdx), RL1d;
743         xorl 4 * 4(%rdx), RR2d;
744         xorl 5 * 4(%rdx), RL2d;
745
746         movl RR0d, 0 * 4(%rsi);
747         movl RL0d, 1 * 4(%rsi);
748         movl RR1d, 2 * 4(%rsi);
749         movl RL1d, 3 * 4(%rsi);
750         movl RR2d, 4 * 4(%rsi);
751         movl RL2d, 5 * 4(%rsi);
752
753         popq %r15;
754         popq %r14;
755         popq %r13;
756         popq %r12;
757         popq %rbx;
758         popq %rbp;
759         ret;
760 .size _gcry_3des_amd64_cfb_dec,.-_gcry_3des_amd64_cfb_dec;
761
762 .data
763 .align 16
764 .L_s1:
765         .quad 0x0010100001010400, 0x0000000000000000
766         .quad 0x0000100000010000, 0x0010100001010404
767         .quad 0x0010100001010004, 0x0000100000010404
768         .quad 0x0000000000000004, 0x0000100000010000
769         .quad 0x0000000000000400, 0x0010100001010400
770         .quad 0x0010100001010404, 0x0000000000000400
771         .quad 0x0010000001000404, 0x0010100001010004
772         .quad 0x0010000001000000, 0x0000000000000004
773         .quad 0x0000000000000404, 0x0010000001000400
774         .quad 0x0010000001000400, 0x0000100000010400
775         .quad 0x0000100000010400, 0x0010100001010000
776         .quad 0x0010100001010000, 0x0010000001000404
777         .quad 0x0000100000010004, 0x0010000001000004
778         .quad 0x0010000001000004, 0x0000100000010004
779         .quad 0x0000000000000000, 0x0000000000000404
780         .quad 0x0000100000010404, 0x0010000001000000
781         .quad 0x0000100000010000, 0x0010100001010404
782         .quad 0x0000000000000004, 0x0010100001010000
783         .quad 0x0010100001010400, 0x0010000001000000
784         .quad 0x0010000001000000, 0x0000000000000400
785         .quad 0x0010100001010004, 0x0000100000010000
786         .quad 0x0000100000010400, 0x0010000001000004
787         .quad 0x0000000000000400, 0x0000000000000004
788         .quad 0x0010000001000404, 0x0000100000010404
789         .quad 0x0010100001010404, 0x0000100000010004
790         .quad 0x0010100001010000, 0x0010000001000404
791         .quad 0x0010000001000004, 0x0000000000000404
792         .quad 0x0000100000010404, 0x0010100001010400
793         .quad 0x0000000000000404, 0x0010000001000400
794         .quad 0x0010000001000400, 0x0000000000000000
795         .quad 0x0000100000010004, 0x0000100000010400
796         .quad 0x0000000000000000, 0x0010100001010004
797 .L_s2:
798         .quad 0x0801080200100020, 0x0800080000000000
799         .quad 0x0000080000000000, 0x0001080200100020
800         .quad 0x0001000000100000, 0x0000000200000020
801         .quad 0x0801000200100020, 0x0800080200000020
802         .quad 0x0800000200000020, 0x0801080200100020
803         .quad 0x0801080000100000, 0x0800000000000000
804         .quad 0x0800080000000000, 0x0001000000100000
805         .quad 0x0000000200000020, 0x0801000200100020
806         .quad 0x0001080000100000, 0x0001000200100020
807         .quad 0x0800080200000020, 0x0000000000000000
808         .quad 0x0800000000000000, 0x0000080000000000
809         .quad 0x0001080200100020, 0x0801000000100000
810         .quad 0x0001000200100020, 0x0800000200000020
811         .quad 0x0000000000000000, 0x0001080000100000
812         .quad 0x0000080200000020, 0x0801080000100000
813         .quad 0x0801000000100000, 0x0000080200000020
814         .quad 0x0000000000000000, 0x0001080200100020
815         .quad 0x0801000200100020, 0x0001000000100000
816         .quad 0x0800080200000020, 0x0801000000100000
817         .quad 0x0801080000100000, 0x0000080000000000
818         .quad 0x0801000000100000, 0x0800080000000000
819         .quad 0x0000000200000020, 0x0801080200100020
820         .quad 0x0001080200100020, 0x0000000200000020
821         .quad 0x0000080000000000, 0x0800000000000000
822         .quad 0x0000080200000020, 0x0801080000100000
823         .quad 0x0001000000100000, 0x0800000200000020
824         .quad 0x0001000200100020, 0x0800080200000020
825         .quad 0x0800000200000020, 0x0001000200100020
826         .quad 0x0001080000100000, 0x0000000000000000
827         .quad 0x0800080000000000, 0x0000080200000020
828         .quad 0x0800000000000000, 0x0801000200100020
829         .quad 0x0801080200100020, 0x0001080000100000
830 .L_s3:
831         .quad 0x0000002000000208, 0x0000202008020200
832         .quad 0x0000000000000000, 0x0000200008020008
833         .quad 0x0000002008000200, 0x0000000000000000
834         .quad 0x0000202000020208, 0x0000002008000200
835         .quad 0x0000200000020008, 0x0000000008000008
836         .quad 0x0000000008000008, 0x0000200000020000
837         .quad 0x0000202008020208, 0x0000200000020008
838         .quad 0x0000200008020000, 0x0000002000000208
839         .quad 0x0000000008000000, 0x0000000000000008
840         .quad 0x0000202008020200, 0x0000002000000200
841         .quad 0x0000202000020200, 0x0000200008020000
842         .quad 0x0000200008020008, 0x0000202000020208
843         .quad 0x0000002008000208, 0x0000202000020200
844         .quad 0x0000200000020000, 0x0000002008000208
845         .quad 0x0000000000000008, 0x0000202008020208
846         .quad 0x0000002000000200, 0x0000000008000000
847         .quad 0x0000202008020200, 0x0000000008000000
848         .quad 0x0000200000020008, 0x0000002000000208
849         .quad 0x0000200000020000, 0x0000202008020200
850         .quad 0x0000002008000200, 0x0000000000000000
851         .quad 0x0000002000000200, 0x0000200000020008
852         .quad 0x0000202008020208, 0x0000002008000200
853         .quad 0x0000000008000008, 0x0000002000000200
854         .quad 0x0000000000000000, 0x0000200008020008
855         .quad 0x0000002008000208, 0x0000200000020000
856         .quad 0x0000000008000000, 0x0000202008020208
857         .quad 0x0000000000000008, 0x0000202000020208
858         .quad 0x0000202000020200, 0x0000000008000008
859         .quad 0x0000200008020000, 0x0000002008000208
860         .quad 0x0000002000000208, 0x0000200008020000
861         .quad 0x0000202000020208, 0x0000000000000008
862         .quad 0x0000200008020008, 0x0000202000020200
863 .L_s4:
864         .quad 0x1008020000002001, 0x1000020800002001
865         .quad 0x1000020800002001, 0x0000000800000000
866         .quad 0x0008020800002000, 0x1008000800000001
867         .quad 0x1008000000000001, 0x1000020000002001
868         .quad 0x0000000000000000, 0x0008020000002000
869         .quad 0x0008020000002000, 0x1008020800002001
870         .quad 0x1000000800000001, 0x0000000000000000
871         .quad 0x0008000800000000, 0x1008000000000001
872         .quad 0x1000000000000001, 0x0000020000002000
873         .quad 0x0008000000000000, 0x1008020000002001
874         .quad 0x0000000800000000, 0x0008000000000000
875         .quad 0x1000020000002001, 0x0000020800002000
876         .quad 0x1008000800000001, 0x1000000000000001
877         .quad 0x0000020800002000, 0x0008000800000000
878         .quad 0x0000020000002000, 0x0008020800002000
879         .quad 0x1008020800002001, 0x1000000800000001
880         .quad 0x0008000800000000, 0x1008000000000001
881         .quad 0x0008020000002000, 0x1008020800002001
882         .quad 0x1000000800000001, 0x0000000000000000
883         .quad 0x0000000000000000, 0x0008020000002000
884         .quad 0x0000020800002000, 0x0008000800000000
885         .quad 0x1008000800000001, 0x1000000000000001
886         .quad 0x1008020000002001, 0x1000020800002001
887         .quad 0x1000020800002001, 0x0000000800000000
888         .quad 0x1008020800002001, 0x1000000800000001
889         .quad 0x1000000000000001, 0x0000020000002000
890         .quad 0x1008000000000001, 0x1000020000002001
891         .quad 0x0008020800002000, 0x1008000800000001
892         .quad 0x1000020000002001, 0x0000020800002000
893         .quad 0x0008000000000000, 0x1008020000002001
894         .quad 0x0000000800000000, 0x0008000000000000
895         .quad 0x0000020000002000, 0x0008020800002000
896 .L_s5:
897         .quad 0x0000001000000100, 0x0020001002080100
898         .quad 0x0020000002080000, 0x0420001002000100
899         .quad 0x0000000000080000, 0x0000001000000100
900         .quad 0x0400000000000000, 0x0020000002080000
901         .quad 0x0400001000080100, 0x0000000000080000
902         .quad 0x0020001002000100, 0x0400001000080100
903         .quad 0x0420001002000100, 0x0420000002080000
904         .quad 0x0000001000080100, 0x0400000000000000
905         .quad 0x0020000002000000, 0x0400000000080000
906         .quad 0x0400000000080000, 0x0000000000000000
907         .quad 0x0400001000000100, 0x0420001002080100
908         .quad 0x0420001002080100, 0x0020001002000100
909         .quad 0x0420000002080000, 0x0400001000000100
910         .quad 0x0000000000000000, 0x0420000002000000
911         .quad 0x0020001002080100, 0x0020000002000000
912         .quad 0x0420000002000000, 0x0000001000080100
913         .quad 0x0000000000080000, 0x0420001002000100
914         .quad 0x0000001000000100, 0x0020000002000000
915         .quad 0x0400000000000000, 0x0020000002080000
916         .quad 0x0420001002000100, 0x0400001000080100
917         .quad 0x0020001002000100, 0x0400000000000000
918         .quad 0x0420000002080000, 0x0020001002080100
919         .quad 0x0400001000080100, 0x0000001000000100
920         .quad 0x0020000002000000, 0x0420000002080000
921         .quad 0x0420001002080100, 0x0000001000080100
922         .quad 0x0420000002000000, 0x0420001002080100
923         .quad 0x0020000002080000, 0x0000000000000000
924         .quad 0x0400000000080000, 0x0420000002000000
925         .quad 0x0000001000080100, 0x0020001002000100
926         .quad 0x0400001000000100, 0x0000000000080000
927         .quad 0x0000000000000000, 0x0400000000080000
928         .quad 0x0020001002080100, 0x0400001000000100
929 .L_s6:
930         .quad 0x0200000120000010, 0x0204000020000000
931         .quad 0x0000040000000000, 0x0204040120000010
932         .quad 0x0204000020000000, 0x0000000100000010
933         .quad 0x0204040120000010, 0x0004000000000000
934         .quad 0x0200040020000000, 0x0004040100000010
935         .quad 0x0004000000000000, 0x0200000120000010
936         .quad 0x0004000100000010, 0x0200040020000000
937         .quad 0x0200000020000000, 0x0000040100000010
938         .quad 0x0000000000000000, 0x0004000100000010
939         .quad 0x0200040120000010, 0x0000040000000000
940         .quad 0x0004040000000000, 0x0200040120000010
941         .quad 0x0000000100000010, 0x0204000120000010
942         .quad 0x0204000120000010, 0x0000000000000000
943         .quad 0x0004040100000010, 0x0204040020000000
944         .quad 0x0000040100000010, 0x0004040000000000
945         .quad 0x0204040020000000, 0x0200000020000000
946         .quad 0x0200040020000000, 0x0000000100000010
947         .quad 0x0204000120000010, 0x0004040000000000
948         .quad 0x0204040120000010, 0x0004000000000000
949         .quad 0x0000040100000010, 0x0200000120000010
950         .quad 0x0004000000000000, 0x0200040020000000
951         .quad 0x0200000020000000, 0x0000040100000010
952         .quad 0x0200000120000010, 0x0204040120000010
953         .quad 0x0004040000000000, 0x0204000020000000
954         .quad 0x0004040100000010, 0x0204040020000000
955         .quad 0x0000000000000000, 0x0204000120000010
956         .quad 0x0000000100000010, 0x0000040000000000
957         .quad 0x0204000020000000, 0x0004040100000010
958         .quad 0x0000040000000000, 0x0004000100000010
959         .quad 0x0200040120000010, 0x0000000000000000
960         .quad 0x0204040020000000, 0x0200000020000000
961         .quad 0x0004000100000010, 0x0200040120000010
962 .L_s7:
963         .quad 0x0002000000200000, 0x2002000004200002
964         .quad 0x2000000004000802, 0x0000000000000000
965         .quad 0x0000000000000800, 0x2000000004000802
966         .quad 0x2002000000200802, 0x0002000004200800
967         .quad 0x2002000004200802, 0x0002000000200000
968         .quad 0x0000000000000000, 0x2000000004000002
969         .quad 0x2000000000000002, 0x0000000004000000
970         .quad 0x2002000004200002, 0x2000000000000802
971         .quad 0x0000000004000800, 0x2002000000200802
972         .quad 0x2002000000200002, 0x0000000004000800
973         .quad 0x2000000004000002, 0x0002000004200000
974         .quad 0x0002000004200800, 0x2002000000200002
975         .quad 0x0002000004200000, 0x0000000000000800
976         .quad 0x2000000000000802, 0x2002000004200802
977         .quad 0x0002000000200800, 0x2000000000000002
978         .quad 0x0000000004000000, 0x0002000000200800
979         .quad 0x0000000004000000, 0x0002000000200800
980         .quad 0x0002000000200000, 0x2000000004000802
981         .quad 0x2000000004000802, 0x2002000004200002
982         .quad 0x2002000004200002, 0x2000000000000002
983         .quad 0x2002000000200002, 0x0000000004000000
984         .quad 0x0000000004000800, 0x0002000000200000
985         .quad 0x0002000004200800, 0x2000000000000802
986         .quad 0x2002000000200802, 0x0002000004200800
987         .quad 0x2000000000000802, 0x2000000004000002
988         .quad 0x2002000004200802, 0x0002000004200000
989         .quad 0x0002000000200800, 0x0000000000000000
990         .quad 0x2000000000000002, 0x2002000004200802
991         .quad 0x0000000000000000, 0x2002000000200802
992         .quad 0x0002000004200000, 0x0000000000000800
993         .quad 0x2000000004000002, 0x0000000004000800
994         .quad 0x0000000000000800, 0x2002000000200002
995 .L_s8:
996         .quad 0x0100010410001000, 0x0000010000001000
997         .quad 0x0000000000040000, 0x0100010410041000
998         .quad 0x0100000010000000, 0x0100010410001000
999         .quad 0x0000000400000000, 0x0100000010000000
1000         .quad 0x0000000400040000, 0x0100000010040000
1001         .quad 0x0100010410041000, 0x0000010000041000
1002         .quad 0x0100010010041000, 0x0000010400041000
1003         .quad 0x0000010000001000, 0x0000000400000000
1004         .quad 0x0100000010040000, 0x0100000410000000
1005         .quad 0x0100010010001000, 0x0000010400001000
1006         .quad 0x0000010000041000, 0x0000000400040000
1007         .quad 0x0100000410040000, 0x0100010010041000
1008         .quad 0x0000010400001000, 0x0000000000000000
1009         .quad 0x0000000000000000, 0x0100000410040000
1010         .quad 0x0100000410000000, 0x0100010010001000
1011         .quad 0x0000010400041000, 0x0000000000040000
1012         .quad 0x0000010400041000, 0x0000000000040000
1013         .quad 0x0100010010041000, 0x0000010000001000
1014         .quad 0x0000000400000000, 0x0100000410040000
1015         .quad 0x0000010000001000, 0x0000010400041000
1016         .quad 0x0100010010001000, 0x0000000400000000
1017         .quad 0x0100000410000000, 0x0100000010040000
1018         .quad 0x0100000410040000, 0x0100000010000000
1019         .quad 0x0000000000040000, 0x0100010410001000
1020         .quad 0x0000000000000000, 0x0100010410041000
1021         .quad 0x0000000400040000, 0x0100000410000000
1022         .quad 0x0100000010040000, 0x0100010010001000
1023         .quad 0x0100010410001000, 0x0000000000000000
1024         .quad 0x0100010410041000, 0x0000010000041000
1025         .quad 0x0000010000041000, 0x0000010400001000
1026         .quad 0x0000010400001000, 0x0000000400040000
1027         .quad 0x0100000010000000, 0x0100010010041000
1028
1029 #endif
1030 #endif