Add Poly1305 MAC
[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 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(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT)
25
26 #ifdef __PIC__
27 #  define RIP (%rip)
28 #else
29 #  define RIP
30 #endif
31
32 #define CAMELLIA_TABLE_BYTE_LEN 272
33
34 /* struct CAMELLIA_context: */
35 #define key_table 0
36 #define key_bitlength CAMELLIA_TABLE_BYTE_LEN
37
38 /* register macros */
39 #define CTX %rdi
40 #define RIO %r8
41
42 /**********************************************************************
43   helper macros
44  **********************************************************************/
45 #define filter_8bit(x, lo_t, hi_t, mask4bit, tmp0) \
46         vpand x, mask4bit, tmp0; \
47         vpandn x, mask4bit, x; \
48         vpsrld $4, x, x; \
49         \
50         vpshufb tmp0, lo_t, tmp0; \
51         vpshufb x, hi_t, x; \
52         vpxor tmp0, x, x;
53
54 #define ymm0_x xmm0
55 #define ymm1_x xmm1
56 #define ymm2_x xmm2
57 #define ymm3_x xmm3
58 #define ymm4_x xmm4
59 #define ymm5_x xmm5
60 #define ymm6_x xmm6
61 #define ymm7_x xmm7
62 #define ymm8_x xmm8
63 #define ymm9_x xmm9
64 #define ymm10_x xmm10
65 #define ymm11_x xmm11
66 #define ymm12_x xmm12
67 #define ymm13_x xmm13
68 #define ymm14_x xmm14
69 #define ymm15_x xmm15
70
71 /**********************************************************************
72   32-way camellia
73  **********************************************************************/
74
75 /*
76  * IN:
77  *   x0..x7: byte-sliced AB state
78  *   mem_cd: register pointer storing CD state
79  *   key: index for key material
80  * OUT:
81  *   x0..x7: new byte-sliced CD state
82  */
83 #define roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, t0, t1, t2, t3, t4, t5, t6, \
84                   t7, mem_cd, key) \
85         /* \
86          * S-function with AES subbytes \
87          */ \
88         vbroadcasti128 .Linv_shift_row RIP, t4; \
89         vpbroadcastd .L0f0f0f0f RIP, t7; \
90         vbroadcasti128 .Lpre_tf_lo_s1 RIP, t5; \
91         vbroadcasti128 .Lpre_tf_hi_s1 RIP, t6; \
92         vbroadcasti128 .Lpre_tf_lo_s4 RIP, t2; \
93         vbroadcasti128 .Lpre_tf_hi_s4 RIP, t3; \
94         \
95         /* AES inverse shift rows */ \
96         vpshufb t4, x0, x0; \
97         vpshufb t4, x7, x7; \
98         vpshufb t4, x3, x3; \
99         vpshufb t4, x6, x6; \
100         vpshufb t4, x2, x2; \
101         vpshufb t4, x5, x5; \
102         vpshufb t4, x1, x1; \
103         vpshufb t4, x4, x4; \
104         \
105         /* prefilter sboxes 1, 2 and 3 */ \
106         /* prefilter sbox 4 */ \
107         filter_8bit(x0, t5, t6, t7, t4); \
108         filter_8bit(x7, t5, t6, t7, t4); \
109         vextracti128 $1, x0, t0##_x; \
110         vextracti128 $1, x7, t1##_x; \
111         filter_8bit(x3, t2, t3, t7, t4); \
112         filter_8bit(x6, t2, t3, t7, t4); \
113         vextracti128 $1, x3, t3##_x; \
114         vextracti128 $1, x6, t2##_x; \
115         filter_8bit(x2, t5, t6, t7, t4); \
116         filter_8bit(x5, t5, t6, t7, t4); \
117         filter_8bit(x1, t5, t6, t7, t4); \
118         filter_8bit(x4, t5, t6, t7, t4); \
119         \
120         vpxor t4##_x, t4##_x, t4##_x; \
121         \
122         /* AES subbytes + AES shift rows */ \
123         vextracti128 $1, x2, t6##_x; \
124         vextracti128 $1, x5, t5##_x; \
125         vaesenclast t4##_x, x0##_x, x0##_x; \
126         vaesenclast t4##_x, t0##_x, t0##_x; \
127         vaesenclast t4##_x, x7##_x, x7##_x; \
128         vaesenclast t4##_x, t1##_x, t1##_x; \
129         vaesenclast t4##_x, x3##_x, x3##_x; \
130         vaesenclast t4##_x, t3##_x, t3##_x; \
131         vaesenclast t4##_x, x6##_x, x6##_x; \
132         vaesenclast t4##_x, t2##_x, t2##_x; \
133         vinserti128 $1, t0##_x, x0, x0; \
134         vinserti128 $1, t1##_x, x7, x7; \
135         vinserti128 $1, t3##_x, x3, x3; \
136         vinserti128 $1, t2##_x, x6, x6; \
137         vextracti128 $1, x1, t3##_x; \
138         vextracti128 $1, x4, t2##_x; \
139         vbroadcasti128 .Lpost_tf_lo_s1 RIP, t0; \
140         vbroadcasti128 .Lpost_tf_hi_s1 RIP, t1; \
141         vaesenclast t4##_x, x2##_x, x2##_x; \
142         vaesenclast t4##_x, t6##_x, t6##_x; \
143         vaesenclast t4##_x, x5##_x, x5##_x; \
144         vaesenclast t4##_x, t5##_x, t5##_x; \
145         vaesenclast t4##_x, x1##_x, x1##_x; \
146         vaesenclast t4##_x, t3##_x, t3##_x; \
147         vaesenclast t4##_x, x4##_x, x4##_x; \
148         vaesenclast t4##_x, t2##_x, t2##_x; \
149         vinserti128 $1, t6##_x, x2, x2; \
150         vinserti128 $1, t5##_x, x5, x5; \
151         vinserti128 $1, t3##_x, x1, x1; \
152         vinserti128 $1, t2##_x, x4, x4; \
153         \
154         /* postfilter sboxes 1 and 4 */ \
155         vbroadcasti128 .Lpost_tf_lo_s3 RIP, t2; \
156         vbroadcasti128 .Lpost_tf_hi_s3 RIP, t3; \
157         filter_8bit(x0, t0, t1, t7, t4); \
158         filter_8bit(x7, t0, t1, t7, t4); \
159         filter_8bit(x3, t0, t1, t7, t6); \
160         filter_8bit(x6, t0, t1, t7, t6); \
161         \
162         /* postfilter sbox 3 */ \
163         vbroadcasti128 .Lpost_tf_lo_s2 RIP, t4; \
164         vbroadcasti128 .Lpost_tf_hi_s2 RIP, t5; \
165         filter_8bit(x2, t2, t3, t7, t6); \
166         filter_8bit(x5, t2, t3, t7, t6); \
167         \
168         vpbroadcastq key, t0; /* higher 64-bit duplicate ignored */ \
169         \
170         /* postfilter sbox 2 */ \
171         filter_8bit(x1, t4, t5, t7, t2); \
172         filter_8bit(x4, t4, t5, t7, t2); \
173         vpxor t7, t7, t7; \
174         \
175         vpsrldq $1, t0, t1; \
176         vpsrldq $2, t0, t2; \
177         vpshufb t7, t1, t1; \
178         vpsrldq $3, t0, t3; \
179         \
180         /* P-function */ \
181         vpxor x5, x0, x0; \
182         vpxor x6, x1, x1; \
183         vpxor x7, x2, x2; \
184         vpxor x4, x3, x3; \
185         \
186         vpshufb t7, t2, t2; \
187         vpsrldq $4, t0, t4; \
188         vpshufb t7, t3, t3; \
189         vpsrldq $5, t0, t5; \
190         vpshufb t7, t4, t4; \
191         \
192         vpxor x2, x4, x4; \
193         vpxor x3, x5, x5; \
194         vpxor x0, x6, x6; \
195         vpxor x1, x7, x7; \
196         \
197         vpsrldq $6, t0, t6; \
198         vpshufb t7, t5, t5; \
199         vpshufb t7, t6, t6; \
200         \
201         vpxor x7, x0, x0; \
202         vpxor x4, x1, x1; \
203         vpxor x5, x2, x2; \
204         vpxor x6, x3, x3; \
205         \
206         vpxor x3, x4, x4; \
207         vpxor x0, x5, x5; \
208         vpxor x1, x6, x6; \
209         vpxor x2, x7, x7; /* note: high and low parts swapped */ \
210         \
211         /* Add key material and result to CD (x becomes new CD) */ \
212         \
213         vpxor t6, x1, x1; \
214         vpxor 5 * 32(mem_cd), x1, x1; \
215         \
216         vpsrldq $7, t0, t6; \
217         vpshufb t7, t0, t0; \
218         vpshufb t7, t6, t7; \
219         \
220         vpxor t7, x0, x0; \
221         vpxor 4 * 32(mem_cd), x0, x0; \
222         \
223         vpxor t5, x2, x2; \
224         vpxor 6 * 32(mem_cd), x2, x2; \
225         \
226         vpxor t4, x3, x3; \
227         vpxor 7 * 32(mem_cd), x3, x3; \
228         \
229         vpxor t3, x4, x4; \
230         vpxor 0 * 32(mem_cd), x4, x4; \
231         \
232         vpxor t2, x5, x5; \
233         vpxor 1 * 32(mem_cd), x5, x5; \
234         \
235         vpxor t1, x6, x6; \
236         vpxor 2 * 32(mem_cd), x6, x6; \
237         \
238         vpxor t0, x7, x7; \
239         vpxor 3 * 32(mem_cd), x7, x7;
240
241 /*
242  * IN/OUT:
243  *  x0..x7: byte-sliced AB state preloaded
244  *  mem_ab: byte-sliced AB state in memory
245  *  mem_cb: byte-sliced CD state in memory
246  */
247 #define two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
248                       y6, y7, mem_ab, mem_cd, i, dir, store_ab) \
249         roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
250                   y6, y7, mem_cd, (key_table + (i) * 8)(CTX)); \
251         \
252         vmovdqu x0, 4 * 32(mem_cd); \
253         vmovdqu x1, 5 * 32(mem_cd); \
254         vmovdqu x2, 6 * 32(mem_cd); \
255         vmovdqu x3, 7 * 32(mem_cd); \
256         vmovdqu x4, 0 * 32(mem_cd); \
257         vmovdqu x5, 1 * 32(mem_cd); \
258         vmovdqu x6, 2 * 32(mem_cd); \
259         vmovdqu x7, 3 * 32(mem_cd); \
260         \
261         roundsm32(x4, x5, x6, x7, x0, x1, x2, x3, y0, y1, y2, y3, y4, y5, \
262                   y6, y7, mem_ab, (key_table + ((i) + (dir)) * 8)(CTX)); \
263         \
264         store_ab(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab);
265
266 #define dummy_store(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) /* do nothing */
267
268 #define store_ab_state(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) \
269         /* Store new AB state */ \
270         vmovdqu x4, 4 * 32(mem_ab); \
271         vmovdqu x5, 5 * 32(mem_ab); \
272         vmovdqu x6, 6 * 32(mem_ab); \
273         vmovdqu x7, 7 * 32(mem_ab); \
274         vmovdqu x0, 0 * 32(mem_ab); \
275         vmovdqu x1, 1 * 32(mem_ab); \
276         vmovdqu x2, 2 * 32(mem_ab); \
277         vmovdqu x3, 3 * 32(mem_ab);
278
279 #define enc_rounds32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
280                       y6, y7, mem_ab, mem_cd, i) \
281         two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
282                       y6, y7, mem_ab, mem_cd, (i) + 2, 1, store_ab_state); \
283         two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
284                       y6, y7, mem_ab, mem_cd, (i) + 4, 1, store_ab_state); \
285         two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
286                       y6, y7, mem_ab, mem_cd, (i) + 6, 1, dummy_store);
287
288 #define dec_rounds32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
289                       y6, y7, mem_ab, mem_cd, i) \
290         two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
291                       y6, y7, mem_ab, mem_cd, (i) + 7, -1, store_ab_state); \
292         two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
293                       y6, y7, mem_ab, mem_cd, (i) + 5, -1, store_ab_state); \
294         two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
295                       y6, y7, mem_ab, mem_cd, (i) + 3, -1, dummy_store);
296
297 /*
298  * IN:
299  *  v0..3: byte-sliced 32-bit integers
300  * OUT:
301  *  v0..3: (IN <<< 1)
302  */
303 #define rol32_1_32(v0, v1, v2, v3, t0, t1, t2, zero) \
304         vpcmpgtb v0, zero, t0; \
305         vpaddb v0, v0, v0; \
306         vpabsb t0, t0; \
307         \
308         vpcmpgtb v1, zero, t1; \
309         vpaddb v1, v1, v1; \
310         vpabsb t1, t1; \
311         \
312         vpcmpgtb v2, zero, t2; \
313         vpaddb v2, v2, v2; \
314         vpabsb t2, t2; \
315         \
316         vpor t0, v1, v1; \
317         \
318         vpcmpgtb v3, zero, t0; \
319         vpaddb v3, v3, v3; \
320         vpabsb t0, t0; \
321         \
322         vpor t1, v2, v2; \
323         vpor t2, v3, v3; \
324         vpor t0, v0, v0;
325
326 /*
327  * IN:
328  *   r: byte-sliced AB state in memory
329  *   l: byte-sliced CD state in memory
330  * OUT:
331  *   x0..x7: new byte-sliced CD state
332  */
333 #define fls32(l, l0, l1, l2, l3, l4, l5, l6, l7, r, t0, t1, t2, t3, tt0, \
334               tt1, tt2, tt3, kll, klr, krl, krr) \
335         /* \
336          * t0 = kll; \
337          * t0 &= ll; \
338          * lr ^= rol32(t0, 1); \
339          */ \
340         vpbroadcastd kll, t0; /* only lowest 32-bit used */ \
341         vpxor tt0, tt0, tt0; \
342         vpshufb tt0, t0, t3; \
343         vpsrldq $1, t0, t0; \
344         vpshufb tt0, t0, t2; \
345         vpsrldq $1, t0, t0; \
346         vpshufb tt0, t0, t1; \
347         vpsrldq $1, t0, t0; \
348         vpshufb tt0, t0, t0; \
349         \
350         vpand l0, t0, t0; \
351         vpand l1, t1, t1; \
352         vpand l2, t2, t2; \
353         vpand l3, t3, t3; \
354         \
355         rol32_1_32(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
356         \
357         vpxor l4, t0, l4; \
358         vpbroadcastd krr, t0; /* only lowest 32-bit used */ \
359         vmovdqu l4, 4 * 32(l); \
360         vpxor l5, t1, l5; \
361         vmovdqu l5, 5 * 32(l); \
362         vpxor l6, t2, l6; \
363         vmovdqu l6, 6 * 32(l); \
364         vpxor l7, t3, l7; \
365         vmovdqu l7, 7 * 32(l); \
366         \
367         /* \
368          * t2 = krr; \
369          * t2 |= rr; \
370          * rl ^= t2; \
371          */ \
372         \
373         vpshufb tt0, t0, t3; \
374         vpsrldq $1, t0, t0; \
375         vpshufb tt0, t0, t2; \
376         vpsrldq $1, t0, t0; \
377         vpshufb tt0, t0, t1; \
378         vpsrldq $1, t0, t0; \
379         vpshufb tt0, t0, t0; \
380         \
381         vpor 4 * 32(r), t0, t0; \
382         vpor 5 * 32(r), t1, t1; \
383         vpor 6 * 32(r), t2, t2; \
384         vpor 7 * 32(r), t3, t3; \
385         \
386         vpxor 0 * 32(r), t0, t0; \
387         vpxor 1 * 32(r), t1, t1; \
388         vpxor 2 * 32(r), t2, t2; \
389         vpxor 3 * 32(r), t3, t3; \
390         vmovdqu t0, 0 * 32(r); \
391         vpbroadcastd krl, t0; /* only lowest 32-bit used */ \
392         vmovdqu t1, 1 * 32(r); \
393         vmovdqu t2, 2 * 32(r); \
394         vmovdqu t3, 3 * 32(r); \
395         \
396         /* \
397          * t2 = krl; \
398          * t2 &= rl; \
399          * rr ^= rol32(t2, 1); \
400          */ \
401         vpshufb tt0, t0, t3; \
402         vpsrldq $1, t0, t0; \
403         vpshufb tt0, t0, t2; \
404         vpsrldq $1, t0, t0; \
405         vpshufb tt0, t0, t1; \
406         vpsrldq $1, t0, t0; \
407         vpshufb tt0, t0, t0; \
408         \
409         vpand 0 * 32(r), t0, t0; \
410         vpand 1 * 32(r), t1, t1; \
411         vpand 2 * 32(r), t2, t2; \
412         vpand 3 * 32(r), t3, t3; \
413         \
414         rol32_1_32(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
415         \
416         vpxor 4 * 32(r), t0, t0; \
417         vpxor 5 * 32(r), t1, t1; \
418         vpxor 6 * 32(r), t2, t2; \
419         vpxor 7 * 32(r), t3, t3; \
420         vmovdqu t0, 4 * 32(r); \
421         vpbroadcastd klr, t0; /* only lowest 32-bit used */ \
422         vmovdqu t1, 5 * 32(r); \
423         vmovdqu t2, 6 * 32(r); \
424         vmovdqu t3, 7 * 32(r); \
425         \
426         /* \
427          * t0 = klr; \
428          * t0 |= lr; \
429          * ll ^= t0; \
430          */ \
431         \
432         vpshufb tt0, t0, t3; \
433         vpsrldq $1, t0, t0; \
434         vpshufb tt0, t0, t2; \
435         vpsrldq $1, t0, t0; \
436         vpshufb tt0, t0, t1; \
437         vpsrldq $1, t0, t0; \
438         vpshufb tt0, t0, t0; \
439         \
440         vpor l4, t0, t0; \
441         vpor l5, t1, t1; \
442         vpor l6, t2, t2; \
443         vpor l7, t3, t3; \
444         \
445         vpxor l0, t0, l0; \
446         vmovdqu l0, 0 * 32(l); \
447         vpxor l1, t1, l1; \
448         vmovdqu l1, 1 * 32(l); \
449         vpxor l2, t2, l2; \
450         vmovdqu l2, 2 * 32(l); \
451         vpxor l3, t3, l3; \
452         vmovdqu l3, 3 * 32(l);
453
454 #define transpose_4x4(x0, x1, x2, x3, t1, t2) \
455         vpunpckhdq x1, x0, t2; \
456         vpunpckldq x1, x0, x0; \
457         \
458         vpunpckldq x3, x2, t1; \
459         vpunpckhdq x3, x2, x2; \
460         \
461         vpunpckhqdq t1, x0, x1; \
462         vpunpcklqdq t1, x0, x0; \
463         \
464         vpunpckhqdq x2, t2, x3; \
465         vpunpcklqdq x2, t2, x2;
466
467 #define byteslice_16x16b_fast(a0, b0, c0, d0, a1, b1, c1, d1, a2, b2, c2, d2, \
468                               a3, b3, c3, d3, st0, st1) \
469         vmovdqu d2, st0; \
470         vmovdqu d3, st1; \
471         transpose_4x4(a0, a1, a2, a3, d2, d3); \
472         transpose_4x4(b0, b1, b2, b3, d2, d3); \
473         vmovdqu st0, d2; \
474         vmovdqu st1, d3; \
475         \
476         vmovdqu a0, st0; \
477         vmovdqu a1, st1; \
478         transpose_4x4(c0, c1, c2, c3, a0, a1); \
479         transpose_4x4(d0, d1, d2, d3, a0, a1); \
480         \
481         vbroadcasti128 .Lshufb_16x16b RIP, a0; \
482         vmovdqu st1, a1; \
483         vpshufb a0, a2, a2; \
484         vpshufb a0, a3, a3; \
485         vpshufb a0, b0, b0; \
486         vpshufb a0, b1, b1; \
487         vpshufb a0, b2, b2; \
488         vpshufb a0, b3, b3; \
489         vpshufb a0, a1, a1; \
490         vpshufb a0, c0, c0; \
491         vpshufb a0, c1, c1; \
492         vpshufb a0, c2, c2; \
493         vpshufb a0, c3, c3; \
494         vpshufb a0, d0, d0; \
495         vpshufb a0, d1, d1; \
496         vpshufb a0, d2, d2; \
497         vpshufb a0, d3, d3; \
498         vmovdqu d3, st1; \
499         vmovdqu st0, d3; \
500         vpshufb a0, d3, a0; \
501         vmovdqu d2, st0; \
502         \
503         transpose_4x4(a0, b0, c0, d0, d2, d3); \
504         transpose_4x4(a1, b1, c1, d1, d2, d3); \
505         vmovdqu st0, d2; \
506         vmovdqu st1, d3; \
507         \
508         vmovdqu b0, st0; \
509         vmovdqu b1, st1; \
510         transpose_4x4(a2, b2, c2, d2, b0, b1); \
511         transpose_4x4(a3, b3, c3, d3, b0, b1); \
512         vmovdqu st0, b0; \
513         vmovdqu st1, b1; \
514         /* does not adjust output bytes inside vectors */
515
516 /* load blocks to registers and apply pre-whitening */
517 #define inpack32_pre(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
518                      y6, y7, rio, key) \
519         vpbroadcastq key, x0; \
520         vpshufb .Lpack_bswap RIP, x0, x0; \
521         \
522         vpxor 0 * 32(rio), x0, y7; \
523         vpxor 1 * 32(rio), x0, y6; \
524         vpxor 2 * 32(rio), x0, y5; \
525         vpxor 3 * 32(rio), x0, y4; \
526         vpxor 4 * 32(rio), x0, y3; \
527         vpxor 5 * 32(rio), x0, y2; \
528         vpxor 6 * 32(rio), x0, y1; \
529         vpxor 7 * 32(rio), x0, y0; \
530         vpxor 8 * 32(rio), x0, x7; \
531         vpxor 9 * 32(rio), x0, x6; \
532         vpxor 10 * 32(rio), x0, x5; \
533         vpxor 11 * 32(rio), x0, x4; \
534         vpxor 12 * 32(rio), x0, x3; \
535         vpxor 13 * 32(rio), x0, x2; \
536         vpxor 14 * 32(rio), x0, x1; \
537         vpxor 15 * 32(rio), x0, x0;
538
539 /* byteslice pre-whitened blocks and store to temporary memory */
540 #define inpack32_post(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
541                       y6, y7, mem_ab, mem_cd) \
542         byteslice_16x16b_fast(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, \
543                               y4, y5, y6, y7, (mem_ab), (mem_cd)); \
544         \
545         vmovdqu x0, 0 * 32(mem_ab); \
546         vmovdqu x1, 1 * 32(mem_ab); \
547         vmovdqu x2, 2 * 32(mem_ab); \
548         vmovdqu x3, 3 * 32(mem_ab); \
549         vmovdqu x4, 4 * 32(mem_ab); \
550         vmovdqu x5, 5 * 32(mem_ab); \
551         vmovdqu x6, 6 * 32(mem_ab); \
552         vmovdqu x7, 7 * 32(mem_ab); \
553         vmovdqu y0, 0 * 32(mem_cd); \
554         vmovdqu y1, 1 * 32(mem_cd); \
555         vmovdqu y2, 2 * 32(mem_cd); \
556         vmovdqu y3, 3 * 32(mem_cd); \
557         vmovdqu y4, 4 * 32(mem_cd); \
558         vmovdqu y5, 5 * 32(mem_cd); \
559         vmovdqu y6, 6 * 32(mem_cd); \
560         vmovdqu y7, 7 * 32(mem_cd);
561
562 /* de-byteslice, apply post-whitening and store blocks */
563 #define outunpack32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, \
564                     y5, y6, y7, key, stack_tmp0, stack_tmp1) \
565         byteslice_16x16b_fast(y0, y4, x0, x4, y1, y5, x1, x5, y2, y6, x2, x6, \
566                               y3, y7, x3, x7, stack_tmp0, stack_tmp1); \
567         \
568         vmovdqu x0, stack_tmp0; \
569         \
570         vpbroadcastq key, x0; \
571         vpshufb .Lpack_bswap RIP, x0, x0; \
572         \
573         vpxor x0, y7, y7; \
574         vpxor x0, y6, y6; \
575         vpxor x0, y5, y5; \
576         vpxor x0, y4, y4; \
577         vpxor x0, y3, y3; \
578         vpxor x0, y2, y2; \
579         vpxor x0, y1, y1; \
580         vpxor x0, y0, y0; \
581         vpxor x0, x7, x7; \
582         vpxor x0, x6, x6; \
583         vpxor x0, x5, x5; \
584         vpxor x0, x4, x4; \
585         vpxor x0, x3, x3; \
586         vpxor x0, x2, x2; \
587         vpxor x0, x1, x1; \
588         vpxor stack_tmp0, x0, x0;
589
590 #define write_output(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
591                      y6, y7, rio) \
592         vmovdqu x0, 0 * 32(rio); \
593         vmovdqu x1, 1 * 32(rio); \
594         vmovdqu x2, 2 * 32(rio); \
595         vmovdqu x3, 3 * 32(rio); \
596         vmovdqu x4, 4 * 32(rio); \
597         vmovdqu x5, 5 * 32(rio); \
598         vmovdqu x6, 6 * 32(rio); \
599         vmovdqu x7, 7 * 32(rio); \
600         vmovdqu y0, 8 * 32(rio); \
601         vmovdqu y1, 9 * 32(rio); \
602         vmovdqu y2, 10 * 32(rio); \
603         vmovdqu y3, 11 * 32(rio); \
604         vmovdqu y4, 12 * 32(rio); \
605         vmovdqu y5, 13 * 32(rio); \
606         vmovdqu y6, 14 * 32(rio); \
607         vmovdqu y7, 15 * 32(rio);
608
609 .data
610 .align 32
611
612 #define SHUFB_BYTES(idx) \
613         0 + (idx), 4 + (idx), 8 + (idx), 12 + (idx)
614
615 .Lshufb_16x16b:
616         .byte SHUFB_BYTES(0), SHUFB_BYTES(1), SHUFB_BYTES(2), SHUFB_BYTES(3)
617         .byte SHUFB_BYTES(0), SHUFB_BYTES(1), SHUFB_BYTES(2), SHUFB_BYTES(3)
618
619 .Lpack_bswap:
620         .long 0x00010203, 0x04050607, 0x80808080, 0x80808080
621         .long 0x00010203, 0x04050607, 0x80808080, 0x80808080
622
623 /* For CTR-mode IV byteswap */
624 .Lbswap128_mask:
625         .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
626
627 /*
628  * pre-SubByte transform
629  *
630  * pre-lookup for sbox1, sbox2, sbox3:
631  *   swap_bitendianness(
632  *       isom_map_camellia_to_aes(
633  *           camellia_f(
634  *               swap_bitendianess(in)
635  *           )
636  *       )
637  *   )
638  *
639  * (note: '⊕ 0xc5' inside camellia_f())
640  */
641 .Lpre_tf_lo_s1:
642         .byte 0x45, 0xe8, 0x40, 0xed, 0x2e, 0x83, 0x2b, 0x86
643         .byte 0x4b, 0xe6, 0x4e, 0xe3, 0x20, 0x8d, 0x25, 0x88
644 .Lpre_tf_hi_s1:
645         .byte 0x00, 0x51, 0xf1, 0xa0, 0x8a, 0xdb, 0x7b, 0x2a
646         .byte 0x09, 0x58, 0xf8, 0xa9, 0x83, 0xd2, 0x72, 0x23
647
648 /*
649  * pre-SubByte transform
650  *
651  * pre-lookup for sbox4:
652  *   swap_bitendianness(
653  *       isom_map_camellia_to_aes(
654  *           camellia_f(
655  *               swap_bitendianess(in <<< 1)
656  *           )
657  *       )
658  *   )
659  *
660  * (note: '⊕ 0xc5' inside camellia_f())
661  */
662 .Lpre_tf_lo_s4:
663         .byte 0x45, 0x40, 0x2e, 0x2b, 0x4b, 0x4e, 0x20, 0x25
664         .byte 0x14, 0x11, 0x7f, 0x7a, 0x1a, 0x1f, 0x71, 0x74
665 .Lpre_tf_hi_s4:
666         .byte 0x00, 0xf1, 0x8a, 0x7b, 0x09, 0xf8, 0x83, 0x72
667         .byte 0xad, 0x5c, 0x27, 0xd6, 0xa4, 0x55, 0x2e, 0xdf
668
669 /*
670  * post-SubByte transform
671  *
672  * post-lookup for sbox1, sbox4:
673  *  swap_bitendianness(
674  *      camellia_h(
675  *          isom_map_aes_to_camellia(
676  *              swap_bitendianness(
677  *                  aes_inverse_affine_transform(in)
678  *              )
679  *          )
680  *      )
681  *  )
682  *
683  * (note: '⊕ 0x6e' inside camellia_h())
684  */
685 .Lpost_tf_lo_s1:
686         .byte 0x3c, 0xcc, 0xcf, 0x3f, 0x32, 0xc2, 0xc1, 0x31
687         .byte 0xdc, 0x2c, 0x2f, 0xdf, 0xd2, 0x22, 0x21, 0xd1
688 .Lpost_tf_hi_s1:
689         .byte 0x00, 0xf9, 0x86, 0x7f, 0xd7, 0x2e, 0x51, 0xa8
690         .byte 0xa4, 0x5d, 0x22, 0xdb, 0x73, 0x8a, 0xf5, 0x0c
691
692 /*
693  * post-SubByte transform
694  *
695  * post-lookup for sbox2:
696  *  swap_bitendianness(
697  *      camellia_h(
698  *          isom_map_aes_to_camellia(
699  *              swap_bitendianness(
700  *                  aes_inverse_affine_transform(in)
701  *              )
702  *          )
703  *      )
704  *  ) <<< 1
705  *
706  * (note: '⊕ 0x6e' inside camellia_h())
707  */
708 .Lpost_tf_lo_s2:
709         .byte 0x78, 0x99, 0x9f, 0x7e, 0x64, 0x85, 0x83, 0x62
710         .byte 0xb9, 0x58, 0x5e, 0xbf, 0xa5, 0x44, 0x42, 0xa3
711 .Lpost_tf_hi_s2:
712         .byte 0x00, 0xf3, 0x0d, 0xfe, 0xaf, 0x5c, 0xa2, 0x51
713         .byte 0x49, 0xba, 0x44, 0xb7, 0xe6, 0x15, 0xeb, 0x18
714
715 /*
716  * post-SubByte transform
717  *
718  * post-lookup for sbox3:
719  *  swap_bitendianness(
720  *      camellia_h(
721  *          isom_map_aes_to_camellia(
722  *              swap_bitendianness(
723  *                  aes_inverse_affine_transform(in)
724  *              )
725  *          )
726  *      )
727  *  ) >>> 1
728  *
729  * (note: '⊕ 0x6e' inside camellia_h())
730  */
731 .Lpost_tf_lo_s3:
732         .byte 0x1e, 0x66, 0xe7, 0x9f, 0x19, 0x61, 0xe0, 0x98
733         .byte 0x6e, 0x16, 0x97, 0xef, 0x69, 0x11, 0x90, 0xe8
734 .Lpost_tf_hi_s3:
735         .byte 0x00, 0xfc, 0x43, 0xbf, 0xeb, 0x17, 0xa8, 0x54
736         .byte 0x52, 0xae, 0x11, 0xed, 0xb9, 0x45, 0xfa, 0x06
737
738 /* For isolating SubBytes from AESENCLAST, inverse shift row */
739 .Linv_shift_row:
740         .byte 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b
741         .byte 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03
742
743 .align 4
744 /* 4-bit mask */
745 .L0f0f0f0f:
746         .long 0x0f0f0f0f
747
748 .text
749
750 .align 8
751 .type   __camellia_enc_blk32,@function;
752
753 __camellia_enc_blk32:
754         /* input:
755          *      %rdi: ctx, CTX
756          *      %rax: temporary storage, 512 bytes
757          *      %ymm0..%ymm15: 32 plaintext blocks
758          * output:
759          *      %ymm0..%ymm15: 32 encrypted blocks, order swapped:
760          *       7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
761          */
762
763         leaq 8 * 32(%rax), %rcx;
764
765         inpack32_post(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
766                       %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
767                       %ymm15, %rax, %rcx);
768
769         enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
770                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
771                      %ymm15, %rax, %rcx, 0);
772
773         fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
774               %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
775               %ymm15,
776               ((key_table + (8) * 8) + 0)(CTX),
777               ((key_table + (8) * 8) + 4)(CTX),
778               ((key_table + (8) * 8) + 8)(CTX),
779               ((key_table + (8) * 8) + 12)(CTX));
780
781         enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
782                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
783                      %ymm15, %rax, %rcx, 8);
784
785         fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
786               %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
787               %ymm15,
788               ((key_table + (16) * 8) + 0)(CTX),
789               ((key_table + (16) * 8) + 4)(CTX),
790               ((key_table + (16) * 8) + 8)(CTX),
791               ((key_table + (16) * 8) + 12)(CTX));
792
793         enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
794                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
795                      %ymm15, %rax, %rcx, 16);
796
797         movl $24, %r8d;
798         cmpl $128, key_bitlength(CTX);
799         jne .Lenc_max32;
800
801 .Lenc_done:
802         /* load CD for output */
803         vmovdqu 0 * 32(%rcx), %ymm8;
804         vmovdqu 1 * 32(%rcx), %ymm9;
805         vmovdqu 2 * 32(%rcx), %ymm10;
806         vmovdqu 3 * 32(%rcx), %ymm11;
807         vmovdqu 4 * 32(%rcx), %ymm12;
808         vmovdqu 5 * 32(%rcx), %ymm13;
809         vmovdqu 6 * 32(%rcx), %ymm14;
810         vmovdqu 7 * 32(%rcx), %ymm15;
811
812         outunpack32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
813                     %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
814                     %ymm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 32(%rax));
815
816         ret;
817
818 .align 8
819 .Lenc_max32:
820         movl $32, %r8d;
821
822         fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
823               %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
824               %ymm15,
825               ((key_table + (24) * 8) + 0)(CTX),
826               ((key_table + (24) * 8) + 4)(CTX),
827               ((key_table + (24) * 8) + 8)(CTX),
828               ((key_table + (24) * 8) + 12)(CTX));
829
830         enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
831                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
832                      %ymm15, %rax, %rcx, 24);
833
834         jmp .Lenc_done;
835 .size __camellia_enc_blk32,.-__camellia_enc_blk32;
836
837 .align 8
838 .type   __camellia_dec_blk32,@function;
839
840 __camellia_dec_blk32:
841         /* input:
842          *      %rdi: ctx, CTX
843          *      %rax: temporary storage, 512 bytes
844          *      %r8d: 24 for 16 byte key, 32 for larger
845          *      %ymm0..%ymm15: 16 encrypted blocks
846          * output:
847          *      %ymm0..%ymm15: 16 plaintext blocks, order swapped:
848          *       7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
849          */
850
851         leaq 8 * 32(%rax), %rcx;
852
853         inpack32_post(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
854                       %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
855                       %ymm15, %rax, %rcx);
856
857         cmpl $32, %r8d;
858         je .Ldec_max32;
859
860 .Ldec_max24:
861         dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
862                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
863                      %ymm15, %rax, %rcx, 16);
864
865         fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
866               %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
867               %ymm15,
868               ((key_table + (16) * 8) + 8)(CTX),
869               ((key_table + (16) * 8) + 12)(CTX),
870               ((key_table + (16) * 8) + 0)(CTX),
871               ((key_table + (16) * 8) + 4)(CTX));
872
873         dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
874                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
875                      %ymm15, %rax, %rcx, 8);
876
877         fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
878               %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
879               %ymm15,
880               ((key_table + (8) * 8) + 8)(CTX),
881               ((key_table + (8) * 8) + 12)(CTX),
882               ((key_table + (8) * 8) + 0)(CTX),
883               ((key_table + (8) * 8) + 4)(CTX));
884
885         dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
886                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
887                      %ymm15, %rax, %rcx, 0);
888
889         /* load CD for output */
890         vmovdqu 0 * 32(%rcx), %ymm8;
891         vmovdqu 1 * 32(%rcx), %ymm9;
892         vmovdqu 2 * 32(%rcx), %ymm10;
893         vmovdqu 3 * 32(%rcx), %ymm11;
894         vmovdqu 4 * 32(%rcx), %ymm12;
895         vmovdqu 5 * 32(%rcx), %ymm13;
896         vmovdqu 6 * 32(%rcx), %ymm14;
897         vmovdqu 7 * 32(%rcx), %ymm15;
898
899         outunpack32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
900                     %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
901                     %ymm15, (key_table)(CTX), (%rax), 1 * 32(%rax));
902
903         ret;
904
905 .align 8
906 .Ldec_max32:
907         dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
908                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
909                      %ymm15, %rax, %rcx, 24);
910
911         fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
912               %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
913               %ymm15,
914               ((key_table + (24) * 8) + 8)(CTX),
915               ((key_table + (24) * 8) + 12)(CTX),
916               ((key_table + (24) * 8) + 0)(CTX),
917               ((key_table + (24) * 8) + 4)(CTX));
918
919         jmp .Ldec_max24;
920 .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 .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
940         pushq %rbp;
941         movq %rsp, %rbp;
942
943         movq 8(%rcx), %r11;
944         bswapq %r11;
945
946         vzeroupper;
947
948         subq $(16 * 32), %rsp;
949         andq $~63, %rsp;
950         movq %rsp, %rax;
951
952         vpcmpeqd %ymm15, %ymm15, %ymm15;
953         vpsrldq $8, %ymm15, %ymm15; /* ab: -1:0 ; cd: -1:0 */
954
955         /* load IV and byteswap */
956         vmovdqu (%rcx), %xmm0;
957         vpshufb .Lbswap128_mask RIP, %xmm0, %xmm0;
958         vmovdqa %xmm0, %xmm1;
959         inc_le128(%xmm0, %xmm15, %xmm14);
960         vbroadcasti128 .Lbswap128_mask RIP, %ymm14;
961         vinserti128 $1, %xmm0, %ymm1, %ymm0;
962         vpshufb %ymm14, %ymm0, %ymm13;
963         vmovdqu %ymm13, 15 * 32(%rax);
964
965         /* check need for handling 64-bit overflow and carry */
966         cmpq $(0xffffffffffffffff - 32), %r11;
967         ja .Lload_ctr_carry;
968
969         /* construct IVs */
970         vpaddq %ymm15, %ymm15, %ymm15; /* ab: -2:0 ; cd: -2:0 */
971         vpsubq %ymm15, %ymm0, %ymm0;
972         vpshufb %ymm14, %ymm0, %ymm13;
973         vmovdqu %ymm13, 14 * 32(%rax);
974         vpsubq %ymm15, %ymm0, %ymm0;
975         vpshufb %ymm14, %ymm0, %ymm13;
976         vmovdqu %ymm13, 13 * 32(%rax);
977         vpsubq %ymm15, %ymm0, %ymm0;
978         vpshufb %ymm14, %ymm0, %ymm12;
979         vpsubq %ymm15, %ymm0, %ymm0;
980         vpshufb %ymm14, %ymm0, %ymm11;
981         vpsubq %ymm15, %ymm0, %ymm0;
982         vpshufb %ymm14, %ymm0, %ymm10;
983         vpsubq %ymm15, %ymm0, %ymm0;
984         vpshufb %ymm14, %ymm0, %ymm9;
985         vpsubq %ymm15, %ymm0, %ymm0;
986         vpshufb %ymm14, %ymm0, %ymm8;
987         vpsubq %ymm15, %ymm0, %ymm0;
988         vpshufb %ymm14, %ymm0, %ymm7;
989         vpsubq %ymm15, %ymm0, %ymm0;
990         vpshufb %ymm14, %ymm0, %ymm6;
991         vpsubq %ymm15, %ymm0, %ymm0;
992         vpshufb %ymm14, %ymm0, %ymm5;
993         vpsubq %ymm15, %ymm0, %ymm0;
994         vpshufb %ymm14, %ymm0, %ymm4;
995         vpsubq %ymm15, %ymm0, %ymm0;
996         vpshufb %ymm14, %ymm0, %ymm3;
997         vpsubq %ymm15, %ymm0, %ymm0;
998         vpshufb %ymm14, %ymm0, %ymm2;
999         vpsubq %ymm15, %ymm0, %ymm0;
1000         vpshufb %ymm14, %ymm0, %ymm1;
1001         vpsubq %ymm15, %ymm0, %ymm0;  /* +30 ; +31 */
1002         vpsubq %xmm15, %xmm0, %xmm13; /* +32 */
1003         vpshufb %ymm14, %ymm0, %ymm0;
1004         vpshufb %xmm14, %xmm13, %xmm13;
1005         vmovdqu %xmm13, (%rcx);
1006
1007         jmp .Lload_ctr_done;
1008
1009 .align 4
1010 .Lload_ctr_carry:
1011         /* construct IVs */
1012         inc_le128(%ymm0, %ymm15, %ymm13); /* ab: le1 ; cd: le2 */
1013         inc_le128(%ymm0, %ymm15, %ymm13); /* ab: le2 ; cd: le3 */
1014         vpshufb %ymm14, %ymm0, %ymm13;
1015         vmovdqu %ymm13, 14 * 32(%rax);
1016         inc_le128(%ymm0, %ymm15, %ymm13);
1017         inc_le128(%ymm0, %ymm15, %ymm13);
1018         vpshufb %ymm14, %ymm0, %ymm13;
1019         vmovdqu %ymm13, 13 * 32(%rax);
1020         inc_le128(%ymm0, %ymm15, %ymm13);
1021         inc_le128(%ymm0, %ymm15, %ymm13);
1022         vpshufb %ymm14, %ymm0, %ymm12;
1023         inc_le128(%ymm0, %ymm15, %ymm13);
1024         inc_le128(%ymm0, %ymm15, %ymm13);
1025         vpshufb %ymm14, %ymm0, %ymm11;
1026         inc_le128(%ymm0, %ymm15, %ymm13);
1027         inc_le128(%ymm0, %ymm15, %ymm13);
1028         vpshufb %ymm14, %ymm0, %ymm10;
1029         inc_le128(%ymm0, %ymm15, %ymm13);
1030         inc_le128(%ymm0, %ymm15, %ymm13);
1031         vpshufb %ymm14, %ymm0, %ymm9;
1032         inc_le128(%ymm0, %ymm15, %ymm13);
1033         inc_le128(%ymm0, %ymm15, %ymm13);
1034         vpshufb %ymm14, %ymm0, %ymm8;
1035         inc_le128(%ymm0, %ymm15, %ymm13);
1036         inc_le128(%ymm0, %ymm15, %ymm13);
1037         vpshufb %ymm14, %ymm0, %ymm7;
1038         inc_le128(%ymm0, %ymm15, %ymm13);
1039         inc_le128(%ymm0, %ymm15, %ymm13);
1040         vpshufb %ymm14, %ymm0, %ymm6;
1041         inc_le128(%ymm0, %ymm15, %ymm13);
1042         inc_le128(%ymm0, %ymm15, %ymm13);
1043         vpshufb %ymm14, %ymm0, %ymm5;
1044         inc_le128(%ymm0, %ymm15, %ymm13);
1045         inc_le128(%ymm0, %ymm15, %ymm13);
1046         vpshufb %ymm14, %ymm0, %ymm4;
1047         inc_le128(%ymm0, %ymm15, %ymm13);
1048         inc_le128(%ymm0, %ymm15, %ymm13);
1049         vpshufb %ymm14, %ymm0, %ymm3;
1050         inc_le128(%ymm0, %ymm15, %ymm13);
1051         inc_le128(%ymm0, %ymm15, %ymm13);
1052         vpshufb %ymm14, %ymm0, %ymm2;
1053         inc_le128(%ymm0, %ymm15, %ymm13);
1054         inc_le128(%ymm0, %ymm15, %ymm13);
1055         vpshufb %ymm14, %ymm0, %ymm1;
1056         inc_le128(%ymm0, %ymm15, %ymm13);
1057         inc_le128(%ymm0, %ymm15, %ymm13);
1058         vextracti128 $1, %ymm0, %xmm13;
1059         vpshufb %ymm14, %ymm0, %ymm0;
1060         inc_le128(%xmm13, %xmm15, %xmm14);
1061         vpshufb .Lbswap128_mask RIP, %xmm13, %xmm13;
1062         vmovdqu %xmm13, (%rcx);
1063
1064 .align 4
1065 .Lload_ctr_done:
1066         /* inpack16_pre: */
1067         vpbroadcastq (key_table)(CTX), %ymm15;
1068         vpshufb .Lpack_bswap RIP, %ymm15, %ymm15;
1069         vpxor %ymm0, %ymm15, %ymm0;
1070         vpxor %ymm1, %ymm15, %ymm1;
1071         vpxor %ymm2, %ymm15, %ymm2;
1072         vpxor %ymm3, %ymm15, %ymm3;
1073         vpxor %ymm4, %ymm15, %ymm4;
1074         vpxor %ymm5, %ymm15, %ymm5;
1075         vpxor %ymm6, %ymm15, %ymm6;
1076         vpxor %ymm7, %ymm15, %ymm7;
1077         vpxor %ymm8, %ymm15, %ymm8;
1078         vpxor %ymm9, %ymm15, %ymm9;
1079         vpxor %ymm10, %ymm15, %ymm10;
1080         vpxor %ymm11, %ymm15, %ymm11;
1081         vpxor %ymm12, %ymm15, %ymm12;
1082         vpxor 13 * 32(%rax), %ymm15, %ymm13;
1083         vpxor 14 * 32(%rax), %ymm15, %ymm14;
1084         vpxor 15 * 32(%rax), %ymm15, %ymm15;
1085
1086         call __camellia_enc_blk32;
1087
1088         vpxor 0 * 32(%rdx), %ymm7, %ymm7;
1089         vpxor 1 * 32(%rdx), %ymm6, %ymm6;
1090         vpxor 2 * 32(%rdx), %ymm5, %ymm5;
1091         vpxor 3 * 32(%rdx), %ymm4, %ymm4;
1092         vpxor 4 * 32(%rdx), %ymm3, %ymm3;
1093         vpxor 5 * 32(%rdx), %ymm2, %ymm2;
1094         vpxor 6 * 32(%rdx), %ymm1, %ymm1;
1095         vpxor 7 * 32(%rdx), %ymm0, %ymm0;
1096         vpxor 8 * 32(%rdx), %ymm15, %ymm15;
1097         vpxor 9 * 32(%rdx), %ymm14, %ymm14;
1098         vpxor 10 * 32(%rdx), %ymm13, %ymm13;
1099         vpxor 11 * 32(%rdx), %ymm12, %ymm12;
1100         vpxor 12 * 32(%rdx), %ymm11, %ymm11;
1101         vpxor 13 * 32(%rdx), %ymm10, %ymm10;
1102         vpxor 14 * 32(%rdx), %ymm9, %ymm9;
1103         vpxor 15 * 32(%rdx), %ymm8, %ymm8;
1104         leaq 32 * 16(%rdx), %rdx;
1105
1106         write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
1107                      %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
1108                      %ymm8, %rsi);
1109
1110         vzeroall;
1111
1112         leave;
1113         ret;
1114 .size _gcry_camellia_aesni_avx2_ctr_enc,.-_gcry_camellia_aesni_avx2_ctr_enc;
1115
1116 .align 8
1117 .globl _gcry_camellia_aesni_avx2_cbc_dec
1118 .type   _gcry_camellia_aesni_avx2_cbc_dec,@function;
1119
1120 _gcry_camellia_aesni_avx2_cbc_dec:
1121         /* input:
1122          *      %rdi: ctx, CTX
1123          *      %rsi: dst (16 blocks)
1124          *      %rdx: src (16 blocks)
1125          *      %rcx: iv
1126          */
1127
1128         pushq %rbp;
1129         movq %rsp, %rbp;
1130
1131         vzeroupper;
1132
1133         movq %rcx, %r9;
1134
1135         cmpl $128, key_bitlength(CTX);
1136         movl $32, %r8d;
1137         movl $24, %eax;
1138         cmovel %eax, %r8d; /* max */
1139
1140         subq $(16 * 32), %rsp;
1141         andq $~63, %rsp;
1142         movq %rsp, %rax;
1143
1144         inpack32_pre(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
1145                      %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
1146                      %ymm15, %rdx, (key_table)(CTX, %r8, 8));
1147
1148         call __camellia_dec_blk32;
1149
1150         /* XOR output with IV */
1151         vmovdqu %ymm8, (%rax);
1152         vmovdqu (%r9), %xmm8;
1153         vinserti128 $1, (%rdx), %ymm8, %ymm8;
1154         vpxor %ymm8, %ymm7, %ymm7;
1155         vmovdqu (%rax), %ymm8;
1156         vpxor (0 * 32 + 16)(%rdx), %ymm6, %ymm6;
1157         vpxor (1 * 32 + 16)(%rdx), %ymm5, %ymm5;
1158         vpxor (2 * 32 + 16)(%rdx), %ymm4, %ymm4;
1159         vpxor (3 * 32 + 16)(%rdx), %ymm3, %ymm3;
1160         vpxor (4 * 32 + 16)(%rdx), %ymm2, %ymm2;
1161         vpxor (5 * 32 + 16)(%rdx), %ymm1, %ymm1;
1162         vpxor (6 * 32 + 16)(%rdx), %ymm0, %ymm0;
1163         vpxor (7 * 32 + 16)(%rdx), %ymm15, %ymm15;
1164         vpxor (8 * 32 + 16)(%rdx), %ymm14, %ymm14;
1165         vpxor (9 * 32 + 16)(%rdx), %ymm13, %ymm13;
1166         vpxor (10 * 32 + 16)(%rdx), %ymm12, %ymm12;
1167         vpxor (11 * 32 + 16)(%rdx), %ymm11, %ymm11;
1168         vpxor (12 * 32 + 16)(%rdx), %ymm10, %ymm10;
1169         vpxor (13 * 32 + 16)(%rdx), %ymm9, %ymm9;
1170         vpxor (14 * 32 + 16)(%rdx), %ymm8, %ymm8;
1171         movq (15 * 32 + 16 + 0)(%rdx), %rax;
1172         movq (15 * 32 + 16 + 8)(%rdx), %rcx;
1173
1174         write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
1175                      %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
1176                      %ymm8, %rsi);
1177
1178         /* store new IV */
1179         movq %rax, (0)(%r9);
1180         movq %rcx, (8)(%r9);
1181
1182         vzeroall;
1183
1184         leave;
1185         ret;
1186 .size _gcry_camellia_aesni_avx2_cbc_dec,.-_gcry_camellia_aesni_avx2_cbc_dec;
1187
1188 .align 8
1189 .globl _gcry_camellia_aesni_avx2_cfb_dec
1190 .type   _gcry_camellia_aesni_avx2_cfb_dec,@function;
1191
1192 _gcry_camellia_aesni_avx2_cfb_dec:
1193         /* input:
1194          *      %rdi: ctx, CTX
1195          *      %rsi: dst (16 blocks)
1196          *      %rdx: src (16 blocks)
1197          *      %rcx: iv
1198          */
1199
1200         pushq %rbp;
1201         movq %rsp, %rbp;
1202
1203         vzeroupper;
1204
1205         subq $(16 * 32), %rsp;
1206         andq $~63, %rsp;
1207         movq %rsp, %rax;
1208
1209         /* inpack16_pre: */
1210         vpbroadcastq (key_table)(CTX), %ymm0;
1211         vpshufb .Lpack_bswap RIP, %ymm0, %ymm0;
1212         vmovdqu (%rcx), %xmm15;
1213         vinserti128 $1, (%rdx), %ymm15, %ymm15;
1214         vpxor %ymm15, %ymm0, %ymm15;
1215         vmovdqu (15 * 32 + 16)(%rdx), %xmm1;
1216         vmovdqu %xmm1, (%rcx); /* store new IV */
1217         vpxor (0 * 32 + 16)(%rdx), %ymm0, %ymm14;
1218         vpxor (1 * 32 + 16)(%rdx), %ymm0, %ymm13;
1219         vpxor (2 * 32 + 16)(%rdx), %ymm0, %ymm12;
1220         vpxor (3 * 32 + 16)(%rdx), %ymm0, %ymm11;
1221         vpxor (4 * 32 + 16)(%rdx), %ymm0, %ymm10;
1222         vpxor (5 * 32 + 16)(%rdx), %ymm0, %ymm9;
1223         vpxor (6 * 32 + 16)(%rdx), %ymm0, %ymm8;
1224         vpxor (7 * 32 + 16)(%rdx), %ymm0, %ymm7;
1225         vpxor (8 * 32 + 16)(%rdx), %ymm0, %ymm6;
1226         vpxor (9 * 32 + 16)(%rdx), %ymm0, %ymm5;
1227         vpxor (10 * 32 + 16)(%rdx), %ymm0, %ymm4;
1228         vpxor (11 * 32 + 16)(%rdx), %ymm0, %ymm3;
1229         vpxor (12 * 32 + 16)(%rdx), %ymm0, %ymm2;
1230         vpxor (13 * 32 + 16)(%rdx), %ymm0, %ymm1;
1231         vpxor (14 * 32 + 16)(%rdx), %ymm0, %ymm0;
1232
1233         call __camellia_enc_blk32;
1234
1235         vpxor 0 * 32(%rdx), %ymm7, %ymm7;
1236         vpxor 1 * 32(%rdx), %ymm6, %ymm6;
1237         vpxor 2 * 32(%rdx), %ymm5, %ymm5;
1238         vpxor 3 * 32(%rdx), %ymm4, %ymm4;
1239         vpxor 4 * 32(%rdx), %ymm3, %ymm3;
1240         vpxor 5 * 32(%rdx), %ymm2, %ymm2;
1241         vpxor 6 * 32(%rdx), %ymm1, %ymm1;
1242         vpxor 7 * 32(%rdx), %ymm0, %ymm0;
1243         vpxor 8 * 32(%rdx), %ymm15, %ymm15;
1244         vpxor 9 * 32(%rdx), %ymm14, %ymm14;
1245         vpxor 10 * 32(%rdx), %ymm13, %ymm13;
1246         vpxor 11 * 32(%rdx), %ymm12, %ymm12;
1247         vpxor 12 * 32(%rdx), %ymm11, %ymm11;
1248         vpxor 13 * 32(%rdx), %ymm10, %ymm10;
1249         vpxor 14 * 32(%rdx), %ymm9, %ymm9;
1250         vpxor 15 * 32(%rdx), %ymm8, %ymm8;
1251
1252         write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
1253                      %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
1254                      %ymm8, %rsi);
1255
1256         vzeroall;
1257
1258         leave;
1259         ret;
1260 .size _gcry_camellia_aesni_avx2_cfb_dec,.-_gcry_camellia_aesni_avx2_cfb_dec;
1261
1262 #endif /*defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT)*/
1263 #endif /*__x86_64*/