ecc: Fix ec_mulm_25519.
[libgcrypt.git] / cipher / camellia-aesni-avx-amd64.S
1 /* camellia-avx-aesni-amd64.S  -  AES-NI/AVX implementation of Camellia cipher
2  *
3  * Copyright (C) 2013-2015 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(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
24      defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
25     defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)
26
27 #ifdef __PIC__
28 #  define RIP (%rip)
29 #else
30 #  define RIP
31 #endif
32
33 #ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
34 # define ELF(...) __VA_ARGS__
35 #else
36 # define ELF(...) /*_*/
37 #endif
38
39 #define CAMELLIA_TABLE_BYTE_LEN 272
40
41 /* struct CAMELLIA_context: */
42 #define key_table 0
43 #define key_bitlength CAMELLIA_TABLE_BYTE_LEN
44
45 /* register macros */
46 #define CTX %rdi
47 #define RIO %r8
48
49 /**********************************************************************
50   helper macros
51  **********************************************************************/
52 #define filter_8bit(x, lo_t, hi_t, mask4bit, tmp0) \
53         vpand x, mask4bit, tmp0; \
54         vpandn x, mask4bit, x; \
55         vpsrld $4, x, x; \
56         \
57         vpshufb tmp0, lo_t, tmp0; \
58         vpshufb x, hi_t, x; \
59         vpxor tmp0, x, x;
60
61 /**********************************************************************
62   16-way camellia
63  **********************************************************************/
64
65 /*
66  * IN:
67  *   x0..x7: byte-sliced AB state
68  *   mem_cd: register pointer storing CD state
69  *   key: index for key material
70  * OUT:
71  *   x0..x7: new byte-sliced CD state
72  */
73 #define roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, t0, t1, t2, t3, t4, t5, t6, \
74                   t7, mem_cd, key) \
75         /* \
76          * S-function with AES subbytes \
77          */ \
78         vmovdqa .Linv_shift_row RIP, t4; \
79         vbroadcastss .L0f0f0f0f RIP, t7; \
80         vmovdqa .Lpre_tf_lo_s1 RIP, t0; \
81         vmovdqa .Lpre_tf_hi_s1 RIP, t1; \
82         \
83         /* AES inverse shift rows */ \
84         vpshufb t4, x0, x0; \
85         vpshufb t4, x7, x7; \
86         vpshufb t4, x1, x1; \
87         vpshufb t4, x4, x4; \
88         vpshufb t4, x2, x2; \
89         vpshufb t4, x5, x5; \
90         vpshufb t4, x3, x3; \
91         vpshufb t4, x6, x6; \
92         \
93         /* prefilter sboxes 1, 2 and 3 */ \
94         vmovdqa .Lpre_tf_lo_s4 RIP, t2; \
95         vmovdqa .Lpre_tf_hi_s4 RIP, t3; \
96         filter_8bit(x0, t0, t1, t7, t6); \
97         filter_8bit(x7, t0, t1, t7, t6); \
98         filter_8bit(x1, t0, t1, t7, t6); \
99         filter_8bit(x4, t0, t1, t7, t6); \
100         filter_8bit(x2, t0, t1, t7, t6); \
101         filter_8bit(x5, t0, t1, t7, t6); \
102         \
103         /* prefilter sbox 4 */ \
104         vpxor t4, t4, t4; \
105         filter_8bit(x3, t2, t3, t7, t6); \
106         filter_8bit(x6, t2, t3, t7, t6); \
107         \
108         /* AES subbytes + AES shift rows */ \
109         vmovdqa .Lpost_tf_lo_s1 RIP, t0; \
110         vmovdqa .Lpost_tf_hi_s1 RIP, t1; \
111         vaesenclast t4, x0, x0; \
112         vaesenclast t4, x7, x7; \
113         vaesenclast t4, x1, x1; \
114         vaesenclast t4, x4, x4; \
115         vaesenclast t4, x2, x2; \
116         vaesenclast t4, x5, x5; \
117         vaesenclast t4, x3, x3; \
118         vaesenclast t4, x6, x6; \
119         \
120         /* postfilter sboxes 1 and 4 */ \
121         vmovdqa .Lpost_tf_lo_s3 RIP, t2; \
122         vmovdqa .Lpost_tf_hi_s3 RIP, t3; \
123         filter_8bit(x0, t0, t1, t7, t6); \
124         filter_8bit(x7, t0, t1, t7, t6); \
125         filter_8bit(x3, t0, t1, t7, t6); \
126         filter_8bit(x6, t0, t1, t7, t6); \
127         \
128         /* postfilter sbox 3 */ \
129         vmovdqa .Lpost_tf_lo_s2 RIP, t4; \
130         vmovdqa .Lpost_tf_hi_s2 RIP, t5; \
131         filter_8bit(x2, t2, t3, t7, t6); \
132         filter_8bit(x5, t2, t3, t7, t6); \
133         \
134         vpxor t6, t6, t6; \
135         vmovq key, t0; \
136         \
137         /* postfilter sbox 2 */ \
138         filter_8bit(x1, t4, t5, t7, t2); \
139         filter_8bit(x4, t4, t5, t7, t2); \
140         \
141         vpsrldq $5, t0, t5; \
142         vpsrldq $1, t0, t1; \
143         vpsrldq $2, t0, t2; \
144         vpsrldq $3, t0, t3; \
145         vpsrldq $4, t0, t4; \
146         vpshufb t6, t0, t0; \
147         vpshufb t6, t1, t1; \
148         vpshufb t6, t2, t2; \
149         vpshufb t6, t3, t3; \
150         vpshufb t6, t4, t4; \
151         vpsrldq $2, t5, t7; \
152         vpshufb t6, t7, t7; \
153         \
154         /* P-function */ \
155         vpxor x5, x0, x0; \
156         vpxor x6, x1, x1; \
157         vpxor x7, x2, x2; \
158         vpxor x4, x3, x3; \
159         \
160         vpxor x2, x4, x4; \
161         vpxor x3, x5, x5; \
162         vpxor x0, x6, x6; \
163         vpxor x1, x7, x7; \
164         \
165         vpxor x7, x0, x0; \
166         vpxor x4, x1, x1; \
167         vpxor x5, x2, x2; \
168         vpxor x6, x3, x3; \
169         \
170         vpxor x3, x4, x4; \
171         vpxor x0, x5, x5; \
172         vpxor x1, x6, x6; \
173         vpxor x2, x7, x7; /* note: high and low parts swapped */ \
174         \
175         /* Add key material and result to CD (x becomes new CD) */ \
176         \
177         vpxor t3, x4, x4; \
178         vpxor 0 * 16(mem_cd), x4, x4; \
179         \
180         vpxor t2, x5, x5; \
181         vpxor 1 * 16(mem_cd), x5, x5; \
182         \
183         vpsrldq $1, t5, t3; \
184         vpshufb t6, t5, t5; \
185         vpshufb t6, t3, t6; \
186         \
187         vpxor t1, x6, x6; \
188         vpxor 2 * 16(mem_cd), x6, x6; \
189         \
190         vpxor t0, x7, x7; \
191         vpxor 3 * 16(mem_cd), x7, x7; \
192         \
193         vpxor t7, x0, x0; \
194         vpxor 4 * 16(mem_cd), x0, x0; \
195         \
196         vpxor t6, x1, x1; \
197         vpxor 5 * 16(mem_cd), x1, x1; \
198         \
199         vpxor t5, x2, x2; \
200         vpxor 6 * 16(mem_cd), x2, x2; \
201         \
202         vpxor t4, x3, x3; \
203         vpxor 7 * 16(mem_cd), x3, x3;
204
205 /*
206  * IN/OUT:
207  *  x0..x7: byte-sliced AB state preloaded
208  *  mem_ab: byte-sliced AB state in memory
209  *  mem_cb: byte-sliced CD state in memory
210  */
211 #define two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
212                       y6, y7, mem_ab, mem_cd, i, dir, store_ab) \
213         roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
214                   y6, y7, mem_cd, (key_table + (i) * 8)(CTX)); \
215         \
216         vmovdqu x4, 0 * 16(mem_cd); \
217         vmovdqu x5, 1 * 16(mem_cd); \
218         vmovdqu x6, 2 * 16(mem_cd); \
219         vmovdqu x7, 3 * 16(mem_cd); \
220         vmovdqu x0, 4 * 16(mem_cd); \
221         vmovdqu x1, 5 * 16(mem_cd); \
222         vmovdqu x2, 6 * 16(mem_cd); \
223         vmovdqu x3, 7 * 16(mem_cd); \
224         \
225         roundsm16(x4, x5, x6, x7, x0, x1, x2, x3, y0, y1, y2, y3, y4, y5, \
226                   y6, y7, mem_ab, (key_table + ((i) + (dir)) * 8)(CTX)); \
227         \
228         store_ab(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab);
229
230 #define dummy_store(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) /* do nothing */
231
232 #define store_ab_state(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) \
233         /* Store new AB state */ \
234         vmovdqu x0, 0 * 16(mem_ab); \
235         vmovdqu x1, 1 * 16(mem_ab); \
236         vmovdqu x2, 2 * 16(mem_ab); \
237         vmovdqu x3, 3 * 16(mem_ab); \
238         vmovdqu x4, 4 * 16(mem_ab); \
239         vmovdqu x5, 5 * 16(mem_ab); \
240         vmovdqu x6, 6 * 16(mem_ab); \
241         vmovdqu x7, 7 * 16(mem_ab);
242
243 #define enc_rounds16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
244                       y6, y7, mem_ab, mem_cd, i) \
245         two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
246                       y6, y7, mem_ab, mem_cd, (i) + 2, 1, store_ab_state); \
247         two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
248                       y6, y7, mem_ab, mem_cd, (i) + 4, 1, store_ab_state); \
249         two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
250                       y6, y7, mem_ab, mem_cd, (i) + 6, 1, dummy_store);
251
252 #define dec_rounds16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
253                       y6, y7, mem_ab, mem_cd, i) \
254         two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
255                       y6, y7, mem_ab, mem_cd, (i) + 7, -1, store_ab_state); \
256         two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
257                       y6, y7, mem_ab, mem_cd, (i) + 5, -1, store_ab_state); \
258         two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
259                       y6, y7, mem_ab, mem_cd, (i) + 3, -1, dummy_store);
260
261 /*
262  * IN:
263  *  v0..3: byte-sliced 32-bit integers
264  * OUT:
265  *  v0..3: (IN <<< 1)
266  */
267 #define rol32_1_16(v0, v1, v2, v3, t0, t1, t2, zero) \
268         vpcmpgtb v0, zero, t0; \
269         vpaddb v0, v0, v0; \
270         vpabsb t0, t0; \
271         \
272         vpcmpgtb v1, zero, t1; \
273         vpaddb v1, v1, v1; \
274         vpabsb t1, t1; \
275         \
276         vpcmpgtb v2, zero, t2; \
277         vpaddb v2, v2, v2; \
278         vpabsb t2, t2; \
279         \
280         vpor t0, v1, v1; \
281         \
282         vpcmpgtb v3, zero, t0; \
283         vpaddb v3, v3, v3; \
284         vpabsb t0, t0; \
285         \
286         vpor t1, v2, v2; \
287         vpor t2, v3, v3; \
288         vpor t0, v0, v0;
289
290 /*
291  * IN:
292  *   r: byte-sliced AB state in memory
293  *   l: byte-sliced CD state in memory
294  * OUT:
295  *   x0..x7: new byte-sliced CD state
296  */
297 #define fls16(l, l0, l1, l2, l3, l4, l5, l6, l7, r, t0, t1, t2, t3, tt0, \
298               tt1, tt2, tt3, kll, klr, krl, krr) \
299         /* \
300          * t0 = kll; \
301          * t0 &= ll; \
302          * lr ^= rol32(t0, 1); \
303          */ \
304         vpxor tt0, tt0, tt0; \
305         vmovd kll, t0; \
306         vpshufb tt0, t0, t3; \
307         vpsrldq $1, t0, t0; \
308         vpshufb tt0, t0, t2; \
309         vpsrldq $1, t0, t0; \
310         vpshufb tt0, t0, t1; \
311         vpsrldq $1, t0, t0; \
312         vpshufb tt0, t0, t0; \
313         \
314         vpand l0, t0, t0; \
315         vpand l1, t1, t1; \
316         vpand l2, t2, t2; \
317         vpand l3, t3, t3; \
318         \
319         rol32_1_16(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
320         \
321         vpxor l4, t0, l4; \
322         vmovdqu l4, 4 * 16(l); \
323         vpxor l5, t1, l5; \
324         vmovdqu l5, 5 * 16(l); \
325         vpxor l6, t2, l6; \
326         vmovdqu l6, 6 * 16(l); \
327         vpxor l7, t3, l7; \
328         vmovdqu l7, 7 * 16(l); \
329         \
330         /* \
331          * t2 = krr; \
332          * t2 |= rr; \
333          * rl ^= t2; \
334          */ \
335         \
336         vmovd krr, t0; \
337         vpshufb tt0, t0, t3; \
338         vpsrldq $1, t0, t0; \
339         vpshufb tt0, t0, t2; \
340         vpsrldq $1, t0, t0; \
341         vpshufb tt0, t0, t1; \
342         vpsrldq $1, t0, t0; \
343         vpshufb tt0, t0, t0; \
344         \
345         vpor 4 * 16(r), t0, t0; \
346         vpor 5 * 16(r), t1, t1; \
347         vpor 6 * 16(r), t2, t2; \
348         vpor 7 * 16(r), t3, t3; \
349         \
350         vpxor 0 * 16(r), t0, t0; \
351         vpxor 1 * 16(r), t1, t1; \
352         vpxor 2 * 16(r), t2, t2; \
353         vpxor 3 * 16(r), t3, t3; \
354         vmovdqu t0, 0 * 16(r); \
355         vmovdqu t1, 1 * 16(r); \
356         vmovdqu t2, 2 * 16(r); \
357         vmovdqu t3, 3 * 16(r); \
358         \
359         /* \
360          * t2 = krl; \
361          * t2 &= rl; \
362          * rr ^= rol32(t2, 1); \
363          */ \
364         vmovd krl, t0; \
365         vpshufb tt0, t0, t3; \
366         vpsrldq $1, t0, t0; \
367         vpshufb tt0, t0, t2; \
368         vpsrldq $1, t0, t0; \
369         vpshufb tt0, t0, t1; \
370         vpsrldq $1, t0, t0; \
371         vpshufb tt0, t0, t0; \
372         \
373         vpand 0 * 16(r), t0, t0; \
374         vpand 1 * 16(r), t1, t1; \
375         vpand 2 * 16(r), t2, t2; \
376         vpand 3 * 16(r), t3, t3; \
377         \
378         rol32_1_16(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
379         \
380         vpxor 4 * 16(r), t0, t0; \
381         vpxor 5 * 16(r), t1, t1; \
382         vpxor 6 * 16(r), t2, t2; \
383         vpxor 7 * 16(r), t3, t3; \
384         vmovdqu t0, 4 * 16(r); \
385         vmovdqu t1, 5 * 16(r); \
386         vmovdqu t2, 6 * 16(r); \
387         vmovdqu t3, 7 * 16(r); \
388         \
389         /* \
390          * t0 = klr; \
391          * t0 |= lr; \
392          * ll ^= t0; \
393          */ \
394         \
395         vmovd klr, t0; \
396         vpshufb tt0, t0, t3; \
397         vpsrldq $1, t0, t0; \
398         vpshufb tt0, t0, t2; \
399         vpsrldq $1, t0, t0; \
400         vpshufb tt0, t0, t1; \
401         vpsrldq $1, t0, t0; \
402         vpshufb tt0, t0, t0; \
403         \
404         vpor l4, t0, t0; \
405         vpor l5, t1, t1; \
406         vpor l6, t2, t2; \
407         vpor l7, t3, t3; \
408         \
409         vpxor l0, t0, l0; \
410         vmovdqu l0, 0 * 16(l); \
411         vpxor l1, t1, l1; \
412         vmovdqu l1, 1 * 16(l); \
413         vpxor l2, t2, l2; \
414         vmovdqu l2, 2 * 16(l); \
415         vpxor l3, t3, l3; \
416         vmovdqu l3, 3 * 16(l);
417
418 #define transpose_4x4(x0, x1, x2, x3, t1, t2) \
419         vpunpckhdq x1, x0, t2; \
420         vpunpckldq x1, x0, x0; \
421         \
422         vpunpckldq x3, x2, t1; \
423         vpunpckhdq x3, x2, x2; \
424         \
425         vpunpckhqdq t1, x0, x1; \
426         vpunpcklqdq t1, x0, x0; \
427         \
428         vpunpckhqdq x2, t2, x3; \
429         vpunpcklqdq x2, t2, x2;
430
431 #define byteslice_16x16b_fast(a0, b0, c0, d0, a1, b1, c1, d1, a2, b2, c2, d2, \
432                               a3, b3, c3, d3, st0, st1) \
433         vmovdqu d2, st0; \
434         vmovdqu d3, st1; \
435         transpose_4x4(a0, a1, a2, a3, d2, d3); \
436         transpose_4x4(b0, b1, b2, b3, d2, d3); \
437         vmovdqu st0, d2; \
438         vmovdqu st1, d3; \
439         \
440         vmovdqu a0, st0; \
441         vmovdqu a1, st1; \
442         transpose_4x4(c0, c1, c2, c3, a0, a1); \
443         transpose_4x4(d0, d1, d2, d3, a0, a1); \
444         \
445         vmovdqu .Lshufb_16x16b RIP, a0; \
446         vmovdqu st1, a1; \
447         vpshufb a0, a2, a2; \
448         vpshufb a0, a3, a3; \
449         vpshufb a0, b0, b0; \
450         vpshufb a0, b1, b1; \
451         vpshufb a0, b2, b2; \
452         vpshufb a0, b3, b3; \
453         vpshufb a0, a1, a1; \
454         vpshufb a0, c0, c0; \
455         vpshufb a0, c1, c1; \
456         vpshufb a0, c2, c2; \
457         vpshufb a0, c3, c3; \
458         vpshufb a0, d0, d0; \
459         vpshufb a0, d1, d1; \
460         vpshufb a0, d2, d2; \
461         vpshufb a0, d3, d3; \
462         vmovdqu d3, st1; \
463         vmovdqu st0, d3; \
464         vpshufb a0, d3, a0; \
465         vmovdqu d2, st0; \
466         \
467         transpose_4x4(a0, b0, c0, d0, d2, d3); \
468         transpose_4x4(a1, b1, c1, d1, d2, d3); \
469         vmovdqu st0, d2; \
470         vmovdqu st1, d3; \
471         \
472         vmovdqu b0, st0; \
473         vmovdqu b1, st1; \
474         transpose_4x4(a2, b2, c2, d2, b0, b1); \
475         transpose_4x4(a3, b3, c3, d3, b0, b1); \
476         vmovdqu st0, b0; \
477         vmovdqu st1, b1; \
478         /* does not adjust output bytes inside vectors */
479
480 #define transpose_8x8b(a, b, c, d, e, f, g, h, t0, t1, t2, t3, t4) \
481         vpunpcklbw a, b, t0; \
482         vpunpckhbw a, b, b; \
483         \
484         vpunpcklbw c, d, t1; \
485         vpunpckhbw c, d, d; \
486         \
487         vpunpcklbw e, f, t2; \
488         vpunpckhbw e, f, f; \
489         \
490         vpunpcklbw g, h, t3; \
491         vpunpckhbw g, h, h; \
492         \
493         vpunpcklwd t0, t1, g; \
494         vpunpckhwd t0, t1, t0; \
495         \
496         vpunpcklwd b, d, t1; \
497         vpunpckhwd b, d, e; \
498         \
499         vpunpcklwd t2, t3, c; \
500         vpunpckhwd t2, t3, t2; \
501         \
502         vpunpcklwd f, h, t3; \
503         vpunpckhwd f, h, b; \
504         \
505         vpunpcklwd e, b, t4; \
506         vpunpckhwd e, b, b; \
507         \
508         vpunpcklwd t1, t3, e; \
509         vpunpckhwd t1, t3, f; \
510         \
511         vmovdqa .Ltranspose_8x8_shuf RIP, t3; \
512         \
513         vpunpcklwd g, c, d; \
514         vpunpckhwd g, c, c; \
515         \
516         vpunpcklwd t0, t2, t1; \
517         vpunpckhwd t0, t2, h; \
518         \
519         vpunpckhqdq b, h, a; \
520         vpshufb t3, a, a; \
521         vpunpcklqdq b, h, b; \
522         vpshufb t3, b, b; \
523         \
524         vpunpckhqdq e, d, g; \
525         vpshufb t3, g, g; \
526         vpunpcklqdq e, d, h; \
527         vpshufb t3, h, h; \
528         \
529         vpunpckhqdq f, c, e; \
530         vpshufb t3, e, e; \
531         vpunpcklqdq f, c, f; \
532         vpshufb t3, f, f; \
533         \
534         vpunpckhqdq t4, t1, c; \
535         vpshufb t3, c, c; \
536         vpunpcklqdq t4, t1, d; \
537         vpshufb t3, d, d;
538
539 /* load blocks to registers and apply pre-whitening */
540 #define inpack16_pre(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
541                      y6, y7, rio, key) \
542         vmovq key, x0; \
543         vpshufb .Lpack_bswap RIP, x0, x0; \
544         \
545         vpxor 0 * 16(rio), x0, y7; \
546         vpxor 1 * 16(rio), x0, y6; \
547         vpxor 2 * 16(rio), x0, y5; \
548         vpxor 3 * 16(rio), x0, y4; \
549         vpxor 4 * 16(rio), x0, y3; \
550         vpxor 5 * 16(rio), x0, y2; \
551         vpxor 6 * 16(rio), x0, y1; \
552         vpxor 7 * 16(rio), x0, y0; \
553         vpxor 8 * 16(rio), x0, x7; \
554         vpxor 9 * 16(rio), x0, x6; \
555         vpxor 10 * 16(rio), x0, x5; \
556         vpxor 11 * 16(rio), x0, x4; \
557         vpxor 12 * 16(rio), x0, x3; \
558         vpxor 13 * 16(rio), x0, x2; \
559         vpxor 14 * 16(rio), x0, x1; \
560         vpxor 15 * 16(rio), x0, x0;
561
562 /* byteslice pre-whitened blocks and store to temporary memory */
563 #define inpack16_post(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
564                       y6, y7, mem_ab, mem_cd) \
565         byteslice_16x16b_fast(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, \
566                               y4, y5, y6, y7, (mem_ab), (mem_cd)); \
567         \
568         vmovdqu x0, 0 * 16(mem_ab); \
569         vmovdqu x1, 1 * 16(mem_ab); \
570         vmovdqu x2, 2 * 16(mem_ab); \
571         vmovdqu x3, 3 * 16(mem_ab); \
572         vmovdqu x4, 4 * 16(mem_ab); \
573         vmovdqu x5, 5 * 16(mem_ab); \
574         vmovdqu x6, 6 * 16(mem_ab); \
575         vmovdqu x7, 7 * 16(mem_ab); \
576         vmovdqu y0, 0 * 16(mem_cd); \
577         vmovdqu y1, 1 * 16(mem_cd); \
578         vmovdqu y2, 2 * 16(mem_cd); \
579         vmovdqu y3, 3 * 16(mem_cd); \
580         vmovdqu y4, 4 * 16(mem_cd); \
581         vmovdqu y5, 5 * 16(mem_cd); \
582         vmovdqu y6, 6 * 16(mem_cd); \
583         vmovdqu y7, 7 * 16(mem_cd);
584
585 /* de-byteslice, apply post-whitening and store blocks */
586 #define outunpack16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, \
587                     y5, y6, y7, key, stack_tmp0, stack_tmp1) \
588         byteslice_16x16b_fast(y0, y4, x0, x4, y1, y5, x1, x5, y2, y6, x2, x6, \
589                               y3, y7, x3, x7, stack_tmp0, stack_tmp1); \
590         \
591         vmovdqu x0, stack_tmp0; \
592         \
593         vmovq key, x0; \
594         vpshufb .Lpack_bswap RIP, x0, x0; \
595         \
596         vpxor x0, y7, y7; \
597         vpxor x0, y6, y6; \
598         vpxor x0, y5, y5; \
599         vpxor x0, y4, y4; \
600         vpxor x0, y3, y3; \
601         vpxor x0, y2, y2; \
602         vpxor x0, y1, y1; \
603         vpxor x0, y0, y0; \
604         vpxor x0, x7, x7; \
605         vpxor x0, x6, x6; \
606         vpxor x0, x5, x5; \
607         vpxor x0, x4, x4; \
608         vpxor x0, x3, x3; \
609         vpxor x0, x2, x2; \
610         vpxor x0, x1, x1; \
611         vpxor stack_tmp0, x0, x0;
612
613 #define write_output(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
614                      y6, y7, rio) \
615         vmovdqu x0, 0 * 16(rio); \
616         vmovdqu x1, 1 * 16(rio); \
617         vmovdqu x2, 2 * 16(rio); \
618         vmovdqu x3, 3 * 16(rio); \
619         vmovdqu x4, 4 * 16(rio); \
620         vmovdqu x5, 5 * 16(rio); \
621         vmovdqu x6, 6 * 16(rio); \
622         vmovdqu x7, 7 * 16(rio); \
623         vmovdqu y0, 8 * 16(rio); \
624         vmovdqu y1, 9 * 16(rio); \
625         vmovdqu y2, 10 * 16(rio); \
626         vmovdqu y3, 11 * 16(rio); \
627         vmovdqu y4, 12 * 16(rio); \
628         vmovdqu y5, 13 * 16(rio); \
629         vmovdqu y6, 14 * 16(rio); \
630         vmovdqu y7, 15 * 16(rio);
631
632 .text
633 .align 16
634
635 #define SHUFB_BYTES(idx) \
636         0 + (idx), 4 + (idx), 8 + (idx), 12 + (idx)
637
638 .Lshufb_16x16b:
639         .byte SHUFB_BYTES(0), SHUFB_BYTES(1), SHUFB_BYTES(2), SHUFB_BYTES(3);
640
641 .Lpack_bswap:
642         .long 0x00010203
643         .long 0x04050607
644         .long 0x80808080
645         .long 0x80808080
646
647 /* For CTR-mode IV byteswap */
648 .Lbswap128_mask:
649         .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
650
651 /*
652  * pre-SubByte transform
653  *
654  * pre-lookup for sbox1, sbox2, sbox3:
655  *   swap_bitendianness(
656  *       isom_map_camellia_to_aes(
657  *           camellia_f(
658  *               swap_bitendianess(in)
659  *           )
660  *       )
661  *   )
662  *
663  * (note: '⊕ 0xc5' inside camellia_f())
664  */
665 .Lpre_tf_lo_s1:
666         .byte 0x45, 0xe8, 0x40, 0xed, 0x2e, 0x83, 0x2b, 0x86
667         .byte 0x4b, 0xe6, 0x4e, 0xe3, 0x20, 0x8d, 0x25, 0x88
668 .Lpre_tf_hi_s1:
669         .byte 0x00, 0x51, 0xf1, 0xa0, 0x8a, 0xdb, 0x7b, 0x2a
670         .byte 0x09, 0x58, 0xf8, 0xa9, 0x83, 0xd2, 0x72, 0x23
671
672 /*
673  * pre-SubByte transform
674  *
675  * pre-lookup for sbox4:
676  *   swap_bitendianness(
677  *       isom_map_camellia_to_aes(
678  *           camellia_f(
679  *               swap_bitendianess(in <<< 1)
680  *           )
681  *       )
682  *   )
683  *
684  * (note: '⊕ 0xc5' inside camellia_f())
685  */
686 .Lpre_tf_lo_s4:
687         .byte 0x45, 0x40, 0x2e, 0x2b, 0x4b, 0x4e, 0x20, 0x25
688         .byte 0x14, 0x11, 0x7f, 0x7a, 0x1a, 0x1f, 0x71, 0x74
689 .Lpre_tf_hi_s4:
690         .byte 0x00, 0xf1, 0x8a, 0x7b, 0x09, 0xf8, 0x83, 0x72
691         .byte 0xad, 0x5c, 0x27, 0xd6, 0xa4, 0x55, 0x2e, 0xdf
692
693 /*
694  * post-SubByte transform
695  *
696  * post-lookup for sbox1, sbox4:
697  *  swap_bitendianness(
698  *      camellia_h(
699  *          isom_map_aes_to_camellia(
700  *              swap_bitendianness(
701  *                  aes_inverse_affine_transform(in)
702  *              )
703  *          )
704  *      )
705  *  )
706  *
707  * (note: '⊕ 0x6e' inside camellia_h())
708  */
709 .Lpost_tf_lo_s1:
710         .byte 0x3c, 0xcc, 0xcf, 0x3f, 0x32, 0xc2, 0xc1, 0x31
711         .byte 0xdc, 0x2c, 0x2f, 0xdf, 0xd2, 0x22, 0x21, 0xd1
712 .Lpost_tf_hi_s1:
713         .byte 0x00, 0xf9, 0x86, 0x7f, 0xd7, 0x2e, 0x51, 0xa8
714         .byte 0xa4, 0x5d, 0x22, 0xdb, 0x73, 0x8a, 0xf5, 0x0c
715
716 /*
717  * post-SubByte transform
718  *
719  * post-lookup for sbox2:
720  *  swap_bitendianness(
721  *      camellia_h(
722  *          isom_map_aes_to_camellia(
723  *              swap_bitendianness(
724  *                  aes_inverse_affine_transform(in)
725  *              )
726  *          )
727  *      )
728  *  ) <<< 1
729  *
730  * (note: '⊕ 0x6e' inside camellia_h())
731  */
732 .Lpost_tf_lo_s2:
733         .byte 0x78, 0x99, 0x9f, 0x7e, 0x64, 0x85, 0x83, 0x62
734         .byte 0xb9, 0x58, 0x5e, 0xbf, 0xa5, 0x44, 0x42, 0xa3
735 .Lpost_tf_hi_s2:
736         .byte 0x00, 0xf3, 0x0d, 0xfe, 0xaf, 0x5c, 0xa2, 0x51
737         .byte 0x49, 0xba, 0x44, 0xb7, 0xe6, 0x15, 0xeb, 0x18
738
739 /*
740  * post-SubByte transform
741  *
742  * post-lookup for sbox3:
743  *  swap_bitendianness(
744  *      camellia_h(
745  *          isom_map_aes_to_camellia(
746  *              swap_bitendianness(
747  *                  aes_inverse_affine_transform(in)
748  *              )
749  *          )
750  *      )
751  *  ) >>> 1
752  *
753  * (note: '⊕ 0x6e' inside camellia_h())
754  */
755 .Lpost_tf_lo_s3:
756         .byte 0x1e, 0x66, 0xe7, 0x9f, 0x19, 0x61, 0xe0, 0x98
757         .byte 0x6e, 0x16, 0x97, 0xef, 0x69, 0x11, 0x90, 0xe8
758 .Lpost_tf_hi_s3:
759         .byte 0x00, 0xfc, 0x43, 0xbf, 0xeb, 0x17, 0xa8, 0x54
760         .byte 0x52, 0xae, 0x11, 0xed, 0xb9, 0x45, 0xfa, 0x06
761
762 /* For isolating SubBytes from AESENCLAST, inverse shift row */
763 .Linv_shift_row:
764         .byte 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b
765         .byte 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03
766
767 /* shuffle mask for 8x8 byte transpose */
768 .Ltranspose_8x8_shuf:
769         .byte 0, 1, 4, 5, 2, 3, 6, 7, 8+0, 8+1, 8+4, 8+5, 8+2, 8+3, 8+6, 8+7
770
771 .align 4
772 /* 4-bit mask */
773 .L0f0f0f0f:
774         .long 0x0f0f0f0f
775
776
777 .align 8
778 ELF(.type   __camellia_enc_blk16,@function;)
779
780 __camellia_enc_blk16:
781         /* input:
782          *      %rdi: ctx, CTX
783          *      %rax: temporary storage, 256 bytes
784          *      %xmm0..%xmm15: 16 plaintext blocks
785          * output:
786          *      %xmm0..%xmm15: 16 encrypted blocks, order swapped:
787          *       7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
788          */
789
790         leaq 8 * 16(%rax), %rcx;
791
792         inpack16_post(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
793                       %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
794                       %xmm15, %rax, %rcx);
795
796         enc_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
797                      %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
798                      %xmm15, %rax, %rcx, 0);
799
800         fls16(%rax, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
801               %rcx, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
802               %xmm15,
803               ((key_table + (8) * 8) + 0)(CTX),
804               ((key_table + (8) * 8) + 4)(CTX),
805               ((key_table + (8) * 8) + 8)(CTX),
806               ((key_table + (8) * 8) + 12)(CTX));
807
808         enc_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
809                      %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
810                      %xmm15, %rax, %rcx, 8);
811
812         fls16(%rax, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
813               %rcx, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
814               %xmm15,
815               ((key_table + (16) * 8) + 0)(CTX),
816               ((key_table + (16) * 8) + 4)(CTX),
817               ((key_table + (16) * 8) + 8)(CTX),
818               ((key_table + (16) * 8) + 12)(CTX));
819
820         enc_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
821                      %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
822                      %xmm15, %rax, %rcx, 16);
823
824         movl $24, %r8d;
825         cmpl $128, key_bitlength(CTX);
826         jne .Lenc_max32;
827
828 .Lenc_done:
829         /* load CD for output */
830         vmovdqu 0 * 16(%rcx), %xmm8;
831         vmovdqu 1 * 16(%rcx), %xmm9;
832         vmovdqu 2 * 16(%rcx), %xmm10;
833         vmovdqu 3 * 16(%rcx), %xmm11;
834         vmovdqu 4 * 16(%rcx), %xmm12;
835         vmovdqu 5 * 16(%rcx), %xmm13;
836         vmovdqu 6 * 16(%rcx), %xmm14;
837         vmovdqu 7 * 16(%rcx), %xmm15;
838
839         outunpack16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
840                     %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
841                     %xmm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 16(%rax));
842
843         ret;
844
845 .align 8
846 .Lenc_max32:
847         movl $32, %r8d;
848
849         fls16(%rax, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
850               %rcx, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
851               %xmm15,
852               ((key_table + (24) * 8) + 0)(CTX),
853               ((key_table + (24) * 8) + 4)(CTX),
854               ((key_table + (24) * 8) + 8)(CTX),
855               ((key_table + (24) * 8) + 12)(CTX));
856
857         enc_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
858                      %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
859                      %xmm15, %rax, %rcx, 24);
860
861         jmp .Lenc_done;
862 ELF(.size __camellia_enc_blk16,.-__camellia_enc_blk16;)
863
864 .align 8
865 ELF(.type   __camellia_dec_blk16,@function;)
866
867 __camellia_dec_blk16:
868         /* input:
869          *      %rdi: ctx, CTX
870          *      %rax: temporary storage, 256 bytes
871          *      %r8d: 24 for 16 byte key, 32 for larger
872          *      %xmm0..%xmm15: 16 encrypted blocks
873          * output:
874          *      %xmm0..%xmm15: 16 plaintext blocks, order swapped:
875          *       7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
876          */
877
878         leaq 8 * 16(%rax), %rcx;
879
880         inpack16_post(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
881                       %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
882                       %xmm15, %rax, %rcx);
883
884         cmpl $32, %r8d;
885         je .Ldec_max32;
886
887 .Ldec_max24:
888         dec_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
889                      %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
890                      %xmm15, %rax, %rcx, 16);
891
892         fls16(%rax, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
893               %rcx, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
894               %xmm15,
895               ((key_table + (16) * 8) + 8)(CTX),
896               ((key_table + (16) * 8) + 12)(CTX),
897               ((key_table + (16) * 8) + 0)(CTX),
898               ((key_table + (16) * 8) + 4)(CTX));
899
900         dec_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
901                      %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
902                      %xmm15, %rax, %rcx, 8);
903
904         fls16(%rax, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
905               %rcx, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
906               %xmm15,
907               ((key_table + (8) * 8) + 8)(CTX),
908               ((key_table + (8) * 8) + 12)(CTX),
909               ((key_table + (8) * 8) + 0)(CTX),
910               ((key_table + (8) * 8) + 4)(CTX));
911
912         dec_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
913                      %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
914                      %xmm15, %rax, %rcx, 0);
915
916         /* load CD for output */
917         vmovdqu 0 * 16(%rcx), %xmm8;
918         vmovdqu 1 * 16(%rcx), %xmm9;
919         vmovdqu 2 * 16(%rcx), %xmm10;
920         vmovdqu 3 * 16(%rcx), %xmm11;
921         vmovdqu 4 * 16(%rcx), %xmm12;
922         vmovdqu 5 * 16(%rcx), %xmm13;
923         vmovdqu 6 * 16(%rcx), %xmm14;
924         vmovdqu 7 * 16(%rcx), %xmm15;
925
926         outunpack16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
927                     %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
928                     %xmm15, (key_table)(CTX), (%rax), 1 * 16(%rax));
929
930         ret;
931
932 .align 8
933 .Ldec_max32:
934         dec_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
935                      %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
936                      %xmm15, %rax, %rcx, 24);
937
938         fls16(%rax, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
939               %rcx, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
940               %xmm15,
941               ((key_table + (24) * 8) + 8)(CTX),
942               ((key_table + (24) * 8) + 12)(CTX),
943               ((key_table + (24) * 8) + 0)(CTX),
944               ((key_table + (24) * 8) + 4)(CTX));
945
946         jmp .Ldec_max24;
947 ELF(.size __camellia_dec_blk16,.-__camellia_dec_blk16;)
948
949 #define inc_le128(x, minus_one, tmp) \
950         vpcmpeqq minus_one, x, tmp; \
951         vpsubq minus_one, x, x; \
952         vpslldq $8, tmp, tmp; \
953         vpsubq tmp, x, x;
954
955 .align 8
956 .globl _gcry_camellia_aesni_avx_ctr_enc
957 ELF(.type   _gcry_camellia_aesni_avx_ctr_enc,@function;)
958
959 _gcry_camellia_aesni_avx_ctr_enc:
960         /* input:
961          *      %rdi: ctx, CTX
962          *      %rsi: dst (16 blocks)
963          *      %rdx: src (16 blocks)
964          *      %rcx: iv (big endian, 128bit)
965          */
966
967         pushq %rbp;
968         movq %rsp, %rbp;
969
970         vzeroupper;
971
972         subq $(16 * 16), %rsp;
973         andq $~31, %rsp;
974         movq %rsp, %rax;
975
976         vmovdqa .Lbswap128_mask RIP, %xmm14;
977
978         /* load IV and byteswap */
979         vmovdqu (%rcx), %xmm15;
980         vmovdqu %xmm15, 15 * 16(%rax);
981         vpshufb %xmm14, %xmm15, %xmm0; /* be => le */
982
983         vpcmpeqd %xmm15, %xmm15, %xmm15;
984         vpsrldq $8, %xmm15, %xmm15; /* low: -1, high: 0 */
985
986         /* construct IVs */
987         inc_le128(%xmm0, %xmm15, %xmm13);
988         vpshufb %xmm14, %xmm0, %xmm13;
989         vmovdqu %xmm13, 14 * 16(%rax);
990         inc_le128(%xmm0, %xmm15, %xmm13);
991         vpshufb %xmm14, %xmm0, %xmm13;
992         vmovdqu %xmm13, 13 * 16(%rax);
993         inc_le128(%xmm0, %xmm15, %xmm13);
994         vpshufb %xmm14, %xmm0, %xmm12;
995         inc_le128(%xmm0, %xmm15, %xmm13);
996         vpshufb %xmm14, %xmm0, %xmm11;
997         inc_le128(%xmm0, %xmm15, %xmm13);
998         vpshufb %xmm14, %xmm0, %xmm10;
999         inc_le128(%xmm0, %xmm15, %xmm13);
1000         vpshufb %xmm14, %xmm0, %xmm9;
1001         inc_le128(%xmm0, %xmm15, %xmm13);
1002         vpshufb %xmm14, %xmm0, %xmm8;
1003         inc_le128(%xmm0, %xmm15, %xmm13);
1004         vpshufb %xmm14, %xmm0, %xmm7;
1005         inc_le128(%xmm0, %xmm15, %xmm13);
1006         vpshufb %xmm14, %xmm0, %xmm6;
1007         inc_le128(%xmm0, %xmm15, %xmm13);
1008         vpshufb %xmm14, %xmm0, %xmm5;
1009         inc_le128(%xmm0, %xmm15, %xmm13);
1010         vpshufb %xmm14, %xmm0, %xmm4;
1011         inc_le128(%xmm0, %xmm15, %xmm13);
1012         vpshufb %xmm14, %xmm0, %xmm3;
1013         inc_le128(%xmm0, %xmm15, %xmm13);
1014         vpshufb %xmm14, %xmm0, %xmm2;
1015         inc_le128(%xmm0, %xmm15, %xmm13);
1016         vpshufb %xmm14, %xmm0, %xmm1;
1017         inc_le128(%xmm0, %xmm15, %xmm13);
1018         vmovdqa %xmm0, %xmm13;
1019         vpshufb %xmm14, %xmm0, %xmm0;
1020         inc_le128(%xmm13, %xmm15, %xmm14);
1021         vpshufb .Lbswap128_mask RIP, %xmm13, %xmm13; /* le => be */
1022         vmovdqu %xmm13, (%rcx);
1023
1024         /* inpack16_pre: */
1025         vmovq (key_table)(CTX), %xmm15;
1026         vpshufb .Lpack_bswap RIP, %xmm15, %xmm15;
1027         vpxor %xmm0, %xmm15, %xmm0;
1028         vpxor %xmm1, %xmm15, %xmm1;
1029         vpxor %xmm2, %xmm15, %xmm2;
1030         vpxor %xmm3, %xmm15, %xmm3;
1031         vpxor %xmm4, %xmm15, %xmm4;
1032         vpxor %xmm5, %xmm15, %xmm5;
1033         vpxor %xmm6, %xmm15, %xmm6;
1034         vpxor %xmm7, %xmm15, %xmm7;
1035         vpxor %xmm8, %xmm15, %xmm8;
1036         vpxor %xmm9, %xmm15, %xmm9;
1037         vpxor %xmm10, %xmm15, %xmm10;
1038         vpxor %xmm11, %xmm15, %xmm11;
1039         vpxor %xmm12, %xmm15, %xmm12;
1040         vpxor 13 * 16(%rax), %xmm15, %xmm13;
1041         vpxor 14 * 16(%rax), %xmm15, %xmm14;
1042         vpxor 15 * 16(%rax), %xmm15, %xmm15;
1043
1044         call __camellia_enc_blk16;
1045
1046         vpxor 0 * 16(%rdx), %xmm7, %xmm7;
1047         vpxor 1 * 16(%rdx), %xmm6, %xmm6;
1048         vpxor 2 * 16(%rdx), %xmm5, %xmm5;
1049         vpxor 3 * 16(%rdx), %xmm4, %xmm4;
1050         vpxor 4 * 16(%rdx), %xmm3, %xmm3;
1051         vpxor 5 * 16(%rdx), %xmm2, %xmm2;
1052         vpxor 6 * 16(%rdx), %xmm1, %xmm1;
1053         vpxor 7 * 16(%rdx), %xmm0, %xmm0;
1054         vpxor 8 * 16(%rdx), %xmm15, %xmm15;
1055         vpxor 9 * 16(%rdx), %xmm14, %xmm14;
1056         vpxor 10 * 16(%rdx), %xmm13, %xmm13;
1057         vpxor 11 * 16(%rdx), %xmm12, %xmm12;
1058         vpxor 12 * 16(%rdx), %xmm11, %xmm11;
1059         vpxor 13 * 16(%rdx), %xmm10, %xmm10;
1060         vpxor 14 * 16(%rdx), %xmm9, %xmm9;
1061         vpxor 15 * 16(%rdx), %xmm8, %xmm8;
1062
1063         write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
1064                      %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
1065                      %xmm8, %rsi);
1066
1067         vzeroall;
1068
1069         leave;
1070         ret;
1071 ELF(.size _gcry_camellia_aesni_avx_ctr_enc,.-_gcry_camellia_aesni_avx_ctr_enc;)
1072
1073 .align 8
1074 .globl _gcry_camellia_aesni_avx_cbc_dec
1075 ELF(.type   _gcry_camellia_aesni_avx_cbc_dec,@function;)
1076
1077 _gcry_camellia_aesni_avx_cbc_dec:
1078         /* input:
1079          *      %rdi: ctx, CTX
1080          *      %rsi: dst (16 blocks)
1081          *      %rdx: src (16 blocks)
1082          *      %rcx: iv
1083          */
1084
1085         pushq %rbp;
1086         movq %rsp, %rbp;
1087
1088         vzeroupper;
1089
1090         movq %rcx, %r9;
1091
1092         cmpl $128, key_bitlength(CTX);
1093         movl $32, %r8d;
1094         movl $24, %eax;
1095         cmovel %eax, %r8d; /* max */
1096
1097         inpack16_pre(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
1098                      %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
1099                      %xmm15, %rdx, (key_table)(CTX, %r8, 8));
1100
1101         subq $(16 * 16), %rsp;
1102         andq $~31, %rsp;
1103         movq %rsp, %rax;
1104
1105         call __camellia_dec_blk16;
1106
1107         /* XOR output with IV */
1108         vpxor (%r9), %xmm7, %xmm7;
1109         vpxor (0 * 16)(%rdx), %xmm6, %xmm6;
1110         vpxor (1 * 16)(%rdx), %xmm5, %xmm5;
1111         vpxor (2 * 16)(%rdx), %xmm4, %xmm4;
1112         vpxor (3 * 16)(%rdx), %xmm3, %xmm3;
1113         vpxor (4 * 16)(%rdx), %xmm2, %xmm2;
1114         vpxor (5 * 16)(%rdx), %xmm1, %xmm1;
1115         vpxor (6 * 16)(%rdx), %xmm0, %xmm0;
1116         vpxor (7 * 16)(%rdx), %xmm15, %xmm15;
1117         vpxor (8 * 16)(%rdx), %xmm14, %xmm14;
1118         vpxor (9 * 16)(%rdx), %xmm13, %xmm13;
1119         vpxor (10 * 16)(%rdx), %xmm12, %xmm12;
1120         vpxor (11 * 16)(%rdx), %xmm11, %xmm11;
1121         vpxor (12 * 16)(%rdx), %xmm10, %xmm10;
1122         vpxor (13 * 16)(%rdx), %xmm9, %xmm9;
1123         vpxor (14 * 16)(%rdx), %xmm8, %xmm8;
1124         movq (15 * 16 + 0)(%rdx), %r10;
1125         movq (15 * 16 + 8)(%rdx), %r11;
1126
1127         write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
1128                      %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
1129                      %xmm8, %rsi);
1130
1131         /* store new IV */
1132         movq %r10, (0)(%r9);
1133         movq %r11, (8)(%r9);
1134
1135         vzeroall;
1136
1137         leave;
1138         ret;
1139 ELF(.size _gcry_camellia_aesni_avx_cbc_dec,.-_gcry_camellia_aesni_avx_cbc_dec;)
1140
1141 .align 8
1142 .globl _gcry_camellia_aesni_avx_cfb_dec
1143 ELF(.type   _gcry_camellia_aesni_avx_cfb_dec,@function;)
1144
1145 _gcry_camellia_aesni_avx_cfb_dec:
1146         /* input:
1147          *      %rdi: ctx, CTX
1148          *      %rsi: dst (16 blocks)
1149          *      %rdx: src (16 blocks)
1150          *      %rcx: iv
1151          */
1152
1153         pushq %rbp;
1154         movq %rsp, %rbp;
1155
1156         vzeroupper;
1157
1158         subq $(16 * 16), %rsp;
1159         andq $~31, %rsp;
1160         movq %rsp, %rax;
1161
1162         /* inpack16_pre: */
1163         vmovq (key_table)(CTX), %xmm0;
1164         vpshufb .Lpack_bswap RIP, %xmm0, %xmm0;
1165         vpxor (%rcx), %xmm0, %xmm15;
1166         vmovdqu 15 * 16(%rdx), %xmm1;
1167         vmovdqu %xmm1, (%rcx); /* store new IV */
1168         vpxor 0 * 16(%rdx), %xmm0, %xmm14;
1169         vpxor 1 * 16(%rdx), %xmm0, %xmm13;
1170         vpxor 2 * 16(%rdx), %xmm0, %xmm12;
1171         vpxor 3 * 16(%rdx), %xmm0, %xmm11;
1172         vpxor 4 * 16(%rdx), %xmm0, %xmm10;
1173         vpxor 5 * 16(%rdx), %xmm0, %xmm9;
1174         vpxor 6 * 16(%rdx), %xmm0, %xmm8;
1175         vpxor 7 * 16(%rdx), %xmm0, %xmm7;
1176         vpxor 8 * 16(%rdx), %xmm0, %xmm6;
1177         vpxor 9 * 16(%rdx), %xmm0, %xmm5;
1178         vpxor 10 * 16(%rdx), %xmm0, %xmm4;
1179         vpxor 11 * 16(%rdx), %xmm0, %xmm3;
1180         vpxor 12 * 16(%rdx), %xmm0, %xmm2;
1181         vpxor 13 * 16(%rdx), %xmm0, %xmm1;
1182         vpxor 14 * 16(%rdx), %xmm0, %xmm0;
1183
1184         call __camellia_enc_blk16;
1185
1186         vpxor 0 * 16(%rdx), %xmm7, %xmm7;
1187         vpxor 1 * 16(%rdx), %xmm6, %xmm6;
1188         vpxor 2 * 16(%rdx), %xmm5, %xmm5;
1189         vpxor 3 * 16(%rdx), %xmm4, %xmm4;
1190         vpxor 4 * 16(%rdx), %xmm3, %xmm3;
1191         vpxor 5 * 16(%rdx), %xmm2, %xmm2;
1192         vpxor 6 * 16(%rdx), %xmm1, %xmm1;
1193         vpxor 7 * 16(%rdx), %xmm0, %xmm0;
1194         vpxor 8 * 16(%rdx), %xmm15, %xmm15;
1195         vpxor 9 * 16(%rdx), %xmm14, %xmm14;
1196         vpxor 10 * 16(%rdx), %xmm13, %xmm13;
1197         vpxor 11 * 16(%rdx), %xmm12, %xmm12;
1198         vpxor 12 * 16(%rdx), %xmm11, %xmm11;
1199         vpxor 13 * 16(%rdx), %xmm10, %xmm10;
1200         vpxor 14 * 16(%rdx), %xmm9, %xmm9;
1201         vpxor 15 * 16(%rdx), %xmm8, %xmm8;
1202
1203         write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
1204                      %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
1205                      %xmm8, %rsi);
1206
1207         vzeroall;
1208
1209         leave;
1210         ret;
1211 ELF(.size _gcry_camellia_aesni_avx_cfb_dec,.-_gcry_camellia_aesni_avx_cfb_dec;)
1212
1213 .align 8
1214 .globl _gcry_camellia_aesni_avx_ocb_enc
1215 ELF(.type   _gcry_camellia_aesni_avx_ocb_enc,@function;)
1216
1217 _gcry_camellia_aesni_avx_ocb_enc:
1218         /* input:
1219          *      %rdi: ctx, CTX
1220          *      %rsi: dst (16 blocks)
1221          *      %rdx: src (16 blocks)
1222          *      %rcx: offset
1223          *      %r8 : checksum
1224          *      %r9 : L pointers (void *L[16])
1225          */
1226
1227         pushq %rbp;
1228         movq %rsp, %rbp;
1229
1230         vzeroupper;
1231
1232         subq $(16 * 16 + 4 * 8), %rsp;
1233         andq $~31, %rsp;
1234         movq %rsp, %rax;
1235
1236         movq %r10, (16 * 16 + 0 * 8)(%rax);
1237         movq %r11, (16 * 16 + 1 * 8)(%rax);
1238         movq %r12, (16 * 16 + 2 * 8)(%rax);
1239         movq %r13, (16 * 16 + 3 * 8)(%rax);
1240
1241         vmovdqu (%rcx), %xmm14;
1242         vmovdqu (%r8), %xmm15;
1243
1244         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
1245         /* Checksum_i = Checksum_{i-1} xor P_i  */
1246         /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
1247
1248 #define OCB_INPUT(n, lreg, xreg) \
1249           vmovdqu (n * 16)(%rdx), xreg; \
1250           vpxor (lreg), %xmm14, %xmm14; \
1251           vpxor xreg, %xmm15, %xmm15; \
1252           vpxor xreg, %xmm14, xreg; \
1253           vmovdqu %xmm14, (n * 16)(%rsi);
1254         movq (0 * 8)(%r9), %r10;
1255         movq (1 * 8)(%r9), %r11;
1256         movq (2 * 8)(%r9), %r12;
1257         movq (3 * 8)(%r9), %r13;
1258         OCB_INPUT(0, %r10, %xmm0);
1259         vmovdqu %xmm0, (15 * 16)(%rax);
1260         OCB_INPUT(1, %r11, %xmm0);
1261         vmovdqu %xmm0, (14 * 16)(%rax);
1262         OCB_INPUT(2, %r12, %xmm13);
1263         OCB_INPUT(3, %r13, %xmm12);
1264         movq (4 * 8)(%r9), %r10;
1265         movq (5 * 8)(%r9), %r11;
1266         movq (6 * 8)(%r9), %r12;
1267         movq (7 * 8)(%r9), %r13;
1268         OCB_INPUT(4, %r10, %xmm11);
1269         OCB_INPUT(5, %r11, %xmm10);
1270         OCB_INPUT(6, %r12, %xmm9);
1271         OCB_INPUT(7, %r13, %xmm8);
1272         movq (8 * 8)(%r9), %r10;
1273         movq (9 * 8)(%r9), %r11;
1274         movq (10 * 8)(%r9), %r12;
1275         movq (11 * 8)(%r9), %r13;
1276         OCB_INPUT(8, %r10, %xmm7);
1277         OCB_INPUT(9, %r11, %xmm6);
1278         OCB_INPUT(10, %r12, %xmm5);
1279         OCB_INPUT(11, %r13, %xmm4);
1280         movq (12 * 8)(%r9), %r10;
1281         movq (13 * 8)(%r9), %r11;
1282         movq (14 * 8)(%r9), %r12;
1283         movq (15 * 8)(%r9), %r13;
1284         OCB_INPUT(12, %r10, %xmm3);
1285         OCB_INPUT(13, %r11, %xmm2);
1286         OCB_INPUT(14, %r12, %xmm1);
1287         OCB_INPUT(15, %r13, %xmm0);
1288 #undef OCB_INPUT
1289
1290         vmovdqu %xmm14, (%rcx);
1291         vmovdqu %xmm15, (%r8);
1292
1293         /* inpack16_pre: */
1294         vmovq (key_table)(CTX), %xmm15;
1295         vpshufb .Lpack_bswap RIP, %xmm15, %xmm15;
1296         vpxor %xmm0, %xmm15, %xmm0;
1297         vpxor %xmm1, %xmm15, %xmm1;
1298         vpxor %xmm2, %xmm15, %xmm2;
1299         vpxor %xmm3, %xmm15, %xmm3;
1300         vpxor %xmm4, %xmm15, %xmm4;
1301         vpxor %xmm5, %xmm15, %xmm5;
1302         vpxor %xmm6, %xmm15, %xmm6;
1303         vpxor %xmm7, %xmm15, %xmm7;
1304         vpxor %xmm8, %xmm15, %xmm8;
1305         vpxor %xmm9, %xmm15, %xmm9;
1306         vpxor %xmm10, %xmm15, %xmm10;
1307         vpxor %xmm11, %xmm15, %xmm11;
1308         vpxor %xmm12, %xmm15, %xmm12;
1309         vpxor %xmm13, %xmm15, %xmm13;
1310         vpxor 14 * 16(%rax), %xmm15, %xmm14;
1311         vpxor 15 * 16(%rax), %xmm15, %xmm15;
1312
1313         call __camellia_enc_blk16;
1314
1315         vpxor 0 * 16(%rsi), %xmm7, %xmm7;
1316         vpxor 1 * 16(%rsi), %xmm6, %xmm6;
1317         vpxor 2 * 16(%rsi), %xmm5, %xmm5;
1318         vpxor 3 * 16(%rsi), %xmm4, %xmm4;
1319         vpxor 4 * 16(%rsi), %xmm3, %xmm3;
1320         vpxor 5 * 16(%rsi), %xmm2, %xmm2;
1321         vpxor 6 * 16(%rsi), %xmm1, %xmm1;
1322         vpxor 7 * 16(%rsi), %xmm0, %xmm0;
1323         vpxor 8 * 16(%rsi), %xmm15, %xmm15;
1324         vpxor 9 * 16(%rsi), %xmm14, %xmm14;
1325         vpxor 10 * 16(%rsi), %xmm13, %xmm13;
1326         vpxor 11 * 16(%rsi), %xmm12, %xmm12;
1327         vpxor 12 * 16(%rsi), %xmm11, %xmm11;
1328         vpxor 13 * 16(%rsi), %xmm10, %xmm10;
1329         vpxor 14 * 16(%rsi), %xmm9, %xmm9;
1330         vpxor 15 * 16(%rsi), %xmm8, %xmm8;
1331
1332         write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
1333                      %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
1334                      %xmm8, %rsi);
1335
1336         vzeroall;
1337
1338         movq (16 * 16 + 0 * 8)(%rax), %r10;
1339         movq (16 * 16 + 1 * 8)(%rax), %r11;
1340         movq (16 * 16 + 2 * 8)(%rax), %r12;
1341         movq (16 * 16 + 3 * 8)(%rax), %r13;
1342
1343         leave;
1344         ret;
1345 ELF(.size _gcry_camellia_aesni_avx_ocb_enc,.-_gcry_camellia_aesni_avx_ocb_enc;)
1346
1347 .align 8
1348 .globl _gcry_camellia_aesni_avx_ocb_dec
1349 ELF(.type   _gcry_camellia_aesni_avx_ocb_dec,@function;)
1350
1351 _gcry_camellia_aesni_avx_ocb_dec:
1352         /* input:
1353          *      %rdi: ctx, CTX
1354          *      %rsi: dst (16 blocks)
1355          *      %rdx: src (16 blocks)
1356          *      %rcx: offset
1357          *      %r8 : checksum
1358          *      %r9 : L pointers (void *L[16])
1359          */
1360
1361         pushq %rbp;
1362         movq %rsp, %rbp;
1363
1364         vzeroupper;
1365
1366         subq $(16 * 16 + 4 * 8), %rsp;
1367         andq $~31, %rsp;
1368         movq %rsp, %rax;
1369
1370         movq %r10, (16 * 16 + 0 * 8)(%rax);
1371         movq %r11, (16 * 16 + 1 * 8)(%rax);
1372         movq %r12, (16 * 16 + 2 * 8)(%rax);
1373         movq %r13, (16 * 16 + 3 * 8)(%rax);
1374
1375         vmovdqu (%rcx), %xmm15;
1376
1377         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
1378         /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)  */
1379
1380 #define OCB_INPUT(n, lreg, xreg) \
1381           vmovdqu (n * 16)(%rdx), xreg; \
1382           vpxor (lreg), %xmm15, %xmm15; \
1383           vpxor xreg, %xmm15, xreg; \
1384           vmovdqu %xmm15, (n * 16)(%rsi);
1385         movq (0 * 8)(%r9), %r10;
1386         movq (1 * 8)(%r9), %r11;
1387         movq (2 * 8)(%r9), %r12;
1388         movq (3 * 8)(%r9), %r13;
1389         OCB_INPUT(0, %r10, %xmm0);
1390         vmovdqu %xmm0, (15 * 16)(%rax);
1391         OCB_INPUT(1, %r11, %xmm14);
1392         OCB_INPUT(2, %r12, %xmm13);
1393         OCB_INPUT(3, %r13, %xmm12);
1394         movq (4 * 8)(%r9), %r10;
1395         movq (5 * 8)(%r9), %r11;
1396         movq (6 * 8)(%r9), %r12;
1397         movq (7 * 8)(%r9), %r13;
1398         OCB_INPUT(4, %r10, %xmm11);
1399         OCB_INPUT(5, %r11, %xmm10);
1400         OCB_INPUT(6, %r12, %xmm9);
1401         OCB_INPUT(7, %r13, %xmm8);
1402         movq (8 * 8)(%r9), %r10;
1403         movq (9 * 8)(%r9), %r11;
1404         movq (10 * 8)(%r9), %r12;
1405         movq (11 * 8)(%r9), %r13;
1406         OCB_INPUT(8, %r10, %xmm7);
1407         OCB_INPUT(9, %r11, %xmm6);
1408         OCB_INPUT(10, %r12, %xmm5);
1409         OCB_INPUT(11, %r13, %xmm4);
1410         movq (12 * 8)(%r9), %r10;
1411         movq (13 * 8)(%r9), %r11;
1412         movq (14 * 8)(%r9), %r12;
1413         movq (15 * 8)(%r9), %r13;
1414         OCB_INPUT(12, %r10, %xmm3);
1415         OCB_INPUT(13, %r11, %xmm2);
1416         OCB_INPUT(14, %r12, %xmm1);
1417         OCB_INPUT(15, %r13, %xmm0);
1418 #undef OCB_INPUT
1419
1420         vmovdqu %xmm15, (%rcx);
1421
1422         movq %r8, %r10;
1423
1424         cmpl $128, key_bitlength(CTX);
1425         movl $32, %r8d;
1426         movl $24, %r9d;
1427         cmovel %r9d, %r8d; /* max */
1428
1429         /* inpack16_pre: */
1430         vmovq (key_table)(CTX, %r8, 8), %xmm15;
1431         vpshufb .Lpack_bswap RIP, %xmm15, %xmm15;
1432         vpxor %xmm0, %xmm15, %xmm0;
1433         vpxor %xmm1, %xmm15, %xmm1;
1434         vpxor %xmm2, %xmm15, %xmm2;
1435         vpxor %xmm3, %xmm15, %xmm3;
1436         vpxor %xmm4, %xmm15, %xmm4;
1437         vpxor %xmm5, %xmm15, %xmm5;
1438         vpxor %xmm6, %xmm15, %xmm6;
1439         vpxor %xmm7, %xmm15, %xmm7;
1440         vpxor %xmm8, %xmm15, %xmm8;
1441         vpxor %xmm9, %xmm15, %xmm9;
1442         vpxor %xmm10, %xmm15, %xmm10;
1443         vpxor %xmm11, %xmm15, %xmm11;
1444         vpxor %xmm12, %xmm15, %xmm12;
1445         vpxor %xmm13, %xmm15, %xmm13;
1446         vpxor %xmm14, %xmm15, %xmm14;
1447         vpxor 15 * 16(%rax), %xmm15, %xmm15;
1448
1449         call __camellia_dec_blk16;
1450
1451         vpxor 0 * 16(%rsi), %xmm7, %xmm7;
1452         vpxor 1 * 16(%rsi), %xmm6, %xmm6;
1453         vpxor 2 * 16(%rsi), %xmm5, %xmm5;
1454         vpxor 3 * 16(%rsi), %xmm4, %xmm4;
1455         vpxor 4 * 16(%rsi), %xmm3, %xmm3;
1456         vpxor 5 * 16(%rsi), %xmm2, %xmm2;
1457         vpxor 6 * 16(%rsi), %xmm1, %xmm1;
1458         vpxor 7 * 16(%rsi), %xmm0, %xmm0;
1459         vmovdqu %xmm7, (7 * 16)(%rax);
1460         vpxor 8 * 16(%rsi), %xmm15, %xmm15;
1461         vpxor 9 * 16(%rsi), %xmm14, %xmm14;
1462         vpxor 10 * 16(%rsi), %xmm13, %xmm13;
1463         vpxor 11 * 16(%rsi), %xmm12, %xmm12;
1464         vpxor 12 * 16(%rsi), %xmm11, %xmm11;
1465         vpxor 13 * 16(%rsi), %xmm10, %xmm10;
1466         vpxor 14 * 16(%rsi), %xmm9, %xmm9;
1467         vpxor 15 * 16(%rsi), %xmm8, %xmm8;
1468
1469         /* Checksum_i = Checksum_{i-1} xor P_i  */
1470
1471         vpxor (%r10), %xmm7, %xmm7;
1472         vpxor %xmm6, %xmm7, %xmm7;
1473         vpxor %xmm5, %xmm7, %xmm7;
1474         vpxor %xmm4, %xmm7, %xmm7;
1475         vpxor %xmm3, %xmm7, %xmm7;
1476         vpxor %xmm2, %xmm7, %xmm7;
1477         vpxor %xmm1, %xmm7, %xmm7;
1478         vpxor %xmm0, %xmm7, %xmm7;
1479         vpxor %xmm15, %xmm7, %xmm7;
1480         vpxor %xmm14, %xmm7, %xmm7;
1481         vpxor %xmm13, %xmm7, %xmm7;
1482         vpxor %xmm12, %xmm7, %xmm7;
1483         vpxor %xmm11, %xmm7, %xmm7;
1484         vpxor %xmm10, %xmm7, %xmm7;
1485         vpxor %xmm9, %xmm7, %xmm7;
1486         vpxor %xmm8, %xmm7, %xmm7;
1487         vmovdqu %xmm7, (%r10);
1488         vmovdqu (7 * 16)(%rax), %xmm7;
1489
1490         write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
1491                      %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
1492                      %xmm8, %rsi);
1493
1494         vzeroall;
1495
1496         movq (16 * 16 + 0 * 8)(%rax), %r10;
1497         movq (16 * 16 + 1 * 8)(%rax), %r11;
1498         movq (16 * 16 + 2 * 8)(%rax), %r12;
1499         movq (16 * 16 + 3 * 8)(%rax), %r13;
1500
1501         leave;
1502         ret;
1503 ELF(.size _gcry_camellia_aesni_avx_ocb_dec,.-_gcry_camellia_aesni_avx_ocb_dec;)
1504
1505 .align 8
1506 .globl _gcry_camellia_aesni_avx_ocb_auth
1507 ELF(.type   _gcry_camellia_aesni_avx_ocb_auth,@function;)
1508
1509 _gcry_camellia_aesni_avx_ocb_auth:
1510         /* input:
1511          *      %rdi: ctx, CTX
1512          *      %rsi: abuf (16 blocks)
1513          *      %rdx: offset
1514          *      %rcx: checksum
1515          *      %r8 : L pointers (void *L[16])
1516          */
1517
1518         pushq %rbp;
1519         movq %rsp, %rbp;
1520
1521         vzeroupper;
1522
1523         subq $(16 * 16 + 4 * 8), %rsp;
1524         andq $~31, %rsp;
1525         movq %rsp, %rax;
1526
1527         movq %r10, (16 * 16 + 0 * 8)(%rax);
1528         movq %r11, (16 * 16 + 1 * 8)(%rax);
1529         movq %r12, (16 * 16 + 2 * 8)(%rax);
1530         movq %r13, (16 * 16 + 3 * 8)(%rax);
1531
1532         vmovdqu (%rdx), %xmm15;
1533
1534         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
1535         /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i)  */
1536
1537 #define OCB_INPUT(n, lreg, xreg) \
1538           vmovdqu (n * 16)(%rsi), xreg; \
1539           vpxor (lreg), %xmm15, %xmm15; \
1540           vpxor xreg, %xmm15, xreg;
1541
1542         movq (0 * 8)(%r8), %r10;
1543         movq (1 * 8)(%r8), %r11;
1544         movq (2 * 8)(%r8), %r12;
1545         movq (3 * 8)(%r8), %r13;
1546         OCB_INPUT(0, %r10, %xmm0);
1547         vmovdqu %xmm0, (15 * 16)(%rax);
1548         OCB_INPUT(1, %r11, %xmm14);
1549         OCB_INPUT(2, %r12, %xmm13);
1550         OCB_INPUT(3, %r13, %xmm12);
1551         movq (4 * 8)(%r8), %r10;
1552         movq (5 * 8)(%r8), %r11;
1553         movq (6 * 8)(%r8), %r12;
1554         movq (7 * 8)(%r8), %r13;
1555         OCB_INPUT(4, %r10, %xmm11);
1556         OCB_INPUT(5, %r11, %xmm10);
1557         OCB_INPUT(6, %r12, %xmm9);
1558         OCB_INPUT(7, %r13, %xmm8);
1559         movq (8 * 8)(%r8), %r10;
1560         movq (9 * 8)(%r8), %r11;
1561         movq (10 * 8)(%r8), %r12;
1562         movq (11 * 8)(%r8), %r13;
1563         OCB_INPUT(8, %r10, %xmm7);
1564         OCB_INPUT(9, %r11, %xmm6);
1565         OCB_INPUT(10, %r12, %xmm5);
1566         OCB_INPUT(11, %r13, %xmm4);
1567         movq (12 * 8)(%r8), %r10;
1568         movq (13 * 8)(%r8), %r11;
1569         movq (14 * 8)(%r8), %r12;
1570         movq (15 * 8)(%r8), %r13;
1571         OCB_INPUT(12, %r10, %xmm3);
1572         OCB_INPUT(13, %r11, %xmm2);
1573         OCB_INPUT(14, %r12, %xmm1);
1574         OCB_INPUT(15, %r13, %xmm0);
1575 #undef OCB_INPUT
1576
1577         vmovdqu %xmm15, (%rdx);
1578
1579         movq %rcx, %r10;
1580
1581         /* inpack16_pre: */
1582         vmovq (key_table)(CTX), %xmm15;
1583         vpshufb .Lpack_bswap RIP, %xmm15, %xmm15;
1584         vpxor %xmm0, %xmm15, %xmm0;
1585         vpxor %xmm1, %xmm15, %xmm1;
1586         vpxor %xmm2, %xmm15, %xmm2;
1587         vpxor %xmm3, %xmm15, %xmm3;
1588         vpxor %xmm4, %xmm15, %xmm4;
1589         vpxor %xmm5, %xmm15, %xmm5;
1590         vpxor %xmm6, %xmm15, %xmm6;
1591         vpxor %xmm7, %xmm15, %xmm7;
1592         vpxor %xmm8, %xmm15, %xmm8;
1593         vpxor %xmm9, %xmm15, %xmm9;
1594         vpxor %xmm10, %xmm15, %xmm10;
1595         vpxor %xmm11, %xmm15, %xmm11;
1596         vpxor %xmm12, %xmm15, %xmm12;
1597         vpxor %xmm13, %xmm15, %xmm13;
1598         vpxor %xmm14, %xmm15, %xmm14;
1599         vpxor 15 * 16(%rax), %xmm15, %xmm15;
1600
1601         call __camellia_enc_blk16;
1602
1603         vpxor %xmm7, %xmm6, %xmm6;
1604         vpxor %xmm5, %xmm4, %xmm4;
1605         vpxor %xmm3, %xmm2, %xmm2;
1606         vpxor %xmm1, %xmm0, %xmm0;
1607         vpxor %xmm15, %xmm14, %xmm14;
1608         vpxor %xmm13, %xmm12, %xmm12;
1609         vpxor %xmm11, %xmm10, %xmm10;
1610         vpxor %xmm9, %xmm8, %xmm8;
1611
1612         vpxor %xmm6, %xmm4, %xmm4;
1613         vpxor %xmm2, %xmm0, %xmm0;
1614         vpxor %xmm14, %xmm12, %xmm12;
1615         vpxor %xmm10, %xmm8, %xmm8;
1616
1617         vpxor %xmm4, %xmm0, %xmm0;
1618         vpxor %xmm12, %xmm8, %xmm8;
1619
1620         vpxor %xmm0, %xmm8, %xmm0;
1621         vpxor (%r10), %xmm0, %xmm0;
1622         vmovdqu %xmm0, (%r10);
1623
1624         vzeroall;
1625
1626         movq (16 * 16 + 0 * 8)(%rax), %r10;
1627         movq (16 * 16 + 1 * 8)(%rax), %r11;
1628         movq (16 * 16 + 2 * 8)(%rax), %r12;
1629         movq (16 * 16 + 3 * 8)(%rax), %r13;
1630
1631         leave;
1632         ret;
1633 ELF(.size _gcry_camellia_aesni_avx_ocb_auth,.-_gcry_camellia_aesni_avx_ocb_auth;)
1634
1635 /*
1636  * IN:
1637  *  ab: 64-bit AB state
1638  *  cd: 64-bit CD state
1639  */
1640 #define camellia_f(ab, x, t0, t1, t2, t3, t4, inv_shift_row, sbox4mask, \
1641                    _0f0f0f0fmask, pre_s1lo_mask, pre_s1hi_mask, key) \
1642         vmovq key, t0; \
1643         vpxor x, x, t3; \
1644         \
1645         vpxor ab, t0, x; \
1646         \
1647         /* \
1648          * S-function with AES subbytes \
1649          */ \
1650         \
1651         /* input rotation for sbox4 (<<< 1) */ \
1652         vpand x, sbox4mask, t0; \
1653         vpandn x, sbox4mask, x; \
1654         vpaddw t0, t0, t1; \
1655         vpsrlw $7, t0, t0; \
1656         vpor t0, t1, t0; \
1657         vpand sbox4mask, t0, t0; \
1658         vpor t0, x, x; \
1659         \
1660         vmovdqa .Lpost_tf_lo_s1 RIP, t0; \
1661         vmovdqa .Lpost_tf_hi_s1 RIP, t1; \
1662         \
1663         /* prefilter sboxes */ \
1664         filter_8bit(x, pre_s1lo_mask, pre_s1hi_mask, _0f0f0f0fmask, t2); \
1665         \
1666         /* AES subbytes + AES shift rows + AES inv shift rows */ \
1667         vaesenclast t3, x, x; \
1668         \
1669         /* postfilter sboxes */ \
1670         filter_8bit(x, t0, t1, _0f0f0f0fmask, t2); \
1671         \
1672         /* output rotation for sbox2 (<<< 1) */ \
1673         /* output rotation for sbox3 (>>> 1) */ \
1674         vpshufb inv_shift_row, x, t1; \
1675         vpshufb .Lsp0044440444044404mask RIP, x, t4; \
1676         vpshufb .Lsp1110111010011110mask RIP, x, x; \
1677         vpaddb t1, t1, t2; \
1678         vpsrlw $7, t1, t0; \
1679         vpsllw $7, t1, t3; \
1680         vpor t0, t2, t0; \
1681         vpsrlw $1, t1, t1; \
1682         vpshufb .Lsp0222022222000222mask RIP, t0, t0; \
1683         vpor t1, t3, t1; \
1684         \
1685         vpxor x, t4, t4; \
1686         vpshufb .Lsp3033303303303033mask RIP, t1, t1; \
1687         vpxor t4, t0, t0; \
1688         vpxor t1, t0, t0; \
1689         vpsrldq $8, t0, x; \
1690         vpxor t0, x, x;
1691
1692 #define vec_rol128(in, out, nrol, t0) \
1693         vpshufd $0x4e, in, out; \
1694         vpsllq $(nrol), in, t0; \
1695         vpsrlq $(64-(nrol)), out, out; \
1696         vpaddd t0, out, out;
1697
1698 #define vec_ror128(in, out, nror, t0) \
1699         vpshufd $0x4e, in, out; \
1700         vpsrlq $(nror), in, t0; \
1701         vpsllq $(64-(nror)), out, out; \
1702         vpaddd t0, out, out;
1703
1704
1705 .align 16
1706 .Linv_shift_row_and_unpcklbw:
1707         .byte 0x00, 0xff, 0x0d, 0xff, 0x0a, 0xff, 0x07, 0xff
1708         .byte 0x04, 0xff, 0x01, 0xff, 0x0e, 0xff, 0x0b, 0xff
1709 .Lsp0044440444044404mask:
1710         .long 0xffff0404, 0x0404ff04;
1711         .long 0x0d0dff0d, 0x0d0dff0d;
1712 .Lsp1110111010011110mask:
1713         .long 0x000000ff, 0x000000ff;
1714         .long 0x0bffff0b, 0x0b0b0bff;
1715 .Lsp0222022222000222mask:
1716         .long 0xff060606, 0xff060606;
1717         .long 0x0c0cffff, 0xff0c0c0c;
1718 .Lsp3033303303303033mask:
1719         .long 0x04ff0404, 0x04ff0404;
1720         .long 0xff0a0aff, 0x0aff0a0a;
1721 .Lsbox4_input_mask:
1722         .byte 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00;
1723 .Lsigma1:
1724         .long 0x3BCC908B, 0xA09E667F;
1725 .Lsigma2:
1726         .long 0x4CAA73B2, 0xB67AE858;
1727 .Lsigma3:
1728         .long 0xE94F82BE, 0xC6EF372F;
1729 .Lsigma4:
1730         .long 0xF1D36F1C, 0x54FF53A5;
1731 .Lsigma5:
1732         .long 0xDE682D1D, 0x10E527FA;
1733 .Lsigma6:
1734         .long 0xB3E6C1FD, 0xB05688C2;
1735
1736
1737 .align 8
1738 ELF(.type  __camellia_avx_setup128,@function;)
1739 __camellia_avx_setup128:
1740         /* input:
1741          *      %rdi: ctx, CTX; subkey storage at key_table(CTX)
1742          *      %xmm0: key
1743          */
1744 #define cmll_sub(n, ctx) (key_table+((n)*8))(ctx)
1745 #define KL128 %xmm0
1746 #define KA128 %xmm2
1747
1748         vpshufb .Lbswap128_mask RIP, KL128, KL128;
1749
1750         vmovdqa .Linv_shift_row_and_unpcklbw RIP, %xmm11;
1751         vmovq .Lsbox4_input_mask RIP, %xmm12;
1752         vbroadcastss .L0f0f0f0f RIP, %xmm13;
1753         vmovdqa .Lpre_tf_lo_s1 RIP, %xmm14;
1754         vmovdqa .Lpre_tf_hi_s1 RIP, %xmm15;
1755
1756         /*
1757          * Generate KA
1758          */
1759         vpsrldq $8, KL128, %xmm2;
1760         vmovdqa KL128, %xmm3;
1761         vpslldq $8, %xmm3, %xmm3;
1762         vpsrldq $8, %xmm3, %xmm3;
1763
1764         camellia_f(%xmm2, %xmm4, %xmm1,
1765                    %xmm5, %xmm6, %xmm7, %xmm8,
1766                    %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma1 RIP);
1767         vpxor %xmm4, %xmm3, %xmm3;
1768         camellia_f(%xmm3, %xmm2, %xmm1,
1769                    %xmm5, %xmm6, %xmm7, %xmm8,
1770                    %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma2 RIP);
1771         camellia_f(%xmm2, %xmm3, %xmm1,
1772                    %xmm5, %xmm6, %xmm7, %xmm8,
1773                    %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma3 RIP);
1774         vpxor %xmm4, %xmm3, %xmm3;
1775         camellia_f(%xmm3, %xmm4, %xmm1,
1776                    %xmm5, %xmm6, %xmm7, %xmm8,
1777                    %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma4 RIP);
1778
1779         vpslldq $8, %xmm3, %xmm3;
1780         vpxor %xmm4, %xmm2, %xmm2;
1781         vpsrldq $8, %xmm3, %xmm3;
1782         vpslldq $8, %xmm2, KA128;
1783         vpor %xmm3, KA128, KA128;
1784
1785         /*
1786          * Generate subkeys
1787          */
1788         vmovdqu KA128, cmll_sub(24, CTX);
1789         vec_rol128(KL128, %xmm3, 15, %xmm15);
1790         vec_rol128(KA128, %xmm4, 15, %xmm15);
1791         vec_rol128(KA128, %xmm5, 30, %xmm15);
1792         vec_rol128(KL128, %xmm6, 45, %xmm15);
1793         vec_rol128(KA128, %xmm7, 45, %xmm15);
1794         vec_rol128(KL128, %xmm8, 60, %xmm15);
1795         vec_rol128(KA128, %xmm9, 60, %xmm15);
1796         vec_ror128(KL128, %xmm10, 128-77, %xmm15);
1797
1798         /* absorb kw2 to other subkeys */
1799         vpslldq $8, KL128, %xmm15;
1800         vpsrldq $8, %xmm15, %xmm15;
1801         vpxor %xmm15, KA128, KA128;
1802         vpxor %xmm15, %xmm3, %xmm3;
1803         vpxor %xmm15, %xmm4, %xmm4;
1804
1805         /* subl(1) ^= subr(1) & ~subr(9); */
1806         vpandn %xmm15, %xmm5, %xmm13;
1807         vpslldq $12, %xmm13, %xmm13;
1808         vpsrldq $8, %xmm13, %xmm13;
1809         vpxor %xmm13, %xmm15, %xmm15;
1810         /* dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw); */
1811         vpand %xmm15, %xmm5, %xmm14;
1812         vpslld $1, %xmm14, %xmm11;
1813         vpsrld $31, %xmm14, %xmm14;
1814         vpaddd %xmm11, %xmm14, %xmm14;
1815         vpslldq $8, %xmm14, %xmm14;
1816         vpsrldq $12, %xmm14, %xmm14;
1817         vpxor %xmm14, %xmm15, %xmm15;
1818
1819         vpxor %xmm15, %xmm6, %xmm6;
1820         vpxor %xmm15, %xmm8, %xmm8;
1821         vpxor %xmm15, %xmm9, %xmm9;
1822
1823         /* subl(1) ^= subr(1) & ~subr(17); */
1824         vpandn %xmm15, %xmm10, %xmm13;
1825         vpslldq $12, %xmm13, %xmm13;
1826         vpsrldq $8, %xmm13, %xmm13;
1827         vpxor %xmm13, %xmm15, %xmm15;
1828         /* dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw); */
1829         vpand %xmm15, %xmm10, %xmm14;
1830         vpslld $1, %xmm14, %xmm11;
1831         vpsrld $31, %xmm14, %xmm14;
1832         vpaddd %xmm11, %xmm14, %xmm14;
1833         vpslldq $8, %xmm14, %xmm14;
1834         vpsrldq $12, %xmm14, %xmm14;
1835         vpxor %xmm14, %xmm15, %xmm15;
1836
1837         vpshufd $0x1b, KL128, KL128;
1838         vpshufd $0x1b, KA128, KA128;
1839         vpshufd $0x1b, %xmm3, %xmm3;
1840         vpshufd $0x1b, %xmm4, %xmm4;
1841         vpshufd $0x1b, %xmm5, %xmm5;
1842         vpshufd $0x1b, %xmm6, %xmm6;
1843         vpshufd $0x1b, %xmm7, %xmm7;
1844         vpshufd $0x1b, %xmm8, %xmm8;
1845         vpshufd $0x1b, %xmm9, %xmm9;
1846         vpshufd $0x1b, %xmm10, %xmm10;
1847
1848         vmovdqu KL128, cmll_sub(0, CTX);
1849         vpshufd $0x1b, KL128, KL128;
1850         vmovdqu KA128, cmll_sub(2, CTX);
1851         vmovdqu %xmm3, cmll_sub(4, CTX);
1852         vmovdqu %xmm4, cmll_sub(6, CTX);
1853         vmovdqu %xmm5, cmll_sub(8, CTX);
1854         vmovdqu %xmm6, cmll_sub(10, CTX);
1855         vpsrldq $8, %xmm8, %xmm8;
1856         vmovq %xmm7, cmll_sub(12, CTX);
1857         vmovq %xmm8, cmll_sub(13, CTX);
1858         vmovdqu %xmm9, cmll_sub(14, CTX);
1859         vmovdqu %xmm10, cmll_sub(16, CTX);
1860
1861         vmovdqu cmll_sub(24, CTX), KA128;
1862
1863         vec_ror128(KL128, %xmm3, 128 - 94, %xmm7);
1864         vec_ror128(KA128, %xmm4, 128 - 94, %xmm7);
1865         vec_ror128(KL128, %xmm5, 128 - 111, %xmm7);
1866         vec_ror128(KA128, %xmm6, 128 - 111, %xmm7);
1867
1868         vpxor %xmm15, %xmm3, %xmm3;
1869         vpxor %xmm15, %xmm4, %xmm4;
1870         vpxor %xmm15, %xmm5, %xmm5;
1871         vpslldq $8, %xmm15, %xmm15;
1872         vpxor %xmm15, %xmm6, %xmm6;
1873
1874         /* absorb kw4 to other subkeys */
1875         vpslldq $8, %xmm6, %xmm15;
1876         vpxor %xmm15, %xmm5, %xmm5;
1877         vpxor %xmm15, %xmm4, %xmm4;
1878         vpxor %xmm15, %xmm3, %xmm3;
1879
1880         /* subl(25) ^= subr(25) & ~subr(16); */
1881         vpshufd $0x1b, cmll_sub(16, CTX), %xmm10;
1882         vpandn %xmm15, %xmm10, %xmm13;
1883         vpslldq $4, %xmm13, %xmm13;
1884         vpxor %xmm13, %xmm15, %xmm15;
1885         /* dw = subl(25) & subl(16), subr(25) ^= CAMELLIA_RL1(dw); */
1886         vpand %xmm15, %xmm10, %xmm14;
1887         vpslld $1, %xmm14, %xmm11;
1888         vpsrld $31, %xmm14, %xmm14;
1889         vpaddd %xmm11, %xmm14, %xmm14;
1890         vpsrldq $12, %xmm14, %xmm14;
1891         vpslldq $8, %xmm14, %xmm14;
1892         vpxor %xmm14, %xmm15, %xmm15;
1893
1894         vpshufd $0x1b, %xmm3, %xmm3;
1895         vpshufd $0x1b, %xmm4, %xmm4;
1896         vpshufd $0x1b, %xmm5, %xmm5;
1897         vpshufd $0x1b, %xmm6, %xmm6;
1898
1899         vmovdqu %xmm3, cmll_sub(18, CTX);
1900         vmovdqu %xmm4, cmll_sub(20, CTX);
1901         vmovdqu %xmm5, cmll_sub(22, CTX);
1902         vmovdqu %xmm6, cmll_sub(24, CTX);
1903
1904         vpshufd $0x1b, cmll_sub(14, CTX), %xmm3;
1905         vpshufd $0x1b, cmll_sub(12, CTX), %xmm4;
1906         vpshufd $0x1b, cmll_sub(10, CTX), %xmm5;
1907         vpshufd $0x1b, cmll_sub(8, CTX), %xmm6;
1908
1909         vpxor %xmm15, %xmm3, %xmm3;
1910         vpxor %xmm15, %xmm4, %xmm4;
1911         vpxor %xmm15, %xmm5, %xmm5;
1912
1913         /* subl(25) ^= subr(25) & ~subr(8); */
1914         vpandn %xmm15, %xmm6, %xmm13;
1915         vpslldq $4, %xmm13, %xmm13;
1916         vpxor %xmm13, %xmm15, %xmm15;
1917         /* dw = subl(25) & subl(8), subr(25) ^= CAMELLIA_RL1(dw); */
1918         vpand %xmm15, %xmm6, %xmm14;
1919         vpslld $1, %xmm14, %xmm11;
1920         vpsrld $31, %xmm14, %xmm14;
1921         vpaddd %xmm11, %xmm14, %xmm14;
1922         vpsrldq $12, %xmm14, %xmm14;
1923         vpslldq $8, %xmm14, %xmm14;
1924         vpxor %xmm14, %xmm15, %xmm15;
1925
1926         vpshufd $0x1b, %xmm3, %xmm3;
1927         vpshufd $0x1b, %xmm4, %xmm4;
1928         vpshufd $0x1b, %xmm5, %xmm5;
1929
1930         vmovdqu %xmm3, cmll_sub(14, CTX);
1931         vmovdqu %xmm4, cmll_sub(12, CTX);
1932         vmovdqu %xmm5, cmll_sub(10, CTX);
1933
1934         vpshufd $0x1b, cmll_sub(6, CTX), %xmm6;
1935         vpshufd $0x1b, cmll_sub(4, CTX), %xmm4;
1936         vpshufd $0x1b, cmll_sub(2, CTX), %xmm2;
1937         vpshufd $0x1b, cmll_sub(0, CTX), %xmm0;
1938
1939         vpxor %xmm15, %xmm6, %xmm6;
1940         vpxor %xmm15, %xmm4, %xmm4;
1941         vpxor %xmm15, %xmm2, %xmm2;
1942         vpxor %xmm15, %xmm0, %xmm0;
1943
1944         vpshufd $0x1b, %xmm6, %xmm6;
1945         vpshufd $0x1b, %xmm4, %xmm4;
1946         vpshufd $0x1b, %xmm2, %xmm2;
1947         vpshufd $0x1b, %xmm0, %xmm0;
1948
1949         vpsrldq $8, %xmm2, %xmm3;
1950         vpsrldq $8, %xmm4, %xmm5;
1951         vpsrldq $8, %xmm6, %xmm7;
1952
1953         /*
1954          * key XOR is end of F-function.
1955          */
1956         vpxor %xmm2, %xmm0, %xmm0;
1957         vpxor %xmm4, %xmm2, %xmm2;
1958
1959         vmovq %xmm0, cmll_sub(0, CTX);
1960         vmovq %xmm3, cmll_sub(2, CTX);
1961         vpxor %xmm5, %xmm3, %xmm3;
1962         vpxor %xmm6, %xmm4, %xmm4;
1963         vpxor %xmm7, %xmm5, %xmm5;
1964         vmovq %xmm2, cmll_sub(3, CTX);
1965         vmovq %xmm3, cmll_sub(4, CTX);
1966         vmovq %xmm4, cmll_sub(5, CTX);
1967         vmovq %xmm5, cmll_sub(6, CTX);
1968
1969         vmovq cmll_sub(7, CTX), %xmm7;
1970         vmovq cmll_sub(8, CTX), %xmm8;
1971         vmovq cmll_sub(9, CTX), %xmm9;
1972         vmovq cmll_sub(10, CTX), %xmm10;
1973         /* tl = subl(10) ^ (subr(10) & ~subr(8)); */
1974         vpandn %xmm10, %xmm8, %xmm15;
1975         vpsrldq $4, %xmm15, %xmm15;
1976         vpxor %xmm15, %xmm10, %xmm0;
1977         /* dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw); */
1978         vpand %xmm8, %xmm0, %xmm15;
1979         vpslld $1, %xmm15, %xmm14;
1980         vpsrld $31, %xmm15, %xmm15;
1981         vpaddd %xmm14, %xmm15, %xmm15;
1982         vpslldq $12, %xmm15, %xmm15;
1983         vpsrldq $8, %xmm15, %xmm15;
1984         vpxor %xmm15, %xmm0, %xmm0;
1985
1986         vpxor %xmm0, %xmm6, %xmm6;
1987         vmovq %xmm6, cmll_sub(7, CTX);
1988
1989         vmovq cmll_sub(11, CTX), %xmm11;
1990         vmovq cmll_sub(12, CTX), %xmm12;
1991         vmovq cmll_sub(13, CTX), %xmm13;
1992         vmovq cmll_sub(14, CTX), %xmm14;
1993         vmovq cmll_sub(15, CTX), %xmm15;
1994         /* tl = subl(7) ^ (subr(7) & ~subr(9)); */
1995         vpandn %xmm7, %xmm9, %xmm1;
1996         vpsrldq $4, %xmm1, %xmm1;
1997         vpxor %xmm1, %xmm7, %xmm0;
1998         /* dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw); */
1999         vpand %xmm9, %xmm0, %xmm1;
2000         vpslld $1, %xmm1, %xmm2;
2001         vpsrld $31, %xmm1, %xmm1;
2002         vpaddd %xmm2, %xmm1, %xmm1;
2003         vpslldq $12, %xmm1, %xmm1;
2004         vpsrldq $8, %xmm1, %xmm1;
2005         vpxor %xmm1, %xmm0, %xmm0;
2006
2007         vpxor %xmm11, %xmm0, %xmm0;
2008         vpxor %xmm12, %xmm10, %xmm10;
2009         vpxor %xmm13, %xmm11, %xmm11;
2010         vpxor %xmm14, %xmm12, %xmm12;
2011         vpxor %xmm15, %xmm13, %xmm13;
2012         vmovq %xmm0, cmll_sub(10, CTX);
2013         vmovq %xmm10, cmll_sub(11, CTX);
2014         vmovq %xmm11, cmll_sub(12, CTX);
2015         vmovq %xmm12, cmll_sub(13, CTX);
2016         vmovq %xmm13, cmll_sub(14, CTX);
2017
2018         vmovq cmll_sub(16, CTX), %xmm6;
2019         vmovq cmll_sub(17, CTX), %xmm7;
2020         vmovq cmll_sub(18, CTX), %xmm8;
2021         vmovq cmll_sub(19, CTX), %xmm9;
2022         vmovq cmll_sub(20, CTX), %xmm10;
2023         /* tl = subl(18) ^ (subr(18) & ~subr(16)); */
2024         vpandn %xmm8, %xmm6, %xmm1;
2025         vpsrldq $4, %xmm1, %xmm1;
2026         vpxor %xmm1, %xmm8, %xmm0;
2027         /* dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw); */
2028         vpand %xmm6, %xmm0, %xmm1;
2029         vpslld $1, %xmm1, %xmm2;
2030         vpsrld $31, %xmm1, %xmm1;
2031         vpaddd %xmm2, %xmm1, %xmm1;
2032         vpslldq $12, %xmm1, %xmm1;
2033         vpsrldq $8, %xmm1, %xmm1;
2034         vpxor %xmm1, %xmm0, %xmm0;
2035
2036         vpxor %xmm14, %xmm0, %xmm0;
2037         vmovq %xmm0, cmll_sub(15, CTX);
2038
2039         /* tl = subl(15) ^ (subr(15) & ~subr(17)); */
2040         vpandn %xmm15, %xmm7, %xmm1;
2041         vpsrldq $4, %xmm1, %xmm1;
2042         vpxor %xmm1, %xmm15, %xmm0;
2043         /* dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw); */
2044         vpand %xmm7, %xmm0, %xmm1;
2045         vpslld $1, %xmm1, %xmm2;
2046         vpsrld $31, %xmm1, %xmm1;
2047         vpaddd %xmm2, %xmm1, %xmm1;
2048         vpslldq $12, %xmm1, %xmm1;
2049         vpsrldq $8, %xmm1, %xmm1;
2050         vpxor %xmm1, %xmm0, %xmm0;
2051
2052         vmovq cmll_sub(21, CTX), %xmm1;
2053         vmovq cmll_sub(22, CTX), %xmm2;
2054         vmovq cmll_sub(23, CTX), %xmm3;
2055         vmovq cmll_sub(24, CTX), %xmm4;
2056
2057         vpxor %xmm9, %xmm0, %xmm0;
2058         vpxor %xmm10, %xmm8, %xmm8;
2059         vpxor %xmm1, %xmm9, %xmm9;
2060         vpxor %xmm2, %xmm10, %xmm10;
2061         vpxor %xmm3, %xmm1, %xmm1;
2062         vpxor %xmm4, %xmm3, %xmm3;
2063
2064         vmovq %xmm0, cmll_sub(18, CTX);
2065         vmovq %xmm8, cmll_sub(19, CTX);
2066         vmovq %xmm9, cmll_sub(20, CTX);
2067         vmovq %xmm10, cmll_sub(21, CTX);
2068         vmovq %xmm1, cmll_sub(22, CTX);
2069         vmovq %xmm2, cmll_sub(23, CTX);
2070         vmovq %xmm3, cmll_sub(24, CTX);
2071
2072         /* kw2 and kw4 are unused now. */
2073         movq $0, cmll_sub(1, CTX);
2074         movq $0, cmll_sub(25, CTX);
2075
2076         vzeroall;
2077
2078         ret;
2079 ELF(.size __camellia_avx_setup128,.-__camellia_avx_setup128;)
2080
2081 .align 8
2082 ELF(.type  __camellia_avx_setup256,@function;)
2083
2084 __camellia_avx_setup256:
2085         /* input:
2086          *      %rdi: ctx, CTX; subkey storage at key_table(CTX)
2087          *      %xmm0 & %xmm1: key
2088          */
2089 #define KL128 %xmm0
2090 #define KR128 %xmm1
2091 #define KA128 %xmm2
2092 #define KB128 %xmm3
2093
2094         vpshufb .Lbswap128_mask RIP, KL128, KL128;
2095         vpshufb .Lbswap128_mask RIP, KR128, KR128;
2096
2097         vmovdqa .Linv_shift_row_and_unpcklbw RIP, %xmm11;
2098         vmovq .Lsbox4_input_mask RIP, %xmm12;
2099         vbroadcastss .L0f0f0f0f RIP, %xmm13;
2100         vmovdqa .Lpre_tf_lo_s1 RIP, %xmm14;
2101         vmovdqa .Lpre_tf_hi_s1 RIP, %xmm15;
2102
2103         /*
2104          * Generate KA
2105          */
2106         vpxor KL128, KR128, %xmm3;
2107         vpsrldq $8, KR128, %xmm6;
2108         vpsrldq $8, %xmm3, %xmm2;
2109         vpslldq $8, %xmm3, %xmm3;
2110         vpsrldq $8, %xmm3, %xmm3;
2111
2112         camellia_f(%xmm2, %xmm4, %xmm5,
2113                    %xmm7, %xmm8, %xmm9, %xmm10,
2114                    %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma1 RIP);
2115         vpxor %xmm4, %xmm3, %xmm3;
2116         camellia_f(%xmm3, %xmm2, %xmm5,
2117                    %xmm7, %xmm8, %xmm9, %xmm10,
2118                    %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma2 RIP);
2119         vpxor %xmm6, %xmm2, %xmm2;
2120         camellia_f(%xmm2, %xmm3, %xmm5,
2121                    %xmm7, %xmm8, %xmm9, %xmm10,
2122                    %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma3 RIP);
2123         vpxor %xmm4, %xmm3, %xmm3;
2124         vpxor KR128, %xmm3, %xmm3;
2125         camellia_f(%xmm3, %xmm4, %xmm5,
2126                    %xmm7, %xmm8, %xmm9, %xmm10,
2127                    %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma4 RIP);
2128
2129         vpslldq $8, %xmm3, %xmm3;
2130         vpxor %xmm4, %xmm2, %xmm2;
2131         vpsrldq $8, %xmm3, %xmm3;
2132         vpslldq $8, %xmm2, KA128;
2133         vpor %xmm3, KA128, KA128;
2134
2135         /*
2136          * Generate KB
2137          */
2138         vpxor KA128, KR128, %xmm3;
2139         vpsrldq $8, %xmm3, %xmm4;
2140         vpslldq $8, %xmm3, %xmm3;
2141         vpsrldq $8, %xmm3, %xmm3;
2142
2143         camellia_f(%xmm4, %xmm5, %xmm6,
2144                    %xmm7, %xmm8, %xmm9, %xmm10,
2145                    %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma5 RIP);
2146         vpxor %xmm5, %xmm3, %xmm3;
2147
2148         camellia_f(%xmm3, %xmm5, %xmm6,
2149                    %xmm7, %xmm8, %xmm9, %xmm10,
2150                    %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma6 RIP);
2151         vpslldq $8, %xmm3, %xmm3;
2152         vpxor %xmm5, %xmm4, %xmm4;
2153         vpsrldq $8, %xmm3, %xmm3;
2154         vpslldq $8, %xmm4, %xmm4;
2155         vpor %xmm3, %xmm4, KB128;
2156
2157         /*
2158          * Generate subkeys
2159          */
2160         vmovdqu KB128, cmll_sub(32, CTX);
2161         vec_rol128(KR128, %xmm4, 15, %xmm15);
2162         vec_rol128(KA128, %xmm5, 15, %xmm15);
2163         vec_rol128(KR128, %xmm6, 30, %xmm15);
2164         vec_rol128(KB128, %xmm7, 30, %xmm15);
2165         vec_rol128(KL128, %xmm8, 45, %xmm15);
2166         vec_rol128(KA128, %xmm9, 45, %xmm15);
2167         vec_rol128(KL128, %xmm10, 60, %xmm15);
2168         vec_rol128(KR128, %xmm11, 60, %xmm15);
2169         vec_rol128(KB128, %xmm12, 60, %xmm15);
2170
2171         /* absorb kw2 to other subkeys */
2172         vpslldq $8, KL128, %xmm15;
2173         vpsrldq $8, %xmm15, %xmm15;
2174         vpxor %xmm15, KB128, KB128;
2175         vpxor %xmm15, %xmm4, %xmm4;
2176         vpxor %xmm15, %xmm5, %xmm5;
2177
2178         /* subl(1) ^= subr(1) & ~subr(9); */
2179         vpandn %xmm15, %xmm6, %xmm13;
2180         vpslldq $12, %xmm13, %xmm13;
2181         vpsrldq $8, %xmm13, %xmm13;
2182         vpxor %xmm13, %xmm15, %xmm15;
2183         /* dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw); */
2184         vpand %xmm15, %xmm6, %xmm14;
2185         vpslld $1, %xmm14, %xmm13;
2186         vpsrld $31, %xmm14, %xmm14;
2187         vpaddd %xmm13, %xmm14, %xmm14;
2188         vpslldq $8, %xmm14, %xmm14;
2189         vpsrldq $12, %xmm14, %xmm14;
2190         vpxor %xmm14, %xmm15, %xmm15;
2191
2192         vpxor %xmm15, %xmm7, %xmm7;
2193         vpxor %xmm15, %xmm8, %xmm8;
2194         vpxor %xmm15, %xmm9, %xmm9;
2195
2196         vpshufd $0x1b, KL128, KL128;
2197         vpshufd $0x1b, KB128, KB128;
2198         vpshufd $0x1b, %xmm4, %xmm4;
2199         vpshufd $0x1b, %xmm5, %xmm5;
2200         vpshufd $0x1b, %xmm6, %xmm6;
2201         vpshufd $0x1b, %xmm7, %xmm7;
2202         vpshufd $0x1b, %xmm8, %xmm8;
2203         vpshufd $0x1b, %xmm9, %xmm9;
2204
2205         vmovdqu KL128, cmll_sub(0, CTX);
2206         vpshufd $0x1b, KL128, KL128;
2207         vmovdqu KB128, cmll_sub(2, CTX);
2208         vmovdqu %xmm4, cmll_sub(4, CTX);
2209         vmovdqu %xmm5, cmll_sub(6, CTX);
2210         vmovdqu %xmm6, cmll_sub(8, CTX);
2211         vmovdqu %xmm7, cmll_sub(10, CTX);
2212         vmovdqu %xmm8, cmll_sub(12, CTX);
2213         vmovdqu %xmm9, cmll_sub(14, CTX);
2214
2215         vmovdqu cmll_sub(32, CTX), KB128;
2216
2217         /* subl(1) ^= subr(1) & ~subr(17); */
2218         vpandn %xmm15, %xmm10, %xmm13;
2219         vpslldq $12, %xmm13, %xmm13;
2220         vpsrldq $8, %xmm13, %xmm13;
2221         vpxor %xmm13, %xmm15, %xmm15;
2222         /* dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw); */
2223         vpand %xmm15, %xmm10, %xmm14;
2224         vpslld $1, %xmm14, %xmm13;
2225         vpsrld $31, %xmm14, %xmm14;
2226         vpaddd %xmm13, %xmm14, %xmm14;
2227         vpslldq $8, %xmm14, %xmm14;
2228         vpsrldq $12, %xmm14, %xmm14;
2229         vpxor %xmm14, %xmm15, %xmm15;
2230
2231         vpxor %xmm15, %xmm11, %xmm11;
2232         vpxor %xmm15, %xmm12, %xmm12;
2233
2234         vec_ror128(KL128, %xmm4, 128-77, %xmm14);
2235         vec_ror128(KA128, %xmm5, 128-77, %xmm14);
2236         vec_ror128(KR128, %xmm6, 128-94, %xmm14);
2237         vec_ror128(KA128, %xmm7, 128-94, %xmm14);
2238         vec_ror128(KL128, %xmm8, 128-111, %xmm14);
2239         vec_ror128(KB128, %xmm9, 128-111, %xmm14);
2240
2241         vpxor %xmm15, %xmm4, %xmm4;
2242
2243         vpshufd $0x1b, %xmm10, %xmm10;
2244         vpshufd $0x1b, %xmm11, %xmm11;
2245         vpshufd $0x1b, %xmm12, %xmm12;
2246         vpshufd $0x1b, %xmm4, %xmm4;
2247
2248         vmovdqu %xmm10, cmll_sub(16, CTX);
2249         vmovdqu %xmm11, cmll_sub(18, CTX);
2250         vmovdqu %xmm12, cmll_sub(20, CTX);
2251         vmovdqu %xmm4, cmll_sub(22, CTX);
2252
2253         /* subl(1) ^= subr(1) & ~subr(25); */
2254         vpandn %xmm15, %xmm5, %xmm13;
2255         vpslldq $12, %xmm13, %xmm13;
2256         vpsrldq $8, %xmm13, %xmm13;
2257         vpxor %xmm13, %xmm15, %xmm15;
2258         /* dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw); */
2259         vpand %xmm15, %xmm5, %xmm14;
2260         vpslld $1, %xmm14, %xmm13;
2261         vpsrld $31, %xmm14, %xmm14;
2262         vpaddd %xmm13, %xmm14, %xmm14;
2263         vpslldq $8, %xmm14, %xmm14;
2264         vpsrldq $12, %xmm14, %xmm14;
2265         vpxor %xmm14, %xmm15, %xmm15;
2266
2267         vpxor %xmm15, %xmm6, %xmm6;
2268         vpxor %xmm15, %xmm7, %xmm7;
2269         vpxor %xmm15, %xmm8, %xmm8;
2270         vpslldq $8, %xmm15, %xmm15;
2271         vpxor %xmm15, %xmm9, %xmm9;
2272
2273         /* absorb kw4 to other subkeys */
2274         vpslldq $8, %xmm9, %xmm15;
2275         vpxor %xmm15, %xmm8, %xmm8;
2276         vpxor %xmm15, %xmm7, %xmm7;
2277         vpxor %xmm15, %xmm6, %xmm6;
2278
2279         /* subl(33) ^= subr(33) & ~subr(24); */
2280         vpandn %xmm15, %xmm5, %xmm14;
2281         vpslldq $4, %xmm14, %xmm14;
2282         vpxor %xmm14, %xmm15, %xmm15;
2283         /* dw = subl(33) & subl(24), subr(33) ^= CAMELLIA_RL1(dw); */
2284         vpand %xmm15, %xmm5, %xmm14;
2285         vpslld $1, %xmm14, %xmm13;
2286         vpsrld $31, %xmm14, %xmm14;
2287         vpaddd %xmm13, %xmm14, %xmm14;
2288         vpsrldq $12, %xmm14, %xmm14;
2289         vpslldq $8, %xmm14, %xmm14;
2290         vpxor %xmm14, %xmm15, %xmm15;
2291
2292         vpshufd $0x1b, %xmm5, %xmm5;
2293         vpshufd $0x1b, %xmm6, %xmm6;
2294         vpshufd $0x1b, %xmm7, %xmm7;
2295         vpshufd $0x1b, %xmm8, %xmm8;
2296         vpshufd $0x1b, %xmm9, %xmm9;
2297
2298         vmovdqu %xmm5, cmll_sub(24, CTX);
2299         vmovdqu %xmm6, cmll_sub(26, CTX);
2300         vmovdqu %xmm7, cmll_sub(28, CTX);
2301         vmovdqu %xmm8, cmll_sub(30, CTX);
2302         vmovdqu %xmm9, cmll_sub(32, CTX);
2303
2304         vpshufd $0x1b, cmll_sub(22, CTX), %xmm0;
2305         vpshufd $0x1b, cmll_sub(20, CTX), %xmm1;
2306         vpshufd $0x1b, cmll_sub(18, CTX), %xmm2;
2307         vpshufd $0x1b, cmll_sub(16, CTX), %xmm3;
2308         vpshufd $0x1b, cmll_sub(14, CTX), %xmm4;
2309         vpshufd $0x1b, cmll_sub(12, CTX), %xmm5;
2310         vpshufd $0x1b, cmll_sub(10, CTX), %xmm6;
2311         vpshufd $0x1b, cmll_sub(8, CTX), %xmm7;
2312
2313         vpxor %xmm15, %xmm0, %xmm0;
2314         vpxor %xmm15, %xmm1, %xmm1;
2315         vpxor %xmm15, %xmm2, %xmm2;
2316
2317         /* subl(33) ^= subr(33) & ~subr(24); */
2318         vpandn %xmm15, %xmm3, %xmm14;
2319         vpslldq $4, %xmm14, %xmm14;
2320         vpxor %xmm14, %xmm15, %xmm15;
2321         /* dw = subl(33) & subl(24), subr(33) ^= CAMELLIA_RL1(dw); */
2322         vpand %xmm15, %xmm3, %xmm14;
2323         vpslld $1, %xmm14, %xmm13;
2324         vpsrld $31, %xmm14, %xmm14;
2325         vpaddd %xmm13, %xmm14, %xmm14;
2326         vpsrldq $12, %xmm14, %xmm14;
2327         vpslldq $8, %xmm14, %xmm14;
2328         vpxor %xmm14, %xmm15, %xmm15;
2329
2330         vpxor %xmm15, %xmm4, %xmm4;
2331         vpxor %xmm15, %xmm5, %xmm5;
2332         vpxor %xmm15, %xmm6, %xmm6;
2333
2334         vpshufd $0x1b, %xmm0, %xmm0;
2335         vpshufd $0x1b, %xmm1, %xmm1;
2336         vpshufd $0x1b, %xmm2, %xmm2;
2337         vpshufd $0x1b, %xmm4, %xmm4;
2338         vpshufd $0x1b, %xmm5, %xmm5;
2339         vpshufd $0x1b, %xmm6, %xmm6;
2340
2341         vmovdqu %xmm0, cmll_sub(22, CTX);
2342         vmovdqu %xmm1, cmll_sub(20, CTX);
2343         vmovdqu %xmm2, cmll_sub(18, CTX);
2344         vmovdqu %xmm4, cmll_sub(14, CTX);
2345         vmovdqu %xmm5, cmll_sub(12, CTX);
2346         vmovdqu %xmm6, cmll_sub(10, CTX);
2347
2348         vpshufd $0x1b, cmll_sub(6, CTX), %xmm6;
2349         vpshufd $0x1b, cmll_sub(4, CTX), %xmm4;
2350         vpshufd $0x1b, cmll_sub(2, CTX), %xmm2;
2351         vpshufd $0x1b, cmll_sub(0, CTX), %xmm0;
2352
2353         /* subl(33) ^= subr(33) & ~subr(24); */
2354         vpandn %xmm15, %xmm7, %xmm14;
2355         vpslldq $4, %xmm14, %xmm14;
2356         vpxor %xmm14, %xmm15, %xmm15;
2357         /* dw = subl(33) & subl(24), subr(33) ^= CAMELLIA_RL1(dw); */
2358         vpand %xmm15, %xmm7, %xmm14;
2359         vpslld $1, %xmm14, %xmm13;
2360         vpsrld $31, %xmm14, %xmm14;
2361         vpaddd %xmm13, %xmm14, %xmm14;
2362         vpsrldq $12, %xmm14, %xmm14;
2363         vpslldq $8, %xmm14, %xmm14;
2364         vpxor %xmm14, %xmm15, %xmm15;
2365
2366         vpxor %xmm15, %xmm6, %xmm6;
2367         vpxor %xmm15, %xmm4, %xmm4;
2368         vpxor %xmm15, %xmm2, %xmm2;
2369         vpxor %xmm15, %xmm0, %xmm0;
2370
2371         vpshufd $0x1b, %xmm6, %xmm6;
2372         vpshufd $0x1b, %xmm4, %xmm4;
2373         vpshufd $0x1b, %xmm2, %xmm2;
2374         vpshufd $0x1b, %xmm0, %xmm0;
2375
2376         vpsrldq $8, %xmm2, %xmm3;
2377         vpsrldq $8, %xmm4, %xmm5;
2378         vpsrldq $8, %xmm6, %xmm7;
2379
2380         /*
2381          * key XOR is end of F-function.
2382          */
2383         vpxor %xmm2, %xmm0, %xmm0;
2384         vpxor %xmm4, %xmm2, %xmm2;
2385
2386         vmovq %xmm0, cmll_sub(0, CTX);
2387         vmovq %xmm3, cmll_sub(2, CTX);
2388         vpxor %xmm5, %xmm3, %xmm3;
2389         vpxor %xmm6, %xmm4, %xmm4;
2390         vpxor %xmm7, %xmm5, %xmm5;
2391         vmovq %xmm2, cmll_sub(3, CTX);
2392         vmovq %xmm3, cmll_sub(4, CTX);
2393         vmovq %xmm4, cmll_sub(5, CTX);
2394         vmovq %xmm5, cmll_sub(6, CTX);
2395
2396         vmovq cmll_sub(7, CTX), %xmm7;
2397         vmovq cmll_sub(8, CTX), %xmm8;
2398         vmovq cmll_sub(9, CTX), %xmm9;
2399         vmovq cmll_sub(10, CTX), %xmm10;
2400         /* tl = subl(10) ^ (subr(10) & ~subr(8)); */
2401         vpandn %xmm10, %xmm8, %xmm15;
2402         vpsrldq $4, %xmm15, %xmm15;
2403         vpxor %xmm15, %xmm10, %xmm0;
2404         /* dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw); */
2405         vpand %xmm8, %xmm0, %xmm15;
2406         vpslld $1, %xmm15, %xmm14;
2407         vpsrld $31, %xmm15, %xmm15;
2408         vpaddd %xmm14, %xmm15, %xmm15;
2409         vpslldq $12, %xmm15, %xmm15;
2410         vpsrldq $8, %xmm15, %xmm15;
2411         vpxor %xmm15, %xmm0, %xmm0;
2412
2413         vpxor %xmm0, %xmm6, %xmm6;
2414         vmovq %xmm6, cmll_sub(7, CTX);
2415
2416         vmovq cmll_sub(11, CTX), %xmm11;
2417         vmovq cmll_sub(12, CTX), %xmm12;
2418         vmovq cmll_sub(13, CTX), %xmm13;
2419         vmovq cmll_sub(14, CTX), %xmm14;
2420         vmovq cmll_sub(15, CTX), %xmm15;
2421         /* tl = subl(7) ^ (subr(7) & ~subr(9)); */
2422         vpandn %xmm7, %xmm9, %xmm1;
2423         vpsrldq $4, %xmm1, %xmm1;
2424         vpxor %xmm1, %xmm7, %xmm0;
2425         /* dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw); */
2426         vpand %xmm9, %xmm0, %xmm1;
2427         vpslld $1, %xmm1, %xmm2;
2428         vpsrld $31, %xmm1, %xmm1;
2429         vpaddd %xmm2, %xmm1, %xmm1;
2430         vpslldq $12, %xmm1, %xmm1;
2431         vpsrldq $8, %xmm1, %xmm1;
2432         vpxor %xmm1, %xmm0, %xmm0;
2433
2434         vpxor %xmm11, %xmm0, %xmm0;
2435         vpxor %xmm12, %xmm10, %xmm10;
2436         vpxor %xmm13, %xmm11, %xmm11;
2437         vpxor %xmm14, %xmm12, %xmm12;
2438         vpxor %xmm15, %xmm13, %xmm13;
2439         vmovq %xmm0, cmll_sub(10, CTX);
2440         vmovq %xmm10, cmll_sub(11, CTX);
2441         vmovq %xmm11, cmll_sub(12, CTX);
2442         vmovq %xmm12, cmll_sub(13, CTX);
2443         vmovq %xmm13, cmll_sub(14, CTX);
2444
2445         vmovq cmll_sub(16, CTX), %xmm6;
2446         vmovq cmll_sub(17, CTX), %xmm7;
2447         vmovq cmll_sub(18, CTX), %xmm8;
2448         vmovq cmll_sub(19, CTX), %xmm9;
2449         vmovq cmll_sub(20, CTX), %xmm10;
2450         /* tl = subl(18) ^ (subr(18) & ~subr(16)); */
2451         vpandn %xmm8, %xmm6, %xmm1;
2452         vpsrldq $4, %xmm1, %xmm1;
2453         vpxor %xmm1, %xmm8, %xmm0;
2454         /* dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw); */
2455         vpand %xmm6, %xmm0, %xmm1;
2456         vpslld $1, %xmm1, %xmm2;
2457         vpsrld $31, %xmm1, %xmm1;
2458         vpaddd %xmm2, %xmm1, %xmm1;
2459         vpslldq $12, %xmm1, %xmm1;
2460         vpsrldq $8, %xmm1, %xmm1;
2461         vpxor %xmm1, %xmm0, %xmm0;
2462
2463         vpxor %xmm14, %xmm0, %xmm0;
2464         vmovq %xmm0, cmll_sub(15, CTX);
2465
2466         /* tl = subl(15) ^ (subr(15) & ~subr(17)); */
2467         vpandn %xmm15, %xmm7, %xmm1;
2468         vpsrldq $4, %xmm1, %xmm1;
2469         vpxor %xmm1, %xmm15, %xmm0;
2470         /* dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw); */
2471         vpand %xmm7, %xmm0, %xmm1;
2472         vpslld $1, %xmm1, %xmm2;
2473         vpsrld $31, %xmm1, %xmm1;
2474         vpaddd %xmm2, %xmm1, %xmm1;
2475         vpslldq $12, %xmm1, %xmm1;
2476         vpsrldq $8, %xmm1, %xmm1;
2477         vpxor %xmm1, %xmm0, %xmm0;
2478
2479         vmovq cmll_sub(21, CTX), %xmm1;
2480         vmovq cmll_sub(22, CTX), %xmm2;
2481         vmovq cmll_sub(23, CTX), %xmm3;
2482         vmovq cmll_sub(24, CTX), %xmm4;
2483
2484         vpxor %xmm9, %xmm0, %xmm0;
2485         vpxor %xmm10, %xmm8, %xmm8;
2486         vpxor %xmm1, %xmm9, %xmm9;
2487         vpxor %xmm2, %xmm10, %xmm10;
2488         vpxor %xmm3, %xmm1, %xmm1;
2489
2490         vmovq %xmm0, cmll_sub(18, CTX);
2491         vmovq %xmm8, cmll_sub(19, CTX);
2492         vmovq %xmm9, cmll_sub(20, CTX);
2493         vmovq %xmm10, cmll_sub(21, CTX);
2494         vmovq %xmm1, cmll_sub(22, CTX);
2495
2496         vmovq cmll_sub(25, CTX), %xmm5;
2497         vmovq cmll_sub(26, CTX), %xmm6;
2498         vmovq cmll_sub(27, CTX), %xmm7;
2499         vmovq cmll_sub(28, CTX), %xmm8;
2500         vmovq cmll_sub(29, CTX), %xmm9;
2501         vmovq cmll_sub(30, CTX), %xmm10;
2502         vmovq cmll_sub(31, CTX), %xmm11;
2503         vmovq cmll_sub(32, CTX), %xmm12;
2504
2505         /* tl = subl(26) ^ (subr(26) & ~subr(24)); */
2506         vpandn %xmm6, %xmm4, %xmm15;
2507         vpsrldq $4, %xmm15, %xmm15;
2508         vpxor %xmm15, %xmm6, %xmm0;
2509         /* dw = tl & subl(26), tr = subr(24) ^ CAMELLIA_RL1(dw); */
2510         vpand %xmm4, %xmm0, %xmm15;
2511         vpslld $1, %xmm15, %xmm14;
2512         vpsrld $31, %xmm15, %xmm15;
2513         vpaddd %xmm14, %xmm15, %xmm15;
2514         vpslldq $12, %xmm15, %xmm15;
2515         vpsrldq $8, %xmm15, %xmm15;
2516         vpxor %xmm15, %xmm0, %xmm0;
2517
2518         vpxor %xmm0, %xmm2, %xmm2;
2519         vmovq %xmm2, cmll_sub(23, CTX);
2520
2521         /* tl = subl(23) ^ (subr(23) &  ~subr(25)); */
2522         vpandn %xmm3, %xmm5, %xmm15;
2523         vpsrldq $4, %xmm15, %xmm15;
2524         vpxor %xmm15, %xmm3, %xmm0;
2525         /* dw = tl & subl(26), tr = subr(24) ^ CAMELLIA_RL1(dw); */
2526         vpand %xmm5, %xmm0, %xmm15;
2527         vpslld $1, %xmm15, %xmm14;
2528         vpsrld $31, %xmm15, %xmm15;
2529         vpaddd %xmm14, %xmm15, %xmm15;
2530         vpslldq $12, %xmm15, %xmm15;
2531         vpsrldq $8, %xmm15, %xmm15;
2532         vpxor %xmm15, %xmm0, %xmm0;
2533
2534         vpxor %xmm7, %xmm0, %xmm0;
2535         vpxor %xmm8, %xmm6, %xmm6;
2536         vpxor %xmm9, %xmm7, %xmm7;
2537         vpxor %xmm10, %xmm8, %xmm8;
2538         vpxor %xmm11, %xmm9, %xmm9;
2539         vpxor %xmm12, %xmm11, %xmm11;
2540
2541         vmovq %xmm0, cmll_sub(26, CTX);
2542         vmovq %xmm6, cmll_sub(27, CTX);
2543         vmovq %xmm7, cmll_sub(28, CTX);
2544         vmovq %xmm8, cmll_sub(29, CTX);
2545         vmovq %xmm9, cmll_sub(30, CTX);
2546         vmovq %xmm10, cmll_sub(31, CTX);
2547         vmovq %xmm11, cmll_sub(32, CTX);
2548
2549         /* kw2 and kw4 are unused now. */
2550         movq $0, cmll_sub(1, CTX);
2551         movq $0, cmll_sub(33, CTX);
2552
2553         vzeroall;
2554
2555         ret;
2556 ELF(.size __camellia_avx_setup256,.-__camellia_avx_setup256;)
2557
2558 .align 8
2559 .globl _gcry_camellia_aesni_avx_keygen
2560 ELF(.type  _gcry_camellia_aesni_avx_keygen,@function;)
2561
2562 _gcry_camellia_aesni_avx_keygen:
2563         /* input:
2564          *      %rdi: ctx, CTX
2565          *      %rsi: key
2566          *      %rdx: keylen
2567          */
2568
2569         vzeroupper;
2570
2571         vmovdqu (%rsi), %xmm0;
2572         cmpl $24, %edx;
2573         jb __camellia_avx_setup128;
2574         je .Lprepare_key192;
2575
2576         vmovdqu 16(%rsi), %xmm1;
2577         jmp __camellia_avx_setup256;
2578
2579 .Lprepare_key192:
2580         vpcmpeqd %xmm2, %xmm2, %xmm2;
2581         vmovq 16(%rsi), %xmm1;
2582
2583         vpxor %xmm1, %xmm2, %xmm2;
2584         vpslldq $8, %xmm2, %xmm2;
2585         vpor %xmm2, %xmm1, %xmm1;
2586
2587         jmp __camellia_avx_setup256;
2588 ELF(.size _gcry_camellia_aesni_avx_keygen,.-_gcry_camellia_aesni_avx_keygen;)
2589
2590 #endif /*defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)*/
2591 #endif /*__x86_64*/