Add PowerPC extra CFLAGS also for chacha20-ppc and crc-ppc
[libgcrypt.git] / cipher / camellia-aesni-avx2-amd64.S
1 /* camellia-avx2-aesni-amd64.S  -  AES-NI/AVX2 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_AVX2_SUPPORT)
26
27 #include "asm-common-amd64.h"
28
29 #define CAMELLIA_TABLE_BYTE_LEN 272
30
31 /* struct CAMELLIA_context: */
32 #define key_table 0
33 #define key_bitlength CAMELLIA_TABLE_BYTE_LEN
34
35 /* register macros */
36 #define CTX %rdi
37 #define RIO %r8
38
39 /**********************************************************************
40   helper macros
41  **********************************************************************/
42 #define filter_8bit(x, lo_t, hi_t, mask4bit, tmp0) \
43         vpand x, mask4bit, tmp0; \
44         vpandn x, mask4bit, x; \
45         vpsrld $4, x, x; \
46         \
47         vpshufb tmp0, lo_t, tmp0; \
48         vpshufb x, hi_t, x; \
49         vpxor tmp0, x, x;
50
51 #define ymm0_x xmm0
52 #define ymm1_x xmm1
53 #define ymm2_x xmm2
54 #define ymm3_x xmm3
55 #define ymm4_x xmm4
56 #define ymm5_x xmm5
57 #define ymm6_x xmm6
58 #define ymm7_x xmm7
59 #define ymm8_x xmm8
60 #define ymm9_x xmm9
61 #define ymm10_x xmm10
62 #define ymm11_x xmm11
63 #define ymm12_x xmm12
64 #define ymm13_x xmm13
65 #define ymm14_x xmm14
66 #define ymm15_x xmm15
67
68 /**********************************************************************
69   32-way camellia
70  **********************************************************************/
71
72 /*
73  * IN:
74  *   x0..x7: byte-sliced AB state
75  *   mem_cd: register pointer storing CD state
76  *   key: index for key material
77  * OUT:
78  *   x0..x7: new byte-sliced CD state
79  */
80 #define roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, t0, t1, t2, t3, t4, t5, t6, \
81                   t7, mem_cd, key) \
82         /* \
83          * S-function with AES subbytes \
84          */ \
85         vbroadcasti128 .Linv_shift_row rRIP, t4; \
86         vpbroadcastd .L0f0f0f0f rRIP, t7; \
87         vbroadcasti128 .Lpre_tf_lo_s1 rRIP, t5; \
88         vbroadcasti128 .Lpre_tf_hi_s1 rRIP, t6; \
89         vbroadcasti128 .Lpre_tf_lo_s4 rRIP, t2; \
90         vbroadcasti128 .Lpre_tf_hi_s4 rRIP, t3; \
91         \
92         /* AES inverse shift rows */ \
93         vpshufb t4, x0, x0; \
94         vpshufb t4, x7, x7; \
95         vpshufb t4, x3, x3; \
96         vpshufb t4, x6, x6; \
97         vpshufb t4, x2, x2; \
98         vpshufb t4, x5, x5; \
99         vpshufb t4, x1, x1; \
100         vpshufb t4, x4, x4; \
101         \
102         /* prefilter sboxes 1, 2 and 3 */ \
103         /* prefilter sbox 4 */ \
104         filter_8bit(x0, t5, t6, t7, t4); \
105         filter_8bit(x7, t5, t6, t7, t4); \
106         vextracti128 $1, x0, t0##_x; \
107         vextracti128 $1, x7, t1##_x; \
108         filter_8bit(x3, t2, t3, t7, t4); \
109         filter_8bit(x6, t2, t3, t7, t4); \
110         vextracti128 $1, x3, t3##_x; \
111         vextracti128 $1, x6, t2##_x; \
112         filter_8bit(x2, t5, t6, t7, t4); \
113         filter_8bit(x5, t5, t6, t7, t4); \
114         filter_8bit(x1, t5, t6, t7, t4); \
115         filter_8bit(x4, t5, t6, t7, t4); \
116         \
117         vpxor t4##_x, t4##_x, t4##_x; \
118         \
119         /* AES subbytes + AES shift rows */ \
120         vextracti128 $1, x2, t6##_x; \
121         vextracti128 $1, x5, t5##_x; \
122         vaesenclast t4##_x, x0##_x, x0##_x; \
123         vaesenclast t4##_x, t0##_x, t0##_x; \
124         vaesenclast t4##_x, x7##_x, x7##_x; \
125         vaesenclast t4##_x, t1##_x, t1##_x; \
126         vaesenclast t4##_x, x3##_x, x3##_x; \
127         vaesenclast t4##_x, t3##_x, t3##_x; \
128         vaesenclast t4##_x, x6##_x, x6##_x; \
129         vaesenclast t4##_x, t2##_x, t2##_x; \
130         vinserti128 $1, t0##_x, x0, x0; \
131         vinserti128 $1, t1##_x, x7, x7; \
132         vinserti128 $1, t3##_x, x3, x3; \
133         vinserti128 $1, t2##_x, x6, x6; \
134         vextracti128 $1, x1, t3##_x; \
135         vextracti128 $1, x4, t2##_x; \
136         vbroadcasti128 .Lpost_tf_lo_s1 rRIP, t0; \
137         vbroadcasti128 .Lpost_tf_hi_s1 rRIP, t1; \
138         vaesenclast t4##_x, x2##_x, x2##_x; \
139         vaesenclast t4##_x, t6##_x, t6##_x; \
140         vaesenclast t4##_x, x5##_x, x5##_x; \
141         vaesenclast t4##_x, t5##_x, t5##_x; \
142         vaesenclast t4##_x, x1##_x, x1##_x; \
143         vaesenclast t4##_x, t3##_x, t3##_x; \
144         vaesenclast t4##_x, x4##_x, x4##_x; \
145         vaesenclast t4##_x, t2##_x, t2##_x; \
146         vinserti128 $1, t6##_x, x2, x2; \
147         vinserti128 $1, t5##_x, x5, x5; \
148         vinserti128 $1, t3##_x, x1, x1; \
149         vinserti128 $1, t2##_x, x4, x4; \
150         \
151         /* postfilter sboxes 1 and 4 */ \
152         vbroadcasti128 .Lpost_tf_lo_s3 rRIP, t2; \
153         vbroadcasti128 .Lpost_tf_hi_s3 rRIP, t3; \
154         filter_8bit(x0, t0, t1, t7, t4); \
155         filter_8bit(x7, t0, t1, t7, t4); \
156         filter_8bit(x3, t0, t1, t7, t6); \
157         filter_8bit(x6, t0, t1, t7, t6); \
158         \
159         /* postfilter sbox 3 */ \
160         vbroadcasti128 .Lpost_tf_lo_s2 rRIP, t4; \
161         vbroadcasti128 .Lpost_tf_hi_s2 rRIP, t5; \
162         filter_8bit(x2, t2, t3, t7, t6); \
163         filter_8bit(x5, t2, t3, t7, t6); \
164         \
165         vpbroadcastq key, t0; /* higher 64-bit duplicate ignored */ \
166         \
167         /* postfilter sbox 2 */ \
168         filter_8bit(x1, t4, t5, t7, t2); \
169         filter_8bit(x4, t4, t5, t7, t2); \
170         vpxor t7, t7, t7; \
171         \
172         vpsrldq $1, t0, t1; \
173         vpsrldq $2, t0, t2; \
174         vpshufb t7, t1, t1; \
175         vpsrldq $3, t0, t3; \
176         \
177         /* P-function */ \
178         vpxor x5, x0, x0; \
179         vpxor x6, x1, x1; \
180         vpxor x7, x2, x2; \
181         vpxor x4, x3, x3; \
182         \
183         vpshufb t7, t2, t2; \
184         vpsrldq $4, t0, t4; \
185         vpshufb t7, t3, t3; \
186         vpsrldq $5, t0, t5; \
187         vpshufb t7, t4, t4; \
188         \
189         vpxor x2, x4, x4; \
190         vpxor x3, x5, x5; \
191         vpxor x0, x6, x6; \
192         vpxor x1, x7, x7; \
193         \
194         vpsrldq $6, t0, t6; \
195         vpshufb t7, t5, t5; \
196         vpshufb t7, t6, t6; \
197         \
198         vpxor x7, x0, x0; \
199         vpxor x4, x1, x1; \
200         vpxor x5, x2, x2; \
201         vpxor x6, x3, x3; \
202         \
203         vpxor x3, x4, x4; \
204         vpxor x0, x5, x5; \
205         vpxor x1, x6, x6; \
206         vpxor x2, x7, x7; /* note: high and low parts swapped */ \
207         \
208         /* Add key material and result to CD (x becomes new CD) */ \
209         \
210         vpxor t6, x1, x1; \
211         vpxor 5 * 32(mem_cd), x1, x1; \
212         \
213         vpsrldq $7, t0, t6; \
214         vpshufb t7, t0, t0; \
215         vpshufb t7, t6, t7; \
216         \
217         vpxor t7, x0, x0; \
218         vpxor 4 * 32(mem_cd), x0, x0; \
219         \
220         vpxor t5, x2, x2; \
221         vpxor 6 * 32(mem_cd), x2, x2; \
222         \
223         vpxor t4, x3, x3; \
224         vpxor 7 * 32(mem_cd), x3, x3; \
225         \
226         vpxor t3, x4, x4; \
227         vpxor 0 * 32(mem_cd), x4, x4; \
228         \
229         vpxor t2, x5, x5; \
230         vpxor 1 * 32(mem_cd), x5, x5; \
231         \
232         vpxor t1, x6, x6; \
233         vpxor 2 * 32(mem_cd), x6, x6; \
234         \
235         vpxor t0, x7, x7; \
236         vpxor 3 * 32(mem_cd), x7, x7;
237
238 /*
239  * IN/OUT:
240  *  x0..x7: byte-sliced AB state preloaded
241  *  mem_ab: byte-sliced AB state in memory
242  *  mem_cb: byte-sliced CD state in memory
243  */
244 #define two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
245                       y6, y7, mem_ab, mem_cd, i, dir, store_ab) \
246         roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
247                   y6, y7, mem_cd, (key_table + (i) * 8)(CTX)); \
248         \
249         vmovdqu x0, 4 * 32(mem_cd); \
250         vmovdqu x1, 5 * 32(mem_cd); \
251         vmovdqu x2, 6 * 32(mem_cd); \
252         vmovdqu x3, 7 * 32(mem_cd); \
253         vmovdqu x4, 0 * 32(mem_cd); \
254         vmovdqu x5, 1 * 32(mem_cd); \
255         vmovdqu x6, 2 * 32(mem_cd); \
256         vmovdqu x7, 3 * 32(mem_cd); \
257         \
258         roundsm32(x4, x5, x6, x7, x0, x1, x2, x3, y0, y1, y2, y3, y4, y5, \
259                   y6, y7, mem_ab, (key_table + ((i) + (dir)) * 8)(CTX)); \
260         \
261         store_ab(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab);
262
263 #define dummy_store(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) /* do nothing */
264
265 #define store_ab_state(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) \
266         /* Store new AB state */ \
267         vmovdqu x4, 4 * 32(mem_ab); \
268         vmovdqu x5, 5 * 32(mem_ab); \
269         vmovdqu x6, 6 * 32(mem_ab); \
270         vmovdqu x7, 7 * 32(mem_ab); \
271         vmovdqu x0, 0 * 32(mem_ab); \
272         vmovdqu x1, 1 * 32(mem_ab); \
273         vmovdqu x2, 2 * 32(mem_ab); \
274         vmovdqu x3, 3 * 32(mem_ab);
275
276 #define enc_rounds32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
277                       y6, y7, mem_ab, mem_cd, i) \
278         two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
279                       y6, y7, mem_ab, mem_cd, (i) + 2, 1, store_ab_state); \
280         two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
281                       y6, y7, mem_ab, mem_cd, (i) + 4, 1, store_ab_state); \
282         two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
283                       y6, y7, mem_ab, mem_cd, (i) + 6, 1, dummy_store);
284
285 #define dec_rounds32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
286                       y6, y7, mem_ab, mem_cd, i) \
287         two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
288                       y6, y7, mem_ab, mem_cd, (i) + 7, -1, store_ab_state); \
289         two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
290                       y6, y7, mem_ab, mem_cd, (i) + 5, -1, store_ab_state); \
291         two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
292                       y6, y7, mem_ab, mem_cd, (i) + 3, -1, dummy_store);
293
294 /*
295  * IN:
296  *  v0..3: byte-sliced 32-bit integers
297  * OUT:
298  *  v0..3: (IN <<< 1)
299  */
300 #define rol32_1_32(v0, v1, v2, v3, t0, t1, t2, zero) \
301         vpcmpgtb v0, zero, t0; \
302         vpaddb v0, v0, v0; \
303         vpabsb t0, t0; \
304         \
305         vpcmpgtb v1, zero, t1; \
306         vpaddb v1, v1, v1; \
307         vpabsb t1, t1; \
308         \
309         vpcmpgtb v2, zero, t2; \
310         vpaddb v2, v2, v2; \
311         vpabsb t2, t2; \
312         \
313         vpor t0, v1, v1; \
314         \
315         vpcmpgtb v3, zero, t0; \
316         vpaddb v3, v3, v3; \
317         vpabsb t0, t0; \
318         \
319         vpor t1, v2, v2; \
320         vpor t2, v3, v3; \
321         vpor t0, v0, v0;
322
323 /*
324  * IN:
325  *   r: byte-sliced AB state in memory
326  *   l: byte-sliced CD state in memory
327  * OUT:
328  *   x0..x7: new byte-sliced CD state
329  */
330 #define fls32(l, l0, l1, l2, l3, l4, l5, l6, l7, r, t0, t1, t2, t3, tt0, \
331               tt1, tt2, tt3, kll, klr, krl, krr) \
332         /* \
333          * t0 = kll; \
334          * t0 &= ll; \
335          * lr ^= rol32(t0, 1); \
336          */ \
337         vpbroadcastd kll, t0; /* only lowest 32-bit used */ \
338         vpxor tt0, tt0, tt0; \
339         vpshufb tt0, t0, t3; \
340         vpsrldq $1, t0, t0; \
341         vpshufb tt0, t0, t2; \
342         vpsrldq $1, t0, t0; \
343         vpshufb tt0, t0, t1; \
344         vpsrldq $1, t0, t0; \
345         vpshufb tt0, t0, t0; \
346         \
347         vpand l0, t0, t0; \
348         vpand l1, t1, t1; \
349         vpand l2, t2, t2; \
350         vpand l3, t3, t3; \
351         \
352         rol32_1_32(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
353         \
354         vpxor l4, t0, l4; \
355         vpbroadcastd krr, t0; /* only lowest 32-bit used */ \
356         vmovdqu l4, 4 * 32(l); \
357         vpxor l5, t1, l5; \
358         vmovdqu l5, 5 * 32(l); \
359         vpxor l6, t2, l6; \
360         vmovdqu l6, 6 * 32(l); \
361         vpxor l7, t3, l7; \
362         vmovdqu l7, 7 * 32(l); \
363         \
364         /* \
365          * t2 = krr; \
366          * t2 |= rr; \
367          * rl ^= t2; \
368          */ \
369         \
370         vpshufb tt0, t0, t3; \
371         vpsrldq $1, t0, t0; \
372         vpshufb tt0, t0, t2; \
373         vpsrldq $1, t0, t0; \
374         vpshufb tt0, t0, t1; \
375         vpsrldq $1, t0, t0; \
376         vpshufb tt0, t0, t0; \
377         \
378         vpor 4 * 32(r), t0, t0; \
379         vpor 5 * 32(r), t1, t1; \
380         vpor 6 * 32(r), t2, t2; \
381         vpor 7 * 32(r), t3, t3; \
382         \
383         vpxor 0 * 32(r), t0, t0; \
384         vpxor 1 * 32(r), t1, t1; \
385         vpxor 2 * 32(r), t2, t2; \
386         vpxor 3 * 32(r), t3, t3; \
387         vmovdqu t0, 0 * 32(r); \
388         vpbroadcastd krl, t0; /* only lowest 32-bit used */ \
389         vmovdqu t1, 1 * 32(r); \
390         vmovdqu t2, 2 * 32(r); \
391         vmovdqu t3, 3 * 32(r); \
392         \
393         /* \
394          * t2 = krl; \
395          * t2 &= rl; \
396          * rr ^= rol32(t2, 1); \
397          */ \
398         vpshufb tt0, t0, t3; \
399         vpsrldq $1, t0, t0; \
400         vpshufb tt0, t0, t2; \
401         vpsrldq $1, t0, t0; \
402         vpshufb tt0, t0, t1; \
403         vpsrldq $1, t0, t0; \
404         vpshufb tt0, t0, t0; \
405         \
406         vpand 0 * 32(r), t0, t0; \
407         vpand 1 * 32(r), t1, t1; \
408         vpand 2 * 32(r), t2, t2; \
409         vpand 3 * 32(r), t3, t3; \
410         \
411         rol32_1_32(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
412         \
413         vpxor 4 * 32(r), t0, t0; \
414         vpxor 5 * 32(r), t1, t1; \
415         vpxor 6 * 32(r), t2, t2; \
416         vpxor 7 * 32(r), t3, t3; \
417         vmovdqu t0, 4 * 32(r); \
418         vpbroadcastd klr, t0; /* only lowest 32-bit used */ \
419         vmovdqu t1, 5 * 32(r); \
420         vmovdqu t2, 6 * 32(r); \
421         vmovdqu t3, 7 * 32(r); \
422         \
423         /* \
424          * t0 = klr; \
425          * t0 |= lr; \
426          * ll ^= t0; \
427          */ \
428         \
429         vpshufb tt0, t0, t3; \
430         vpsrldq $1, t0, t0; \
431         vpshufb tt0, t0, t2; \
432         vpsrldq $1, t0, t0; \
433         vpshufb tt0, t0, t1; \
434         vpsrldq $1, t0, t0; \
435         vpshufb tt0, t0, t0; \
436         \
437         vpor l4, t0, t0; \
438         vpor l5, t1, t1; \
439         vpor l6, t2, t2; \
440         vpor l7, t3, t3; \
441         \
442         vpxor l0, t0, l0; \
443         vmovdqu l0, 0 * 32(l); \
444         vpxor l1, t1, l1; \
445         vmovdqu l1, 1 * 32(l); \
446         vpxor l2, t2, l2; \
447         vmovdqu l2, 2 * 32(l); \
448         vpxor l3, t3, l3; \
449         vmovdqu l3, 3 * 32(l);
450
451 #define transpose_4x4(x0, x1, x2, x3, t1, t2) \
452         vpunpckhdq x1, x0, t2; \
453         vpunpckldq x1, x0, x0; \
454         \
455         vpunpckldq x3, x2, t1; \
456         vpunpckhdq x3, x2, x2; \
457         \
458         vpunpckhqdq t1, x0, x1; \
459         vpunpcklqdq t1, x0, x0; \
460         \
461         vpunpckhqdq x2, t2, x3; \
462         vpunpcklqdq x2, t2, x2;
463
464 #define byteslice_16x16b_fast(a0, b0, c0, d0, a1, b1, c1, d1, a2, b2, c2, d2, \
465                               a3, b3, c3, d3, st0, st1) \
466         vmovdqu d2, st0; \
467         vmovdqu d3, st1; \
468         transpose_4x4(a0, a1, a2, a3, d2, d3); \
469         transpose_4x4(b0, b1, b2, b3, d2, d3); \
470         vmovdqu st0, d2; \
471         vmovdqu st1, d3; \
472         \
473         vmovdqu a0, st0; \
474         vmovdqu a1, st1; \
475         transpose_4x4(c0, c1, c2, c3, a0, a1); \
476         transpose_4x4(d0, d1, d2, d3, a0, a1); \
477         \
478         vbroadcasti128 .Lshufb_16x16b rRIP, a0; \
479         vmovdqu st1, a1; \
480         vpshufb a0, a2, a2; \
481         vpshufb a0, a3, a3; \
482         vpshufb a0, b0, b0; \
483         vpshufb a0, b1, b1; \
484         vpshufb a0, b2, b2; \
485         vpshufb a0, b3, b3; \
486         vpshufb a0, a1, a1; \
487         vpshufb a0, c0, c0; \
488         vpshufb a0, c1, c1; \
489         vpshufb a0, c2, c2; \
490         vpshufb a0, c3, c3; \
491         vpshufb a0, d0, d0; \
492         vpshufb a0, d1, d1; \
493         vpshufb a0, d2, d2; \
494         vpshufb a0, d3, d3; \
495         vmovdqu d3, st1; \
496         vmovdqu st0, d3; \
497         vpshufb a0, d3, a0; \
498         vmovdqu d2, st0; \
499         \
500         transpose_4x4(a0, b0, c0, d0, d2, d3); \
501         transpose_4x4(a1, b1, c1, d1, d2, d3); \
502         vmovdqu st0, d2; \
503         vmovdqu st1, d3; \
504         \
505         vmovdqu b0, st0; \
506         vmovdqu b1, st1; \
507         transpose_4x4(a2, b2, c2, d2, b0, b1); \
508         transpose_4x4(a3, b3, c3, d3, b0, b1); \
509         vmovdqu st0, b0; \
510         vmovdqu st1, b1; \
511         /* does not adjust output bytes inside vectors */
512
513 /* load blocks to registers and apply pre-whitening */
514 #define inpack32_pre(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
515                      y6, y7, rio, key) \
516         vpbroadcastq key, x0; \
517         vpshufb .Lpack_bswap rRIP, x0, x0; \
518         \
519         vpxor 0 * 32(rio), x0, y7; \
520         vpxor 1 * 32(rio), x0, y6; \
521         vpxor 2 * 32(rio), x0, y5; \
522         vpxor 3 * 32(rio), x0, y4; \
523         vpxor 4 * 32(rio), x0, y3; \
524         vpxor 5 * 32(rio), x0, y2; \
525         vpxor 6 * 32(rio), x0, y1; \
526         vpxor 7 * 32(rio), x0, y0; \
527         vpxor 8 * 32(rio), x0, x7; \
528         vpxor 9 * 32(rio), x0, x6; \
529         vpxor 10 * 32(rio), x0, x5; \
530         vpxor 11 * 32(rio), x0, x4; \
531         vpxor 12 * 32(rio), x0, x3; \
532         vpxor 13 * 32(rio), x0, x2; \
533         vpxor 14 * 32(rio), x0, x1; \
534         vpxor 15 * 32(rio), x0, x0;
535
536 /* byteslice pre-whitened blocks and store to temporary memory */
537 #define inpack32_post(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
538                       y6, y7, mem_ab, mem_cd) \
539         byteslice_16x16b_fast(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, \
540                               y4, y5, y6, y7, (mem_ab), (mem_cd)); \
541         \
542         vmovdqu x0, 0 * 32(mem_ab); \
543         vmovdqu x1, 1 * 32(mem_ab); \
544         vmovdqu x2, 2 * 32(mem_ab); \
545         vmovdqu x3, 3 * 32(mem_ab); \
546         vmovdqu x4, 4 * 32(mem_ab); \
547         vmovdqu x5, 5 * 32(mem_ab); \
548         vmovdqu x6, 6 * 32(mem_ab); \
549         vmovdqu x7, 7 * 32(mem_ab); \
550         vmovdqu y0, 0 * 32(mem_cd); \
551         vmovdqu y1, 1 * 32(mem_cd); \
552         vmovdqu y2, 2 * 32(mem_cd); \
553         vmovdqu y3, 3 * 32(mem_cd); \
554         vmovdqu y4, 4 * 32(mem_cd); \
555         vmovdqu y5, 5 * 32(mem_cd); \
556         vmovdqu y6, 6 * 32(mem_cd); \
557         vmovdqu y7, 7 * 32(mem_cd);
558
559 /* de-byteslice, apply post-whitening and store blocks */
560 #define outunpack32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, \
561                     y5, y6, y7, key, stack_tmp0, stack_tmp1) \
562         byteslice_16x16b_fast(y0, y4, x0, x4, y1, y5, x1, x5, y2, y6, x2, x6, \
563                               y3, y7, x3, x7, stack_tmp0, stack_tmp1); \
564         \
565         vmovdqu x0, stack_tmp0; \
566         \
567         vpbroadcastq key, x0; \
568         vpshufb .Lpack_bswap rRIP, x0, x0; \
569         \
570         vpxor x0, y7, y7; \
571         vpxor x0, y6, y6; \
572         vpxor x0, y5, y5; \
573         vpxor x0, y4, y4; \
574         vpxor x0, y3, y3; \
575         vpxor x0, y2, y2; \
576         vpxor x0, y1, y1; \
577         vpxor x0, y0, y0; \
578         vpxor x0, x7, x7; \
579         vpxor x0, x6, x6; \
580         vpxor x0, x5, x5; \
581         vpxor x0, x4, x4; \
582         vpxor x0, x3, x3; \
583         vpxor x0, x2, x2; \
584         vpxor x0, x1, x1; \
585         vpxor stack_tmp0, x0, x0;
586
587 #define write_output(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
588                      y6, y7, rio) \
589         vmovdqu x0, 0 * 32(rio); \
590         vmovdqu x1, 1 * 32(rio); \
591         vmovdqu x2, 2 * 32(rio); \
592         vmovdqu x3, 3 * 32(rio); \
593         vmovdqu x4, 4 * 32(rio); \
594         vmovdqu x5, 5 * 32(rio); \
595         vmovdqu x6, 6 * 32(rio); \
596         vmovdqu x7, 7 * 32(rio); \
597         vmovdqu y0, 8 * 32(rio); \
598         vmovdqu y1, 9 * 32(rio); \
599         vmovdqu y2, 10 * 32(rio); \
600         vmovdqu y3, 11 * 32(rio); \
601         vmovdqu y4, 12 * 32(rio); \
602         vmovdqu y5, 13 * 32(rio); \
603         vmovdqu y6, 14 * 32(rio); \
604         vmovdqu y7, 15 * 32(rio);
605
606 .text
607 .align 32
608
609 #define SHUFB_BYTES(idx) \
610         0 + (idx), 4 + (idx), 8 + (idx), 12 + (idx)
611
612 .Lshufb_16x16b:
613         .byte SHUFB_BYTES(0), SHUFB_BYTES(1), SHUFB_BYTES(2), SHUFB_BYTES(3)
614         .byte SHUFB_BYTES(0), SHUFB_BYTES(1), SHUFB_BYTES(2), SHUFB_BYTES(3)
615
616 .Lpack_bswap:
617         .long 0x00010203, 0x04050607, 0x80808080, 0x80808080
618         .long 0x00010203, 0x04050607, 0x80808080, 0x80808080
619
620 /* For CTR-mode IV byteswap */
621 .Lbswap128_mask:
622         .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
623
624 /*
625  * pre-SubByte transform
626  *
627  * pre-lookup for sbox1, sbox2, sbox3:
628  *   swap_bitendianness(
629  *       isom_map_camellia_to_aes(
630  *           camellia_f(
631  *               swap_bitendianess(in)
632  *           )
633  *       )
634  *   )
635  *
636  * (note: '⊕ 0xc5' inside camellia_f())
637  */
638 .Lpre_tf_lo_s1:
639         .byte 0x45, 0xe8, 0x40, 0xed, 0x2e, 0x83, 0x2b, 0x86
640         .byte 0x4b, 0xe6, 0x4e, 0xe3, 0x20, 0x8d, 0x25, 0x88
641 .Lpre_tf_hi_s1:
642         .byte 0x00, 0x51, 0xf1, 0xa0, 0x8a, 0xdb, 0x7b, 0x2a
643         .byte 0x09, 0x58, 0xf8, 0xa9, 0x83, 0xd2, 0x72, 0x23
644
645 /*
646  * pre-SubByte transform
647  *
648  * pre-lookup for sbox4:
649  *   swap_bitendianness(
650  *       isom_map_camellia_to_aes(
651  *           camellia_f(
652  *               swap_bitendianess(in <<< 1)
653  *           )
654  *       )
655  *   )
656  *
657  * (note: '⊕ 0xc5' inside camellia_f())
658  */
659 .Lpre_tf_lo_s4:
660         .byte 0x45, 0x40, 0x2e, 0x2b, 0x4b, 0x4e, 0x20, 0x25
661         .byte 0x14, 0x11, 0x7f, 0x7a, 0x1a, 0x1f, 0x71, 0x74
662 .Lpre_tf_hi_s4:
663         .byte 0x00, 0xf1, 0x8a, 0x7b, 0x09, 0xf8, 0x83, 0x72
664         .byte 0xad, 0x5c, 0x27, 0xd6, 0xa4, 0x55, 0x2e, 0xdf
665
666 /*
667  * post-SubByte transform
668  *
669  * post-lookup for sbox1, sbox4:
670  *  swap_bitendianness(
671  *      camellia_h(
672  *          isom_map_aes_to_camellia(
673  *              swap_bitendianness(
674  *                  aes_inverse_affine_transform(in)
675  *              )
676  *          )
677  *      )
678  *  )
679  *
680  * (note: '⊕ 0x6e' inside camellia_h())
681  */
682 .Lpost_tf_lo_s1:
683         .byte 0x3c, 0xcc, 0xcf, 0x3f, 0x32, 0xc2, 0xc1, 0x31
684         .byte 0xdc, 0x2c, 0x2f, 0xdf, 0xd2, 0x22, 0x21, 0xd1
685 .Lpost_tf_hi_s1:
686         .byte 0x00, 0xf9, 0x86, 0x7f, 0xd7, 0x2e, 0x51, 0xa8
687         .byte 0xa4, 0x5d, 0x22, 0xdb, 0x73, 0x8a, 0xf5, 0x0c
688
689 /*
690  * post-SubByte transform
691  *
692  * post-lookup for sbox2:
693  *  swap_bitendianness(
694  *      camellia_h(
695  *          isom_map_aes_to_camellia(
696  *              swap_bitendianness(
697  *                  aes_inverse_affine_transform(in)
698  *              )
699  *          )
700  *      )
701  *  ) <<< 1
702  *
703  * (note: '⊕ 0x6e' inside camellia_h())
704  */
705 .Lpost_tf_lo_s2:
706         .byte 0x78, 0x99, 0x9f, 0x7e, 0x64, 0x85, 0x83, 0x62
707         .byte 0xb9, 0x58, 0x5e, 0xbf, 0xa5, 0x44, 0x42, 0xa3
708 .Lpost_tf_hi_s2:
709         .byte 0x00, 0xf3, 0x0d, 0xfe, 0xaf, 0x5c, 0xa2, 0x51
710         .byte 0x49, 0xba, 0x44, 0xb7, 0xe6, 0x15, 0xeb, 0x18
711
712 /*
713  * post-SubByte transform
714  *
715  * post-lookup for sbox3:
716  *  swap_bitendianness(
717  *      camellia_h(
718  *          isom_map_aes_to_camellia(
719  *              swap_bitendianness(
720  *                  aes_inverse_affine_transform(in)
721  *              )
722  *          )
723  *      )
724  *  ) >>> 1
725  *
726  * (note: '⊕ 0x6e' inside camellia_h())
727  */
728 .Lpost_tf_lo_s3:
729         .byte 0x1e, 0x66, 0xe7, 0x9f, 0x19, 0x61, 0xe0, 0x98
730         .byte 0x6e, 0x16, 0x97, 0xef, 0x69, 0x11, 0x90, 0xe8
731 .Lpost_tf_hi_s3:
732         .byte 0x00, 0xfc, 0x43, 0xbf, 0xeb, 0x17, 0xa8, 0x54
733         .byte 0x52, 0xae, 0x11, 0xed, 0xb9, 0x45, 0xfa, 0x06
734
735 /* For isolating SubBytes from AESENCLAST, inverse shift row */
736 .Linv_shift_row:
737         .byte 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b
738         .byte 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03
739
740 .align 4
741 /* 4-bit mask */
742 .L0f0f0f0f:
743         .long 0x0f0f0f0f
744
745
746 .align 8
747 ELF(.type   __camellia_enc_blk32,@function;)
748
749 __camellia_enc_blk32:
750         /* input:
751          *      %rdi: ctx, CTX
752          *      %rax: temporary storage, 512 bytes
753          *      %ymm0..%ymm15: 32 plaintext blocks
754          * output:
755          *      %ymm0..%ymm15: 32 encrypted blocks, order swapped:
756          *       7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
757          */
758         CFI_STARTPROC();
759
760         leaq 8 * 32(%rax), %rcx;
761
762         inpack32_post(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
763                       %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
764                       %ymm15, %rax, %rcx);
765
766         enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
767                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
768                      %ymm15, %rax, %rcx, 0);
769
770         fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
771               %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
772               %ymm15,
773               ((key_table + (8) * 8) + 0)(CTX),
774               ((key_table + (8) * 8) + 4)(CTX),
775               ((key_table + (8) * 8) + 8)(CTX),
776               ((key_table + (8) * 8) + 12)(CTX));
777
778         enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
779                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
780                      %ymm15, %rax, %rcx, 8);
781
782         fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
783               %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
784               %ymm15,
785               ((key_table + (16) * 8) + 0)(CTX),
786               ((key_table + (16) * 8) + 4)(CTX),
787               ((key_table + (16) * 8) + 8)(CTX),
788               ((key_table + (16) * 8) + 12)(CTX));
789
790         enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
791                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
792                      %ymm15, %rax, %rcx, 16);
793
794         movl $24, %r8d;
795         cmpl $128, key_bitlength(CTX);
796         jne .Lenc_max32;
797
798 .Lenc_done:
799         /* load CD for output */
800         vmovdqu 0 * 32(%rcx), %ymm8;
801         vmovdqu 1 * 32(%rcx), %ymm9;
802         vmovdqu 2 * 32(%rcx), %ymm10;
803         vmovdqu 3 * 32(%rcx), %ymm11;
804         vmovdqu 4 * 32(%rcx), %ymm12;
805         vmovdqu 5 * 32(%rcx), %ymm13;
806         vmovdqu 6 * 32(%rcx), %ymm14;
807         vmovdqu 7 * 32(%rcx), %ymm15;
808
809         outunpack32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
810                     %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
811                     %ymm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 32(%rax));
812
813         ret;
814
815 .align 8
816 .Lenc_max32:
817         movl $32, %r8d;
818
819         fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
820               %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
821               %ymm15,
822               ((key_table + (24) * 8) + 0)(CTX),
823               ((key_table + (24) * 8) + 4)(CTX),
824               ((key_table + (24) * 8) + 8)(CTX),
825               ((key_table + (24) * 8) + 12)(CTX));
826
827         enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
828                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
829                      %ymm15, %rax, %rcx, 24);
830
831         jmp .Lenc_done;
832         CFI_ENDPROC();
833 ELF(.size __camellia_enc_blk32,.-__camellia_enc_blk32;)
834
835 .align 8
836 ELF(.type   __camellia_dec_blk32,@function;)
837
838 __camellia_dec_blk32:
839         /* input:
840          *      %rdi: ctx, CTX
841          *      %rax: temporary storage, 512 bytes
842          *      %r8d: 24 for 16 byte key, 32 for larger
843          *      %ymm0..%ymm15: 16 encrypted blocks
844          * output:
845          *      %ymm0..%ymm15: 16 plaintext blocks, order swapped:
846          *       7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
847          */
848         CFI_STARTPROC();
849
850         leaq 8 * 32(%rax), %rcx;
851
852         inpack32_post(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
853                       %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
854                       %ymm15, %rax, %rcx);
855
856         cmpl $32, %r8d;
857         je .Ldec_max32;
858
859 .Ldec_max24:
860         dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
861                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
862                      %ymm15, %rax, %rcx, 16);
863
864         fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
865               %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
866               %ymm15,
867               ((key_table + (16) * 8) + 8)(CTX),
868               ((key_table + (16) * 8) + 12)(CTX),
869               ((key_table + (16) * 8) + 0)(CTX),
870               ((key_table + (16) * 8) + 4)(CTX));
871
872         dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
873                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
874                      %ymm15, %rax, %rcx, 8);
875
876         fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
877               %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
878               %ymm15,
879               ((key_table + (8) * 8) + 8)(CTX),
880               ((key_table + (8) * 8) + 12)(CTX),
881               ((key_table + (8) * 8) + 0)(CTX),
882               ((key_table + (8) * 8) + 4)(CTX));
883
884         dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
885                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
886                      %ymm15, %rax, %rcx, 0);
887
888         /* load CD for output */
889         vmovdqu 0 * 32(%rcx), %ymm8;
890         vmovdqu 1 * 32(%rcx), %ymm9;
891         vmovdqu 2 * 32(%rcx), %ymm10;
892         vmovdqu 3 * 32(%rcx), %ymm11;
893         vmovdqu 4 * 32(%rcx), %ymm12;
894         vmovdqu 5 * 32(%rcx), %ymm13;
895         vmovdqu 6 * 32(%rcx), %ymm14;
896         vmovdqu 7 * 32(%rcx), %ymm15;
897
898         outunpack32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
899                     %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
900                     %ymm15, (key_table)(CTX), (%rax), 1 * 32(%rax));
901
902         ret;
903
904 .align 8
905 .Ldec_max32:
906         dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
907                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
908                      %ymm15, %rax, %rcx, 24);
909
910         fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
911               %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
912               %ymm15,
913               ((key_table + (24) * 8) + 8)(CTX),
914               ((key_table + (24) * 8) + 12)(CTX),
915               ((key_table + (24) * 8) + 0)(CTX),
916               ((key_table + (24) * 8) + 4)(CTX));
917
918         jmp .Ldec_max24;
919         CFI_ENDPROC();
920 ELF(.size __camellia_dec_blk32,.-__camellia_dec_blk32;)
921
922 #define inc_le128(x, minus_one, tmp) \
923         vpcmpeqq minus_one, x, tmp; \
924         vpsubq minus_one, x, x; \
925         vpslldq $8, tmp, tmp; \
926         vpsubq tmp, x, x;
927
928 .align 8
929 .globl _gcry_camellia_aesni_avx2_ctr_enc
930 ELF(.type   _gcry_camellia_aesni_avx2_ctr_enc,@function;)
931
932 _gcry_camellia_aesni_avx2_ctr_enc:
933         /* input:
934          *      %rdi: ctx, CTX
935          *      %rsi: dst (32 blocks)
936          *      %rdx: src (32 blocks)
937          *      %rcx: iv (big endian, 128bit)
938          */
939         CFI_STARTPROC();
940
941         pushq %rbp;
942         CFI_PUSH(%rbp);
943         movq %rsp, %rbp;
944         CFI_DEF_CFA_REGISTER(%rbp);
945
946         movq 8(%rcx), %r11;
947         bswapq %r11;
948
949         vzeroupper;
950
951         subq $(16 * 32), %rsp;
952         andq $~63, %rsp;
953         movq %rsp, %rax;
954
955         vpcmpeqd %ymm15, %ymm15, %ymm15;
956         vpsrldq $8, %ymm15, %ymm15; /* ab: -1:0 ; cd: -1:0 */
957
958         /* load IV and byteswap */
959         vmovdqu (%rcx), %xmm0;
960         vpshufb .Lbswap128_mask rRIP, %xmm0, %xmm0;
961         vmovdqa %xmm0, %xmm1;
962         inc_le128(%xmm0, %xmm15, %xmm14);
963         vbroadcasti128 .Lbswap128_mask rRIP, %ymm14;
964         vinserti128 $1, %xmm0, %ymm1, %ymm0;
965         vpshufb %ymm14, %ymm0, %ymm13;
966         vmovdqu %ymm13, 15 * 32(%rax);
967
968         /* check need for handling 64-bit overflow and carry */
969         cmpq $(0xffffffffffffffff - 32), %r11;
970         ja .Lload_ctr_carry;
971
972         /* construct IVs */
973         vpaddq %ymm15, %ymm15, %ymm15; /* ab: -2:0 ; cd: -2:0 */
974         vpsubq %ymm15, %ymm0, %ymm0;
975         vpshufb %ymm14, %ymm0, %ymm13;
976         vmovdqu %ymm13, 14 * 32(%rax);
977         vpsubq %ymm15, %ymm0, %ymm0;
978         vpshufb %ymm14, %ymm0, %ymm13;
979         vmovdqu %ymm13, 13 * 32(%rax);
980         vpsubq %ymm15, %ymm0, %ymm0;
981         vpshufb %ymm14, %ymm0, %ymm12;
982         vpsubq %ymm15, %ymm0, %ymm0;
983         vpshufb %ymm14, %ymm0, %ymm11;
984         vpsubq %ymm15, %ymm0, %ymm0;
985         vpshufb %ymm14, %ymm0, %ymm10;
986         vpsubq %ymm15, %ymm0, %ymm0;
987         vpshufb %ymm14, %ymm0, %ymm9;
988         vpsubq %ymm15, %ymm0, %ymm0;
989         vpshufb %ymm14, %ymm0, %ymm8;
990         vpsubq %ymm15, %ymm0, %ymm0;
991         vpshufb %ymm14, %ymm0, %ymm7;
992         vpsubq %ymm15, %ymm0, %ymm0;
993         vpshufb %ymm14, %ymm0, %ymm6;
994         vpsubq %ymm15, %ymm0, %ymm0;
995         vpshufb %ymm14, %ymm0, %ymm5;
996         vpsubq %ymm15, %ymm0, %ymm0;
997         vpshufb %ymm14, %ymm0, %ymm4;
998         vpsubq %ymm15, %ymm0, %ymm0;
999         vpshufb %ymm14, %ymm0, %ymm3;
1000         vpsubq %ymm15, %ymm0, %ymm0;
1001         vpshufb %ymm14, %ymm0, %ymm2;
1002         vpsubq %ymm15, %ymm0, %ymm0;
1003         vpshufb %ymm14, %ymm0, %ymm1;
1004         vpsubq %ymm15, %ymm0, %ymm0;  /* +30 ; +31 */
1005         vpsubq %xmm15, %xmm0, %xmm13; /* +32 */
1006         vpshufb %ymm14, %ymm0, %ymm0;
1007         vpshufb %xmm14, %xmm13, %xmm13;
1008         vmovdqu %xmm13, (%rcx);
1009
1010         jmp .Lload_ctr_done;
1011
1012 .align 4
1013 .Lload_ctr_carry:
1014         /* construct IVs */
1015         inc_le128(%ymm0, %ymm15, %ymm13); /* ab: le1 ; cd: le2 */
1016         inc_le128(%ymm0, %ymm15, %ymm13); /* ab: le2 ; cd: le3 */
1017         vpshufb %ymm14, %ymm0, %ymm13;
1018         vmovdqu %ymm13, 14 * 32(%rax);
1019         inc_le128(%ymm0, %ymm15, %ymm13);
1020         inc_le128(%ymm0, %ymm15, %ymm13);
1021         vpshufb %ymm14, %ymm0, %ymm13;
1022         vmovdqu %ymm13, 13 * 32(%rax);
1023         inc_le128(%ymm0, %ymm15, %ymm13);
1024         inc_le128(%ymm0, %ymm15, %ymm13);
1025         vpshufb %ymm14, %ymm0, %ymm12;
1026         inc_le128(%ymm0, %ymm15, %ymm13);
1027         inc_le128(%ymm0, %ymm15, %ymm13);
1028         vpshufb %ymm14, %ymm0, %ymm11;
1029         inc_le128(%ymm0, %ymm15, %ymm13);
1030         inc_le128(%ymm0, %ymm15, %ymm13);
1031         vpshufb %ymm14, %ymm0, %ymm10;
1032         inc_le128(%ymm0, %ymm15, %ymm13);
1033         inc_le128(%ymm0, %ymm15, %ymm13);
1034         vpshufb %ymm14, %ymm0, %ymm9;
1035         inc_le128(%ymm0, %ymm15, %ymm13);
1036         inc_le128(%ymm0, %ymm15, %ymm13);
1037         vpshufb %ymm14, %ymm0, %ymm8;
1038         inc_le128(%ymm0, %ymm15, %ymm13);
1039         inc_le128(%ymm0, %ymm15, %ymm13);
1040         vpshufb %ymm14, %ymm0, %ymm7;
1041         inc_le128(%ymm0, %ymm15, %ymm13);
1042         inc_le128(%ymm0, %ymm15, %ymm13);
1043         vpshufb %ymm14, %ymm0, %ymm6;
1044         inc_le128(%ymm0, %ymm15, %ymm13);
1045         inc_le128(%ymm0, %ymm15, %ymm13);
1046         vpshufb %ymm14, %ymm0, %ymm5;
1047         inc_le128(%ymm0, %ymm15, %ymm13);
1048         inc_le128(%ymm0, %ymm15, %ymm13);
1049         vpshufb %ymm14, %ymm0, %ymm4;
1050         inc_le128(%ymm0, %ymm15, %ymm13);
1051         inc_le128(%ymm0, %ymm15, %ymm13);
1052         vpshufb %ymm14, %ymm0, %ymm3;
1053         inc_le128(%ymm0, %ymm15, %ymm13);
1054         inc_le128(%ymm0, %ymm15, %ymm13);
1055         vpshufb %ymm14, %ymm0, %ymm2;
1056         inc_le128(%ymm0, %ymm15, %ymm13);
1057         inc_le128(%ymm0, %ymm15, %ymm13);
1058         vpshufb %ymm14, %ymm0, %ymm1;
1059         inc_le128(%ymm0, %ymm15, %ymm13);
1060         inc_le128(%ymm0, %ymm15, %ymm13);
1061         vextracti128 $1, %ymm0, %xmm13;
1062         vpshufb %ymm14, %ymm0, %ymm0;
1063         inc_le128(%xmm13, %xmm15, %xmm14);
1064         vpshufb .Lbswap128_mask rRIP, %xmm13, %xmm13;
1065         vmovdqu %xmm13, (%rcx);
1066
1067 .align 4
1068 .Lload_ctr_done:
1069         /* inpack16_pre: */
1070         vpbroadcastq (key_table)(CTX), %ymm15;
1071         vpshufb .Lpack_bswap rRIP, %ymm15, %ymm15;
1072         vpxor %ymm0, %ymm15, %ymm0;
1073         vpxor %ymm1, %ymm15, %ymm1;
1074         vpxor %ymm2, %ymm15, %ymm2;
1075         vpxor %ymm3, %ymm15, %ymm3;
1076         vpxor %ymm4, %ymm15, %ymm4;
1077         vpxor %ymm5, %ymm15, %ymm5;
1078         vpxor %ymm6, %ymm15, %ymm6;
1079         vpxor %ymm7, %ymm15, %ymm7;
1080         vpxor %ymm8, %ymm15, %ymm8;
1081         vpxor %ymm9, %ymm15, %ymm9;
1082         vpxor %ymm10, %ymm15, %ymm10;
1083         vpxor %ymm11, %ymm15, %ymm11;
1084         vpxor %ymm12, %ymm15, %ymm12;
1085         vpxor 13 * 32(%rax), %ymm15, %ymm13;
1086         vpxor 14 * 32(%rax), %ymm15, %ymm14;
1087         vpxor 15 * 32(%rax), %ymm15, %ymm15;
1088
1089         call __camellia_enc_blk32;
1090
1091         vpxor 0 * 32(%rdx), %ymm7, %ymm7;
1092         vpxor 1 * 32(%rdx), %ymm6, %ymm6;
1093         vpxor 2 * 32(%rdx), %ymm5, %ymm5;
1094         vpxor 3 * 32(%rdx), %ymm4, %ymm4;
1095         vpxor 4 * 32(%rdx), %ymm3, %ymm3;
1096         vpxor 5 * 32(%rdx), %ymm2, %ymm2;
1097         vpxor 6 * 32(%rdx), %ymm1, %ymm1;
1098         vpxor 7 * 32(%rdx), %ymm0, %ymm0;
1099         vpxor 8 * 32(%rdx), %ymm15, %ymm15;
1100         vpxor 9 * 32(%rdx), %ymm14, %ymm14;
1101         vpxor 10 * 32(%rdx), %ymm13, %ymm13;
1102         vpxor 11 * 32(%rdx), %ymm12, %ymm12;
1103         vpxor 12 * 32(%rdx), %ymm11, %ymm11;
1104         vpxor 13 * 32(%rdx), %ymm10, %ymm10;
1105         vpxor 14 * 32(%rdx), %ymm9, %ymm9;
1106         vpxor 15 * 32(%rdx), %ymm8, %ymm8;
1107         leaq 32 * 16(%rdx), %rdx;
1108
1109         write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
1110                      %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
1111                      %ymm8, %rsi);
1112
1113         vzeroall;
1114
1115         leave;
1116         CFI_LEAVE();
1117         ret;
1118         CFI_ENDPROC();
1119 ELF(.size _gcry_camellia_aesni_avx2_ctr_enc,.-_gcry_camellia_aesni_avx2_ctr_enc;)
1120
1121 .align 8
1122 .globl _gcry_camellia_aesni_avx2_cbc_dec
1123 ELF(.type   _gcry_camellia_aesni_avx2_cbc_dec,@function;)
1124
1125 _gcry_camellia_aesni_avx2_cbc_dec:
1126         /* input:
1127          *      %rdi: ctx, CTX
1128          *      %rsi: dst (32 blocks)
1129          *      %rdx: src (32 blocks)
1130          *      %rcx: iv
1131          */
1132         CFI_STARTPROC();
1133
1134         pushq %rbp;
1135         CFI_PUSH(%rbp);
1136         movq %rsp, %rbp;
1137         CFI_DEF_CFA_REGISTER(%rbp);
1138
1139         vzeroupper;
1140
1141         movq %rcx, %r9;
1142
1143         cmpl $128, key_bitlength(CTX);
1144         movl $32, %r8d;
1145         movl $24, %eax;
1146         cmovel %eax, %r8d; /* max */
1147
1148         subq $(16 * 32), %rsp;
1149         andq $~63, %rsp;
1150         movq %rsp, %rax;
1151
1152         inpack32_pre(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
1153                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
1154                      %ymm15, %rdx, (key_table)(CTX, %r8, 8));
1155
1156         call __camellia_dec_blk32;
1157
1158         /* XOR output with IV */
1159         vmovdqu %ymm8, (%rax);
1160         vmovdqu (%r9), %xmm8;
1161         vinserti128 $1, (%rdx), %ymm8, %ymm8;
1162         vpxor %ymm8, %ymm7, %ymm7;
1163         vmovdqu (%rax), %ymm8;
1164         vpxor (0 * 32 + 16)(%rdx), %ymm6, %ymm6;
1165         vpxor (1 * 32 + 16)(%rdx), %ymm5, %ymm5;
1166         vpxor (2 * 32 + 16)(%rdx), %ymm4, %ymm4;
1167         vpxor (3 * 32 + 16)(%rdx), %ymm3, %ymm3;
1168         vpxor (4 * 32 + 16)(%rdx), %ymm2, %ymm2;
1169         vpxor (5 * 32 + 16)(%rdx), %ymm1, %ymm1;
1170         vpxor (6 * 32 + 16)(%rdx), %ymm0, %ymm0;
1171         vpxor (7 * 32 + 16)(%rdx), %ymm15, %ymm15;
1172         vpxor (8 * 32 + 16)(%rdx), %ymm14, %ymm14;
1173         vpxor (9 * 32 + 16)(%rdx), %ymm13, %ymm13;
1174         vpxor (10 * 32 + 16)(%rdx), %ymm12, %ymm12;
1175         vpxor (11 * 32 + 16)(%rdx), %ymm11, %ymm11;
1176         vpxor (12 * 32 + 16)(%rdx), %ymm10, %ymm10;
1177         vpxor (13 * 32 + 16)(%rdx), %ymm9, %ymm9;
1178         vpxor (14 * 32 + 16)(%rdx), %ymm8, %ymm8;
1179         movq (15 * 32 + 16 + 0)(%rdx), %rax;
1180         movq (15 * 32 + 16 + 8)(%rdx), %rcx;
1181
1182         write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
1183                      %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
1184                      %ymm8, %rsi);
1185
1186         /* store new IV */
1187         movq %rax, (0)(%r9);
1188         movq %rcx, (8)(%r9);
1189
1190         vzeroall;
1191
1192         leave;
1193         CFI_LEAVE();
1194         ret;
1195         CFI_ENDPROC();
1196 ELF(.size _gcry_camellia_aesni_avx2_cbc_dec,.-_gcry_camellia_aesni_avx2_cbc_dec;)
1197
1198 .align 8
1199 .globl _gcry_camellia_aesni_avx2_cfb_dec
1200 ELF(.type   _gcry_camellia_aesni_avx2_cfb_dec,@function;)
1201
1202 _gcry_camellia_aesni_avx2_cfb_dec:
1203         /* input:
1204          *      %rdi: ctx, CTX
1205          *      %rsi: dst (32 blocks)
1206          *      %rdx: src (32 blocks)
1207          *      %rcx: iv
1208          */
1209         CFI_STARTPROC();
1210
1211         pushq %rbp;
1212         CFI_PUSH(%rbp);
1213         movq %rsp, %rbp;
1214         CFI_DEF_CFA_REGISTER(%rbp);
1215
1216         vzeroupper;
1217
1218         subq $(16 * 32), %rsp;
1219         andq $~63, %rsp;
1220         movq %rsp, %rax;
1221
1222         /* inpack16_pre: */
1223         vpbroadcastq (key_table)(CTX), %ymm0;
1224         vpshufb .Lpack_bswap rRIP, %ymm0, %ymm0;
1225         vmovdqu (%rcx), %xmm15;
1226         vinserti128 $1, (%rdx), %ymm15, %ymm15;
1227         vpxor %ymm15, %ymm0, %ymm15;
1228         vmovdqu (15 * 32 + 16)(%rdx), %xmm1;
1229         vmovdqu %xmm1, (%rcx); /* store new IV */
1230         vpxor (0 * 32 + 16)(%rdx), %ymm0, %ymm14;
1231         vpxor (1 * 32 + 16)(%rdx), %ymm0, %ymm13;
1232         vpxor (2 * 32 + 16)(%rdx), %ymm0, %ymm12;
1233         vpxor (3 * 32 + 16)(%rdx), %ymm0, %ymm11;
1234         vpxor (4 * 32 + 16)(%rdx), %ymm0, %ymm10;
1235         vpxor (5 * 32 + 16)(%rdx), %ymm0, %ymm9;
1236         vpxor (6 * 32 + 16)(%rdx), %ymm0, %ymm8;
1237         vpxor (7 * 32 + 16)(%rdx), %ymm0, %ymm7;
1238         vpxor (8 * 32 + 16)(%rdx), %ymm0, %ymm6;
1239         vpxor (9 * 32 + 16)(%rdx), %ymm0, %ymm5;
1240         vpxor (10 * 32 + 16)(%rdx), %ymm0, %ymm4;
1241         vpxor (11 * 32 + 16)(%rdx), %ymm0, %ymm3;
1242         vpxor (12 * 32 + 16)(%rdx), %ymm0, %ymm2;
1243         vpxor (13 * 32 + 16)(%rdx), %ymm0, %ymm1;
1244         vpxor (14 * 32 + 16)(%rdx), %ymm0, %ymm0;
1245
1246         call __camellia_enc_blk32;
1247
1248         vpxor 0 * 32(%rdx), %ymm7, %ymm7;
1249         vpxor 1 * 32(%rdx), %ymm6, %ymm6;
1250         vpxor 2 * 32(%rdx), %ymm5, %ymm5;
1251         vpxor 3 * 32(%rdx), %ymm4, %ymm4;
1252         vpxor 4 * 32(%rdx), %ymm3, %ymm3;
1253         vpxor 5 * 32(%rdx), %ymm2, %ymm2;
1254         vpxor 6 * 32(%rdx), %ymm1, %ymm1;
1255         vpxor 7 * 32(%rdx), %ymm0, %ymm0;
1256         vpxor 8 * 32(%rdx), %ymm15, %ymm15;
1257         vpxor 9 * 32(%rdx), %ymm14, %ymm14;
1258         vpxor 10 * 32(%rdx), %ymm13, %ymm13;
1259         vpxor 11 * 32(%rdx), %ymm12, %ymm12;
1260         vpxor 12 * 32(%rdx), %ymm11, %ymm11;
1261         vpxor 13 * 32(%rdx), %ymm10, %ymm10;
1262         vpxor 14 * 32(%rdx), %ymm9, %ymm9;
1263         vpxor 15 * 32(%rdx), %ymm8, %ymm8;
1264
1265         write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
1266                      %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
1267                      %ymm8, %rsi);
1268
1269         vzeroall;
1270
1271         leave;
1272         CFI_LEAVE();
1273         ret;
1274         CFI_ENDPROC();
1275 ELF(.size _gcry_camellia_aesni_avx2_cfb_dec,.-_gcry_camellia_aesni_avx2_cfb_dec;)
1276
1277 .align 8
1278 .globl _gcry_camellia_aesni_avx2_ocb_enc
1279 ELF(.type   _gcry_camellia_aesni_avx2_ocb_enc,@function;)
1280
1281 _gcry_camellia_aesni_avx2_ocb_enc:
1282         /* input:
1283          *      %rdi: ctx, CTX
1284          *      %rsi: dst (32 blocks)
1285          *      %rdx: src (32 blocks)
1286          *      %rcx: offset
1287          *      %r8 : checksum
1288          *      %r9 : L pointers (void *L[32])
1289          */
1290         CFI_STARTPROC();
1291
1292         pushq %rbp;
1293         CFI_PUSH(%rbp);
1294         movq %rsp, %rbp;
1295         CFI_DEF_CFA_REGISTER(%rbp);
1296
1297         vzeroupper;
1298
1299         subq $(16 * 32 + 4 * 8), %rsp;
1300         andq $~63, %rsp;
1301         movq %rsp, %rax;
1302
1303         movq %r10, (16 * 32 + 0 * 8)(%rsp);
1304         movq %r11, (16 * 32 + 1 * 8)(%rsp);
1305         movq %r12, (16 * 32 + 2 * 8)(%rsp);
1306         movq %r13, (16 * 32 + 3 * 8)(%rsp);
1307         CFI_REG_ON_STACK(r10, 16 * 32 + 0 * 8);
1308         CFI_REG_ON_STACK(r11, 16 * 32 + 1 * 8);
1309         CFI_REG_ON_STACK(r12, 16 * 32 + 2 * 8);
1310         CFI_REG_ON_STACK(r13, 16 * 32 + 3 * 8);
1311
1312         vmovdqu (%rcx), %xmm14;
1313         vmovdqu (%r8), %xmm13;
1314
1315         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
1316         /* Checksum_i = Checksum_{i-1} xor P_i  */
1317         /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
1318
1319 #define OCB_INPUT(n, l0reg, l1reg, yreg) \
1320           vmovdqu (n * 32)(%rdx), yreg; \
1321           vpxor (l0reg), %xmm14, %xmm15; \
1322           vpxor (l1reg), %xmm15, %xmm14; \
1323           vinserti128 $1, %xmm14, %ymm15, %ymm15; \
1324           vpxor yreg, %ymm13, %ymm13; \
1325           vpxor yreg, %ymm15, yreg; \
1326           vmovdqu %ymm15, (n * 32)(%rsi);
1327
1328         movq (0 * 8)(%r9), %r10;
1329         movq (1 * 8)(%r9), %r11;
1330         movq (2 * 8)(%r9), %r12;
1331         movq (3 * 8)(%r9), %r13;
1332         OCB_INPUT(0, %r10, %r11, %ymm0);
1333         vmovdqu %ymm0, (15 * 32)(%rax);
1334         OCB_INPUT(1, %r12, %r13, %ymm0);
1335         vmovdqu %ymm0, (14 * 32)(%rax);
1336         movq (4 * 8)(%r9), %r10;
1337         movq (5 * 8)(%r9), %r11;
1338         movq (6 * 8)(%r9), %r12;
1339         movq (7 * 8)(%r9), %r13;
1340         OCB_INPUT(2, %r10, %r11, %ymm0);
1341         vmovdqu %ymm0, (13 * 32)(%rax);
1342         OCB_INPUT(3, %r12, %r13, %ymm12);
1343         movq (8 * 8)(%r9), %r10;
1344         movq (9 * 8)(%r9), %r11;
1345         movq (10 * 8)(%r9), %r12;
1346         movq (11 * 8)(%r9), %r13;
1347         OCB_INPUT(4, %r10, %r11, %ymm11);
1348         OCB_INPUT(5, %r12, %r13, %ymm10);
1349         movq (12 * 8)(%r9), %r10;
1350         movq (13 * 8)(%r9), %r11;
1351         movq (14 * 8)(%r9), %r12;
1352         movq (15 * 8)(%r9), %r13;
1353         OCB_INPUT(6, %r10, %r11, %ymm9);
1354         OCB_INPUT(7, %r12, %r13, %ymm8);
1355         movq (16 * 8)(%r9), %r10;
1356         movq (17 * 8)(%r9), %r11;
1357         movq (18 * 8)(%r9), %r12;
1358         movq (19 * 8)(%r9), %r13;
1359         OCB_INPUT(8, %r10, %r11, %ymm7);
1360         OCB_INPUT(9, %r12, %r13, %ymm6);
1361         movq (20 * 8)(%r9), %r10;
1362         movq (21 * 8)(%r9), %r11;
1363         movq (22 * 8)(%r9), %r12;
1364         movq (23 * 8)(%r9), %r13;
1365         OCB_INPUT(10, %r10, %r11, %ymm5);
1366         OCB_INPUT(11, %r12, %r13, %ymm4);
1367         movq (24 * 8)(%r9), %r10;
1368         movq (25 * 8)(%r9), %r11;
1369         movq (26 * 8)(%r9), %r12;
1370         movq (27 * 8)(%r9), %r13;
1371         OCB_INPUT(12, %r10, %r11, %ymm3);
1372         OCB_INPUT(13, %r12, %r13, %ymm2);
1373         movq (28 * 8)(%r9), %r10;
1374         movq (29 * 8)(%r9), %r11;
1375         movq (30 * 8)(%r9), %r12;
1376         movq (31 * 8)(%r9), %r13;
1377         OCB_INPUT(14, %r10, %r11, %ymm1);
1378         OCB_INPUT(15, %r12, %r13, %ymm0);
1379 #undef OCB_INPUT
1380
1381         vextracti128 $1, %ymm13, %xmm15;
1382         vmovdqu %xmm14, (%rcx);
1383         vpxor %xmm13, %xmm15, %xmm15;
1384         vmovdqu %xmm15, (%r8);
1385
1386         /* inpack16_pre: */
1387         vpbroadcastq (key_table)(CTX), %ymm15;
1388         vpshufb .Lpack_bswap rRIP, %ymm15, %ymm15;
1389         vpxor %ymm0, %ymm15, %ymm0;
1390         vpxor %ymm1, %ymm15, %ymm1;
1391         vpxor %ymm2, %ymm15, %ymm2;
1392         vpxor %ymm3, %ymm15, %ymm3;
1393         vpxor %ymm4, %ymm15, %ymm4;
1394         vpxor %ymm5, %ymm15, %ymm5;
1395         vpxor %ymm6, %ymm15, %ymm6;
1396         vpxor %ymm7, %ymm15, %ymm7;
1397         vpxor %ymm8, %ymm15, %ymm8;
1398         vpxor %ymm9, %ymm15, %ymm9;
1399         vpxor %ymm10, %ymm15, %ymm10;
1400         vpxor %ymm11, %ymm15, %ymm11;
1401         vpxor %ymm12, %ymm15, %ymm12;
1402         vpxor 13 * 32(%rax), %ymm15, %ymm13;
1403         vpxor 14 * 32(%rax), %ymm15, %ymm14;
1404         vpxor 15 * 32(%rax), %ymm15, %ymm15;
1405
1406         call __camellia_enc_blk32;
1407
1408         vpxor 0 * 32(%rsi), %ymm7, %ymm7;
1409         vpxor 1 * 32(%rsi), %ymm6, %ymm6;
1410         vpxor 2 * 32(%rsi), %ymm5, %ymm5;
1411         vpxor 3 * 32(%rsi), %ymm4, %ymm4;
1412         vpxor 4 * 32(%rsi), %ymm3, %ymm3;
1413         vpxor 5 * 32(%rsi), %ymm2, %ymm2;
1414         vpxor 6 * 32(%rsi), %ymm1, %ymm1;
1415         vpxor 7 * 32(%rsi), %ymm0, %ymm0;
1416         vpxor 8 * 32(%rsi), %ymm15, %ymm15;
1417         vpxor 9 * 32(%rsi), %ymm14, %ymm14;
1418         vpxor 10 * 32(%rsi), %ymm13, %ymm13;
1419         vpxor 11 * 32(%rsi), %ymm12, %ymm12;
1420         vpxor 12 * 32(%rsi), %ymm11, %ymm11;
1421         vpxor 13 * 32(%rsi), %ymm10, %ymm10;
1422         vpxor 14 * 32(%rsi), %ymm9, %ymm9;
1423         vpxor 15 * 32(%rsi), %ymm8, %ymm8;
1424
1425         write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
1426                      %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
1427                      %ymm8, %rsi);
1428
1429         vzeroall;
1430
1431         movq (16 * 32 + 0 * 8)(%rsp), %r10;
1432         movq (16 * 32 + 1 * 8)(%rsp), %r11;
1433         movq (16 * 32 + 2 * 8)(%rsp), %r12;
1434         movq (16 * 32 + 3 * 8)(%rsp), %r13;
1435         CFI_RESTORE(%r10);
1436         CFI_RESTORE(%r11);
1437         CFI_RESTORE(%r12);
1438         CFI_RESTORE(%r13);
1439
1440         leave;
1441         CFI_LEAVE();
1442         ret;
1443         CFI_ENDPROC();
1444 ELF(.size _gcry_camellia_aesni_avx2_ocb_enc,.-_gcry_camellia_aesni_avx2_ocb_enc;)
1445
1446 .align 8
1447 .globl _gcry_camellia_aesni_avx2_ocb_dec
1448 ELF(.type   _gcry_camellia_aesni_avx2_ocb_dec,@function;)
1449
1450 _gcry_camellia_aesni_avx2_ocb_dec:
1451         /* input:
1452          *      %rdi: ctx, CTX
1453          *      %rsi: dst (32 blocks)
1454          *      %rdx: src (32 blocks)
1455          *      %rcx: offset
1456          *      %r8 : checksum
1457          *      %r9 : L pointers (void *L[32])
1458          */
1459         CFI_STARTPROC();
1460
1461         pushq %rbp;
1462         CFI_PUSH(%rbp);
1463         movq %rsp, %rbp;
1464         CFI_DEF_CFA_REGISTER(%rbp);
1465
1466         vzeroupper;
1467
1468         subq $(16 * 32 + 4 * 8), %rsp;
1469         andq $~63, %rsp;
1470         movq %rsp, %rax;
1471
1472         movq %r10, (16 * 32 + 0 * 8)(%rsp);
1473         movq %r11, (16 * 32 + 1 * 8)(%rsp);
1474         movq %r12, (16 * 32 + 2 * 8)(%rsp);
1475         movq %r13, (16 * 32 + 3 * 8)(%rsp);
1476         CFI_REG_ON_STACK(r10, 16 * 32 + 0 * 8);
1477         CFI_REG_ON_STACK(r11, 16 * 32 + 1 * 8);
1478         CFI_REG_ON_STACK(r12, 16 * 32 + 2 * 8);
1479         CFI_REG_ON_STACK(r13, 16 * 32 + 3 * 8);
1480
1481         vmovdqu (%rcx), %xmm14;
1482
1483         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
1484         /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)  */
1485
1486 #define OCB_INPUT(n, l0reg, l1reg, yreg) \
1487           vmovdqu (n * 32)(%rdx), yreg; \
1488           vpxor (l0reg), %xmm14, %xmm15; \
1489           vpxor (l1reg), %xmm15, %xmm14; \
1490           vinserti128 $1, %xmm14, %ymm15, %ymm15; \
1491           vpxor yreg, %ymm15, yreg; \
1492           vmovdqu %ymm15, (n * 32)(%rsi);
1493
1494         movq (0 * 8)(%r9), %r10;
1495         movq (1 * 8)(%r9), %r11;
1496         movq (2 * 8)(%r9), %r12;
1497         movq (3 * 8)(%r9), %r13;
1498         OCB_INPUT(0, %r10, %r11, %ymm0);
1499         vmovdqu %ymm0, (15 * 32)(%rax);
1500         OCB_INPUT(1, %r12, %r13, %ymm0);
1501         vmovdqu %ymm0, (14 * 32)(%rax);
1502         movq (4 * 8)(%r9), %r10;
1503         movq (5 * 8)(%r9), %r11;
1504         movq (6 * 8)(%r9), %r12;
1505         movq (7 * 8)(%r9), %r13;
1506         OCB_INPUT(2, %r10, %r11, %ymm13);
1507         OCB_INPUT(3, %r12, %r13, %ymm12);
1508         movq (8 * 8)(%r9), %r10;
1509         movq (9 * 8)(%r9), %r11;
1510         movq (10 * 8)(%r9), %r12;
1511         movq (11 * 8)(%r9), %r13;
1512         OCB_INPUT(4, %r10, %r11, %ymm11);
1513         OCB_INPUT(5, %r12, %r13, %ymm10);
1514         movq (12 * 8)(%r9), %r10;
1515         movq (13 * 8)(%r9), %r11;
1516         movq (14 * 8)(%r9), %r12;
1517         movq (15 * 8)(%r9), %r13;
1518         OCB_INPUT(6, %r10, %r11, %ymm9);
1519         OCB_INPUT(7, %r12, %r13, %ymm8);
1520         movq (16 * 8)(%r9), %r10;
1521         movq (17 * 8)(%r9), %r11;
1522         movq (18 * 8)(%r9), %r12;
1523         movq (19 * 8)(%r9), %r13;
1524         OCB_INPUT(8, %r10, %r11, %ymm7);
1525         OCB_INPUT(9, %r12, %r13, %ymm6);
1526         movq (20 * 8)(%r9), %r10;
1527         movq (21 * 8)(%r9), %r11;
1528         movq (22 * 8)(%r9), %r12;
1529         movq (23 * 8)(%r9), %r13;
1530         OCB_INPUT(10, %r10, %r11, %ymm5);
1531         OCB_INPUT(11, %r12, %r13, %ymm4);
1532         movq (24 * 8)(%r9), %r10;
1533         movq (25 * 8)(%r9), %r11;
1534         movq (26 * 8)(%r9), %r12;
1535         movq (27 * 8)(%r9), %r13;
1536         OCB_INPUT(12, %r10, %r11, %ymm3);
1537         OCB_INPUT(13, %r12, %r13, %ymm2);
1538         movq (28 * 8)(%r9), %r10;
1539         movq (29 * 8)(%r9), %r11;
1540         movq (30 * 8)(%r9), %r12;
1541         movq (31 * 8)(%r9), %r13;
1542         OCB_INPUT(14, %r10, %r11, %ymm1);
1543         OCB_INPUT(15, %r12, %r13, %ymm0);
1544 #undef OCB_INPUT
1545
1546         vmovdqu %xmm14, (%rcx);
1547
1548         movq %r8, %r10;
1549
1550         cmpl $128, key_bitlength(CTX);
1551         movl $32, %r8d;
1552         movl $24, %r9d;
1553         cmovel %r9d, %r8d; /* max */
1554
1555         /* inpack16_pre: */
1556         vpbroadcastq (key_table)(CTX, %r8, 8), %ymm15;
1557         vpshufb .Lpack_bswap rRIP, %ymm15, %ymm15;
1558         vpxor %ymm0, %ymm15, %ymm0;
1559         vpxor %ymm1, %ymm15, %ymm1;
1560         vpxor %ymm2, %ymm15, %ymm2;
1561         vpxor %ymm3, %ymm15, %ymm3;
1562         vpxor %ymm4, %ymm15, %ymm4;
1563         vpxor %ymm5, %ymm15, %ymm5;
1564         vpxor %ymm6, %ymm15, %ymm6;
1565         vpxor %ymm7, %ymm15, %ymm7;
1566         vpxor %ymm8, %ymm15, %ymm8;
1567         vpxor %ymm9, %ymm15, %ymm9;
1568         vpxor %ymm10, %ymm15, %ymm10;
1569         vpxor %ymm11, %ymm15, %ymm11;
1570         vpxor %ymm12, %ymm15, %ymm12;
1571         vpxor %ymm13, %ymm15, %ymm13;
1572         vpxor 14 * 32(%rax), %ymm15, %ymm14;
1573         vpxor 15 * 32(%rax), %ymm15, %ymm15;
1574
1575         call __camellia_dec_blk32;
1576
1577         vpxor 0 * 32(%rsi), %ymm7, %ymm7;
1578         vpxor 1 * 32(%rsi), %ymm6, %ymm6;
1579         vpxor 2 * 32(%rsi), %ymm5, %ymm5;
1580         vpxor 3 * 32(%rsi), %ymm4, %ymm4;
1581         vpxor 4 * 32(%rsi), %ymm3, %ymm3;
1582         vpxor 5 * 32(%rsi), %ymm2, %ymm2;
1583         vpxor 6 * 32(%rsi), %ymm1, %ymm1;
1584         vpxor 7 * 32(%rsi), %ymm0, %ymm0;
1585         vmovdqu %ymm7, (7 * 32)(%rax);
1586         vmovdqu %ymm6, (6 * 32)(%rax);
1587         vpxor 8 * 32(%rsi), %ymm15, %ymm15;
1588         vpxor 9 * 32(%rsi), %ymm14, %ymm14;
1589         vpxor 10 * 32(%rsi), %ymm13, %ymm13;
1590         vpxor 11 * 32(%rsi), %ymm12, %ymm12;
1591         vpxor 12 * 32(%rsi), %ymm11, %ymm11;
1592         vpxor 13 * 32(%rsi), %ymm10, %ymm10;
1593         vpxor 14 * 32(%rsi), %ymm9, %ymm9;
1594         vpxor 15 * 32(%rsi), %ymm8, %ymm8;
1595
1596         /* Checksum_i = Checksum_{i-1} xor P_i  */
1597
1598         vpxor %ymm5, %ymm7, %ymm7;
1599         vpxor %ymm4, %ymm6, %ymm6;
1600         vpxor %ymm3, %ymm7, %ymm7;
1601         vpxor %ymm2, %ymm6, %ymm6;
1602         vpxor %ymm1, %ymm7, %ymm7;
1603         vpxor %ymm0, %ymm6, %ymm6;
1604         vpxor %ymm15, %ymm7, %ymm7;
1605         vpxor %ymm14, %ymm6, %ymm6;
1606         vpxor %ymm13, %ymm7, %ymm7;
1607         vpxor %ymm12, %ymm6, %ymm6;
1608         vpxor %ymm11, %ymm7, %ymm7;
1609         vpxor %ymm10, %ymm6, %ymm6;
1610         vpxor %ymm9, %ymm7, %ymm7;
1611         vpxor %ymm8, %ymm6, %ymm6;
1612         vpxor %ymm7, %ymm6, %ymm7;
1613
1614         vextracti128 $1, %ymm7, %xmm6;
1615         vpxor %xmm6, %xmm7, %xmm7;
1616         vpxor (%r10), %xmm7, %xmm7;
1617         vmovdqu %xmm7, (%r10);
1618
1619         vmovdqu 7 * 32(%rax), %ymm7;
1620         vmovdqu 6 * 32(%rax), %ymm6;
1621
1622         write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
1623                      %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
1624                      %ymm8, %rsi);
1625
1626         vzeroall;
1627
1628         movq (16 * 32 + 0 * 8)(%rsp), %r10;
1629         movq (16 * 32 + 1 * 8)(%rsp), %r11;
1630         movq (16 * 32 + 2 * 8)(%rsp), %r12;
1631         movq (16 * 32 + 3 * 8)(%rsp), %r13;
1632         CFI_RESTORE(%r10);
1633         CFI_RESTORE(%r11);
1634         CFI_RESTORE(%r12);
1635         CFI_RESTORE(%r13);
1636
1637         leave;
1638         CFI_LEAVE();
1639         ret;
1640         CFI_ENDPROC();
1641 ELF(.size _gcry_camellia_aesni_avx2_ocb_dec,.-_gcry_camellia_aesni_avx2_ocb_dec;)
1642
1643 .align 8
1644 .globl _gcry_camellia_aesni_avx2_ocb_auth
1645 ELF(.type   _gcry_camellia_aesni_avx2_ocb_auth,@function;)
1646
1647 _gcry_camellia_aesni_avx2_ocb_auth:
1648         /* input:
1649          *      %rdi: ctx, CTX
1650          *      %rsi: abuf (16 blocks)
1651          *      %rdx: offset
1652          *      %rcx: checksum
1653          *      %r8 : L pointers (void *L[16])
1654          */
1655         CFI_STARTPROC();
1656
1657         pushq %rbp;
1658         CFI_PUSH(%rbp);
1659         movq %rsp, %rbp;
1660         CFI_DEF_CFA_REGISTER(%rbp);
1661
1662         vzeroupper;
1663
1664         subq $(16 * 32 + 4 * 8), %rsp;
1665         andq $~63, %rsp;
1666         movq %rsp, %rax;
1667
1668         movq %r10, (16 * 32 + 0 * 8)(%rsp);
1669         movq %r11, (16 * 32 + 1 * 8)(%rsp);
1670         movq %r12, (16 * 32 + 2 * 8)(%rsp);
1671         movq %r13, (16 * 32 + 3 * 8)(%rsp);
1672         CFI_REG_ON_STACK(r10, 16 * 32 + 0 * 8);
1673         CFI_REG_ON_STACK(r11, 16 * 32 + 1 * 8);
1674         CFI_REG_ON_STACK(r12, 16 * 32 + 2 * 8);
1675         CFI_REG_ON_STACK(r13, 16 * 32 + 3 * 8);
1676
1677         vmovdqu (%rdx), %xmm14;
1678
1679         /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
1680         /* Checksum_i = Checksum_{i-1} xor P_i  */
1681         /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)  */
1682
1683 #define OCB_INPUT(n, l0reg, l1reg, yreg) \
1684           vmovdqu (n * 32)(%rsi), yreg; \
1685           vpxor (l0reg), %xmm14, %xmm15; \
1686           vpxor (l1reg), %xmm15, %xmm14; \
1687           vinserti128 $1, %xmm14, %ymm15, %ymm15; \
1688           vpxor yreg, %ymm15, yreg;
1689
1690         movq (0 * 8)(%r8), %r10;
1691         movq (1 * 8)(%r8), %r11;
1692         movq (2 * 8)(%r8), %r12;
1693         movq (3 * 8)(%r8), %r13;
1694         OCB_INPUT(0, %r10, %r11, %ymm0);
1695         vmovdqu %ymm0, (15 * 32)(%rax);
1696         OCB_INPUT(1, %r12, %r13, %ymm0);
1697         vmovdqu %ymm0, (14 * 32)(%rax);
1698         movq (4 * 8)(%r8), %r10;
1699         movq (5 * 8)(%r8), %r11;
1700         movq (6 * 8)(%r8), %r12;
1701         movq (7 * 8)(%r8), %r13;
1702         OCB_INPUT(2, %r10, %r11, %ymm13);
1703         OCB_INPUT(3, %r12, %r13, %ymm12);
1704         movq (8 * 8)(%r8), %r10;
1705         movq (9 * 8)(%r8), %r11;
1706         movq (10 * 8)(%r8), %r12;
1707         movq (11 * 8)(%r8), %r13;
1708         OCB_INPUT(4, %r10, %r11, %ymm11);
1709         OCB_INPUT(5, %r12, %r13, %ymm10);
1710         movq (12 * 8)(%r8), %r10;
1711         movq (13 * 8)(%r8), %r11;
1712         movq (14 * 8)(%r8), %r12;
1713         movq (15 * 8)(%r8), %r13;
1714         OCB_INPUT(6, %r10, %r11, %ymm9);
1715         OCB_INPUT(7, %r12, %r13, %ymm8);
1716         movq (16 * 8)(%r8), %r10;
1717         movq (17 * 8)(%r8), %r11;
1718         movq (18 * 8)(%r8), %r12;
1719         movq (19 * 8)(%r8), %r13;
1720         OCB_INPUT(8, %r10, %r11, %ymm7);
1721         OCB_INPUT(9, %r12, %r13, %ymm6);
1722         movq (20 * 8)(%r8), %r10;
1723         movq (21 * 8)(%r8), %r11;
1724         movq (22 * 8)(%r8), %r12;
1725         movq (23 * 8)(%r8), %r13;
1726         OCB_INPUT(10, %r10, %r11, %ymm5);
1727         OCB_INPUT(11, %r12, %r13, %ymm4);
1728         movq (24 * 8)(%r8), %r10;
1729         movq (25 * 8)(%r8), %r11;
1730         movq (26 * 8)(%r8), %r12;
1731         movq (27 * 8)(%r8), %r13;
1732         OCB_INPUT(12, %r10, %r11, %ymm3);
1733         OCB_INPUT(13, %r12, %r13, %ymm2);
1734         movq (28 * 8)(%r8), %r10;
1735         movq (29 * 8)(%r8), %r11;
1736         movq (30 * 8)(%r8), %r12;
1737         movq (31 * 8)(%r8), %r13;
1738         OCB_INPUT(14, %r10, %r11, %ymm1);
1739         OCB_INPUT(15, %r12, %r13, %ymm0);
1740 #undef OCB_INPUT
1741
1742         vmovdqu %xmm14, (%rdx);
1743
1744         movq %rcx, %r10;
1745
1746         /* inpack16_pre: */
1747         vpbroadcastq (key_table)(CTX), %ymm15;
1748         vpshufb .Lpack_bswap rRIP, %ymm15, %ymm15;
1749         vpxor %ymm0, %ymm15, %ymm0;
1750         vpxor %ymm1, %ymm15, %ymm1;
1751         vpxor %ymm2, %ymm15, %ymm2;
1752         vpxor %ymm3, %ymm15, %ymm3;
1753         vpxor %ymm4, %ymm15, %ymm4;
1754         vpxor %ymm5, %ymm15, %ymm5;
1755         vpxor %ymm6, %ymm15, %ymm6;
1756         vpxor %ymm7, %ymm15, %ymm7;
1757         vpxor %ymm8, %ymm15, %ymm8;
1758         vpxor %ymm9, %ymm15, %ymm9;
1759         vpxor %ymm10, %ymm15, %ymm10;
1760         vpxor %ymm11, %ymm15, %ymm11;
1761         vpxor %ymm12, %ymm15, %ymm12;
1762         vpxor %ymm13, %ymm15, %ymm13;
1763         vpxor 14 * 32(%rax), %ymm15, %ymm14;
1764         vpxor 15 * 32(%rax), %ymm15, %ymm15;
1765
1766         call __camellia_enc_blk32;
1767
1768         vpxor %ymm7, %ymm6, %ymm6;
1769         vpxor %ymm5, %ymm4, %ymm4;
1770         vpxor %ymm3, %ymm2, %ymm2;
1771         vpxor %ymm1, %ymm0, %ymm0;
1772         vpxor %ymm15, %ymm14, %ymm14;
1773         vpxor %ymm13, %ymm12, %ymm12;
1774         vpxor %ymm11, %ymm10, %ymm10;
1775         vpxor %ymm9, %ymm8, %ymm8;
1776
1777         vpxor %ymm6, %ymm4, %ymm4;
1778         vpxor %ymm2, %ymm0, %ymm0;
1779         vpxor %ymm14, %ymm12, %ymm12;
1780         vpxor %ymm10, %ymm8, %ymm8;
1781
1782         vpxor %ymm4, %ymm0, %ymm0;
1783         vpxor %ymm12, %ymm8, %ymm8;
1784
1785         vpxor %ymm0, %ymm8, %ymm0;
1786
1787         vextracti128 $1, %ymm0, %xmm1;
1788         vpxor (%r10), %xmm0, %xmm0;
1789         vpxor %xmm0, %xmm1, %xmm0;
1790         vmovdqu %xmm0, (%r10);
1791
1792         vzeroall;
1793
1794         movq (16 * 32 + 0 * 8)(%rsp), %r10;
1795         movq (16 * 32 + 1 * 8)(%rsp), %r11;
1796         movq (16 * 32 + 2 * 8)(%rsp), %r12;
1797         movq (16 * 32 + 3 * 8)(%rsp), %r13;
1798         CFI_RESTORE(%r10);
1799         CFI_RESTORE(%r11);
1800         CFI_RESTORE(%r12);
1801         CFI_RESTORE(%r13);
1802
1803         leave;
1804         CFI_LEAVE();
1805         ret;
1806         CFI_ENDPROC();
1807 ELF(.size _gcry_camellia_aesni_avx2_ocb_auth,.-_gcry_camellia_aesni_avx2_ocb_auth;)
1808
1809 #endif /*defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT)*/
1810 #endif /*__x86_64*/