rijndael-ssse3: call assembly functions directly
[libgcrypt.git] / cipher / rijndael-ssse3-amd64-asm.S
1 /* SSSE3 vector permutation AES for Libgcrypt
2  * Copyright (C) 2014-2017 Jussi Kivilinna <jussi.kivilinna@iki.fi>
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  *
19  *
20  * The code is based on the public domain library libvpaes version 0.5
21  * available at http://crypto.stanford.edu/vpaes/ and which carries
22  * this notice:
23  *
24  *     libvpaes: constant-time SSSE3 AES encryption and decryption.
25  *     version 0.5
26  *
27  *     By Mike Hamburg, Stanford University, 2009.  Public domain.
28  *     I wrote essentially all of this code.  I did not write the test
29  *     vectors; they are the NIST known answer tests.  I hereby release all
30  *     the code and documentation here that I wrote into the public domain.
31  *
32  *     This is an implementation of AES following my paper,
33  *       "Accelerating AES with Vector Permute Instructions
34  *       CHES 2009; http://shiftleft.org/papers/vector_aes/
35  */
36
37 #if defined(__x86_64__)
38 #include <config.h>
39 #if defined(HAVE_GCC_INLINE_ASM_SSSE3) && \
40     (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
41      defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
42
43 #include "asm-common-amd64.h"
44
45 .text
46
47 ##
48 ##  _gcry_aes_ssse3_enc_preload
49 ##
50 ELF(.type _gcry_aes_ssse3_enc_preload,@function)
51 .globl _gcry_aes_ssse3_enc_preload
52 _gcry_aes_ssse3_enc_preload:
53         ENTER_SYSV_FUNC_PARAMS_0_4
54         lea     .Laes_consts(%rip), %rax
55         movdqa            (%rax), %xmm9  # 0F
56         movdqa  .Lk_inv   (%rax), %xmm10 # inv
57         movdqa  .Lk_inv+16(%rax), %xmm11 # inva
58         movdqa  .Lk_sb1   (%rax), %xmm13 # sb1u
59         movdqa  .Lk_sb1+16(%rax), %xmm12 # sb1t
60         movdqa  .Lk_sb2   (%rax), %xmm15 # sb2u
61         movdqa  .Lk_sb2+16(%rax), %xmm14 # sb2t
62         EXIT_SYSV_FUNC
63         ret
64 ELF(.size _gcry_aes_ssse3_enc_preload,.-_gcry_aes_ssse3_enc_preload)
65
66 ##
67 ##  _gcry_aes_ssse3_dec_preload
68 ##
69 ELF(.type _gcry_aes_ssse3_dec_preload,@function)
70 .globl _gcry_aes_ssse3_dec_preload
71 _gcry_aes_ssse3_dec_preload:
72         ENTER_SYSV_FUNC_PARAMS_0_4
73         lea     .Laes_consts(%rip), %rax
74         movdqa            (%rax), %xmm9   # 0F
75         movdqa  .Lk_inv   (%rax), %xmm10  # inv
76         movdqa  .Lk_inv+16(%rax), %xmm11  # inva
77         movdqa  .Lk_dsb9   (%rax), %xmm13 # sb9u
78         movdqa  .Lk_dsb9+16(%rax), %xmm12 # sb9t
79         movdqa  .Lk_dsbd   (%rax), %xmm15 # sbdu
80         movdqa  .Lk_dsbb   (%rax), %xmm14 # sbbu
81         movdqa  .Lk_dsbe   (%rax), %xmm8  # sbeu
82         EXIT_SYSV_FUNC
83         ret
84 ELF(.size _gcry_aes_ssse3_dec_preload,.-_gcry_aes_ssse3_dec_preload)
85
86 ##
87 ## Constant-time SSSE3 AES core implementation.
88 ##
89 ## By Mike Hamburg (Stanford University), 2009
90 ## Public domain.
91 ##
92
93 ##
94 ##  _aes_encrypt_core
95 ##
96 ##  AES-encrypt %xmm0.
97 ##
98 ##  Inputs:
99 ##     %xmm0 = input
100 ##     %xmm9-%xmm15 as in .Laes_preheat
101 ##    (%rdi) = scheduled keys
102 ##     %rsi  = nrounds
103 ##
104 ##  Output in %xmm0
105 ##  Clobbers  %xmm1-%xmm4, %r9, %r11, %rax, %rcx, %rdx
106 ##  Preserves %xmm6 - %xmm7 so you get some local vectors
107 ##
108 ##
109 .align 16
110 ELF(.type _gcry_aes_ssse3_encrypt_core,@function)
111 .globl _gcry_aes_ssse3_encrypt_core
112 _gcry_aes_ssse3_encrypt_core:
113 _aes_encrypt_core:
114         ENTER_SYSV_FUNC_PARAMS_0_4
115         mov     %rdi,   %rdx
116         leaq    -1(%rsi), %rax
117         lea     .Laes_consts(%rip), %rcx
118         leaq    .Lk_mc_backward(%rcx), %rdi
119         mov     $16,    %rsi
120         movdqa  .Lk_ipt   (%rcx), %xmm2 # iptlo
121         movdqa  %xmm9,  %xmm1
122         pandn   %xmm0,  %xmm1
123         psrld   $4,     %xmm1
124         pand    %xmm9,  %xmm0
125         pshufb  %xmm0,  %xmm2
126         movdqa  .Lk_ipt+16(%rcx), %xmm0 # ipthi
127         pshufb  %xmm1,  %xmm0
128         pxor    (%rdx),%xmm2
129         pxor    %xmm2,  %xmm0
130         add     $16,    %rdx
131         jmp     .Laes_entry
132
133 .align 8
134 .Laes_loop:
135         # middle of middle round
136         movdqa  %xmm13, %xmm4   # 4 : sb1u
137         pshufb  %xmm2,  %xmm4   # 4 = sb1u
138         pxor    (%rdx), %xmm4   # 4 = sb1u + k
139         movdqa  %xmm12, %xmm0   # 0 : sb1t
140         pshufb  %xmm3,  %xmm0   # 0 = sb1t
141         pxor    %xmm4,  %xmm0   # 0 = A
142         movdqa  %xmm15, %xmm4   # 4 : sb2u
143         pshufb  %xmm2,  %xmm4   # 4 = sb2u
144         movdqa  .Lk_mc_forward-.Lk_mc_backward(%rsi,%rdi), %xmm1
145         movdqa  %xmm14, %xmm2   # 2 : sb2t
146         pshufb  %xmm3,  %xmm2   # 2 = sb2t
147         pxor    %xmm4,  %xmm2   # 2 = 2A
148         movdqa  %xmm0,  %xmm3   # 3 = A
149         pshufb  %xmm1,  %xmm0   # 0 = B
150         pxor    %xmm2,  %xmm0   # 0 = 2A+B
151         pshufb  (%rsi,%rdi), %xmm3  # 3 = D
152         lea     16(%esi),%esi   # next mc
153         pxor    %xmm0,  %xmm3   # 3 = 2A+B+D
154         lea     16(%rdx),%rdx   # next key
155         pshufb  %xmm1,  %xmm0   # 0 = 2B+C
156         pxor    %xmm3,  %xmm0   # 0 = 2A+3B+C+D
157         and     $48, %rsi       # ... mod 4
158         dec     %rax            # nr--
159
160 .Laes_entry:
161         # top of round
162         movdqa  %xmm9,  %xmm1   # 1 : i
163         pandn   %xmm0,  %xmm1   # 1 = i<<4
164         psrld   $4,     %xmm1   # 1 = i
165         pand    %xmm9,  %xmm0   # 0 = k
166         movdqa  %xmm11, %xmm2   # 2 : a/k
167         pshufb  %xmm0,  %xmm2   # 2 = a/k
168         pxor    %xmm1,  %xmm0   # 0 = j
169         movdqa  %xmm10, %xmm3   # 3 : 1/i
170         pshufb  %xmm1,  %xmm3   # 3 = 1/i
171         pxor    %xmm2,  %xmm3   # 3 = iak = 1/i + a/k
172         movdqa  %xmm10, %xmm4   # 4 : 1/j
173         pshufb  %xmm0,  %xmm4   # 4 = 1/j
174         pxor    %xmm2,  %xmm4   # 4 = jak = 1/j + a/k
175         movdqa  %xmm10, %xmm2   # 2 : 1/iak
176         pshufb  %xmm3,  %xmm2   # 2 = 1/iak
177         pxor    %xmm0,  %xmm2   # 2 = io
178         movdqa  %xmm10, %xmm3   # 3 : 1/jak
179         pshufb  %xmm4,  %xmm3   # 3 = 1/jak
180         pxor    %xmm1,  %xmm3   # 3 = jo
181         jnz     .Laes_loop
182
183         # middle of last round
184         movdqa  .Lk_sbo(%rcx), %xmm4    # 3 : sbou
185         pshufb  %xmm2,  %xmm4   # 4 = sbou
186         pxor    (%rdx), %xmm4   # 4 = sb1u + k
187         movdqa  .Lk_sbo+16(%rcx), %xmm0 # 0 : sbot
188         pshufb  %xmm3,  %xmm0   # 0 = sb1t
189         pxor    %xmm4,  %xmm0   # 0 = A
190         pshufb  .Lk_sr(%rsi,%rcx), %xmm0
191         EXIT_SYSV_FUNC
192         ret
193 ELF(.size _aes_encrypt_core,.-_aes_encrypt_core)
194
195 ##
196 ##  Decryption core
197 ##
198 ##  Same API as encryption core.
199 ##
200 .align 16
201 .globl _gcry_aes_ssse3_decrypt_core
202 ELF(.type _gcry_aes_ssse3_decrypt_core,@function)
203 _gcry_aes_ssse3_decrypt_core:
204 _aes_decrypt_core:
205         ENTER_SYSV_FUNC_PARAMS_0_4
206         mov     %rdi,   %rdx
207         lea     .Laes_consts(%rip), %rcx
208         subl    $1,     %esi
209         movl    %esi,   %eax
210         shll    $4,     %esi
211         xorl    $48,    %esi
212         andl    $48,    %esi
213         movdqa  .Lk_dipt   (%rcx), %xmm2 # iptlo
214         movdqa  %xmm9,  %xmm1
215         pandn   %xmm0,  %xmm1
216         psrld   $4,     %xmm1
217         pand    %xmm9,  %xmm0
218         pshufb  %xmm0,  %xmm2
219         movdqa  .Lk_dipt+16(%rcx), %xmm0 # ipthi
220         pshufb  %xmm1,  %xmm0
221         pxor    (%rdx), %xmm2
222         pxor    %xmm2,  %xmm0
223         movdqa  .Lk_mc_forward+48(%rcx), %xmm5
224         lea     16(%rdx), %rdx
225         neg     %rax
226         jmp     .Laes_dec_entry
227
228 .align 16
229 .Laes_dec_loop:
230 ##
231 ##  Inverse mix columns
232 ##
233         movdqa  %xmm13, %xmm4           # 4 : sb9u
234         pshufb  %xmm2,  %xmm4           # 4 = sb9u
235         pxor    (%rdx), %xmm4
236         movdqa  %xmm12, %xmm0           # 0 : sb9t
237         pshufb  %xmm3,  %xmm0           # 0 = sb9t
238         movdqa  .Lk_dsbd+16(%rcx),%xmm1 # 1 : sbdt
239         pxor    %xmm4,  %xmm0           # 0 = ch
240         lea     16(%rdx), %rdx          # next round key
241
242         pshufb  %xmm5,  %xmm0           # MC ch
243         movdqa  %xmm15, %xmm4           # 4 : sbdu
244         pshufb  %xmm2,  %xmm4           # 4 = sbdu
245         pxor    %xmm0,  %xmm4           # 4 = ch
246         pshufb  %xmm3,  %xmm1           # 1 = sbdt
247         pxor    %xmm4,  %xmm1           # 1 = ch
248
249         pshufb  %xmm5,  %xmm1           # MC ch
250         movdqa  %xmm14, %xmm4           # 4 : sbbu
251         pshufb  %xmm2,  %xmm4           # 4 = sbbu
252         inc     %rax                    # nr--
253         pxor    %xmm1,  %xmm4           # 4 = ch
254         movdqa  .Lk_dsbb+16(%rcx),%xmm0 # 0 : sbbt
255         pshufb  %xmm3,  %xmm0           # 0 = sbbt
256         pxor    %xmm4,  %xmm0           # 0 = ch
257
258         pshufb  %xmm5,  %xmm0           # MC ch
259         movdqa  %xmm8,  %xmm4           # 4 : sbeu
260         pshufb  %xmm2,  %xmm4           # 4 = sbeu
261         pshufd  $0x93,  %xmm5,  %xmm5
262         pxor    %xmm0,  %xmm4           # 4 = ch
263         movdqa  .Lk_dsbe+16(%rcx),%xmm0 # 0 : sbet
264         pshufb  %xmm3,  %xmm0           # 0 = sbet
265         pxor    %xmm4,  %xmm0           # 0 = ch
266
267 .Laes_dec_entry:
268         # top of round
269         movdqa  %xmm9,  %xmm1   # 1 : i
270         pandn   %xmm0,  %xmm1   # 1 = i<<4
271         psrld   $4,     %xmm1   # 1 = i
272         pand    %xmm9,  %xmm0   # 0 = k
273         movdqa  %xmm11, %xmm2   # 2 : a/k
274         pshufb  %xmm0,  %xmm2   # 2 = a/k
275         pxor    %xmm1,  %xmm0   # 0 = j
276         movdqa  %xmm10, %xmm3   # 3 : 1/i
277         pshufb  %xmm1,  %xmm3   # 3 = 1/i
278         pxor    %xmm2,  %xmm3   # 3 = iak = 1/i + a/k
279         movdqa  %xmm10, %xmm4   # 4 : 1/j
280         pshufb  %xmm0,  %xmm4   # 4 = 1/j
281         pxor    %xmm2,  %xmm4   # 4 = jak = 1/j + a/k
282         movdqa  %xmm10, %xmm2   # 2 : 1/iak
283         pshufb  %xmm3,  %xmm2   # 2 = 1/iak
284         pxor    %xmm0,  %xmm2   # 2 = io
285         movdqa  %xmm10, %xmm3   # 3 : 1/jak
286         pshufb  %xmm4,  %xmm3   # 3 = 1/jak
287         pxor    %xmm1,  %xmm3   # 3 = jo
288         jnz     .Laes_dec_loop
289
290         # middle of last round
291         movdqa  .Lk_dsbo(%rcx), %xmm4           # 3 : sbou
292         pshufb  %xmm2,  %xmm4   # 4 = sbou
293         pxor    (%rdx), %xmm4   # 4 = sb1u + k
294         movdqa  .Lk_dsbo+16(%rcx), %xmm0        # 0 : sbot
295         pshufb  %xmm3,  %xmm0   # 0 = sb1t
296         pxor    %xmm4,  %xmm0   # 0 = A
297         pshufb  .Lk_sr(%rsi,%rcx), %xmm0
298         EXIT_SYSV_FUNC
299         ret
300 ELF(.size _aes_decrypt_core,.-_aes_decrypt_core)
301
302 ########################################################
303 ##                                                    ##
304 ##                  AES key schedule                  ##
305 ##                                                    ##
306 ########################################################
307
308 .align 16
309 .globl _gcry_aes_ssse3_schedule_core
310 ELF(.type _gcry_aes_ssse3_schedule_core,@function)
311 _gcry_aes_ssse3_schedule_core:
312 _aes_schedule_core:
313         # rdi = key
314         # rsi = size in bits
315         # rdx = buffer
316         # rcx = direction.  0=encrypt, 1=decrypt
317         # r8 = rotoffs
318         ENTER_SYSV_FUNC_PARAMS_5
319
320         # load the tables
321         lea     .Laes_consts(%rip), %r10
322         movdqa            (%r10), %xmm9  # 0F
323         movdqa  .Lk_inv   (%r10), %xmm10 # inv
324         movdqa  .Lk_inv+16(%r10), %xmm11 # inva
325         movdqa  .Lk_sb1   (%r10), %xmm13 # sb1u
326         movdqa  .Lk_sb1+16(%r10), %xmm12 # sb1t
327         movdqa  .Lk_sb2   (%r10), %xmm15 # sb2u
328         movdqa  .Lk_sb2+16(%r10), %xmm14 # sb2t
329
330         movdqa  .Lk_rcon(%r10), %xmm8   # load rcon
331         movdqu  (%rdi), %xmm0           # load key (unaligned)
332
333         # input transform
334         movdqu  %xmm0,  %xmm3
335         lea     .Lk_ipt(%r10), %r11
336         call    .Laes_schedule_transform
337         movdqu  %xmm0,  %xmm7
338
339         test    %rcx,   %rcx
340         jnz     .Laes_schedule_am_decrypting
341
342         # encrypting, output zeroth round key after transform
343         movdqa  %xmm0,  (%rdx)
344         jmp     .Laes_schedule_go
345
346 .Laes_schedule_am_decrypting:
347         # decrypting, output zeroth round key after shiftrows
348         pshufb  .Lk_sr(%r8,%r10),%xmm3
349         movdqa  %xmm3,  (%rdx)
350         xor     $48,    %r8
351
352 .Laes_schedule_go:
353         cmp     $192,   %rsi
354         je      .Laes_schedule_192
355         cmp     $256,   %rsi
356         je      .Laes_schedule_256
357         # 128: fall though
358
359 ##
360 ##  .Laes_schedule_128
361 ##
362 ##  128-bit specific part of key schedule.
363 ##
364 ##  This schedule is really simple, because all its parts
365 ##  are accomplished by the subroutines.
366 ##
367 .Laes_schedule_128:
368         mov     $10, %rsi
369
370 .Laes_schedule_128_L:
371         call    .Laes_schedule_round
372         dec     %rsi
373         jz      .Laes_schedule_mangle_last
374         call    .Laes_schedule_mangle   # write output
375         jmp     .Laes_schedule_128_L
376
377 ##
378 ##  .Laes_schedule_192
379 ##
380 ##  192-bit specific part of key schedule.
381 ##
382 ##  The main body of this schedule is the same as the 128-bit
383 ##  schedule, but with more smearing.  The long, high side is
384 ##  stored in %xmm7 as before, and the short, low side is in
385 ##  the high bits of %xmm6.
386 ##
387 ##  This schedule is somewhat nastier, however, because each
388 ##  round produces 192 bits of key material, or 1.5 round keys.
389 ##  Therefore, on each cycle we do 2 rounds and produce 3 round
390 ##  keys.
391 ##
392 .Laes_schedule_192:
393         movdqu  8(%rdi),%xmm0           # load key part 2 (very unaligned)
394         call    .Laes_schedule_transform        # input transform
395         pshufd  $0x0E,  %xmm0,  %xmm6
396         pslldq  $8,     %xmm6           # clobber low side with zeros
397         mov     $4,     %rsi
398
399 .Laes_schedule_192_L:
400         call    .Laes_schedule_round
401         palignr $8,%xmm6,%xmm0
402         call    .Laes_schedule_mangle   # save key n
403         call    .Laes_schedule_192_smear
404         call    .Laes_schedule_mangle   # save key n+1
405         call    .Laes_schedule_round
406         dec     %rsi
407         jz      .Laes_schedule_mangle_last
408         call    .Laes_schedule_mangle   # save key n+2
409         call    .Laes_schedule_192_smear
410         jmp     .Laes_schedule_192_L
411
412 ##
413 ##  .Laes_schedule_192_smear
414 ##
415 ##  Smear the short, low side in the 192-bit key schedule.
416 ##
417 ##  Inputs:
418 ##    %xmm7: high side, b  a  x  y
419 ##    %xmm6:  low side, d  c  0  0
420 ##    %xmm13: 0
421 ##
422 ##  Outputs:
423 ##    %xmm6: b+c+d  b+c  0  0
424 ##    %xmm0: b+c+d  b+c  b  a
425 ##
426 .Laes_schedule_192_smear:
427         pshufd  $0x80,  %xmm6,  %xmm0   # d c 0 0 -> c 0 0 0
428         pxor    %xmm0,  %xmm6           # -> c+d c 0 0
429         pshufd  $0xFE,  %xmm7,  %xmm0   # b a _ _ -> b b b a
430         pxor    %xmm6,  %xmm0           # -> b+c+d b+c b a
431         pshufd  $0x0E,  %xmm0,  %xmm6
432         pslldq  $8,     %xmm6           # clobber low side with zeros
433         ret
434
435 ##
436 ##  .Laes_schedule_256
437 ##
438 ##  256-bit specific part of key schedule.
439 ##
440 ##  The structure here is very similar to the 128-bit
441 ##  schedule, but with an additional 'low side' in
442 ##  %xmm6.  The low side's rounds are the same as the
443 ##  high side's, except no rcon and no rotation.
444 ##
445 .Laes_schedule_256:
446         movdqu  16(%rdi),%xmm0          # load key part 2 (unaligned)
447         call    .Laes_schedule_transform        # input transform
448         mov     $7, %rsi
449
450 .Laes_schedule_256_L:
451         call    .Laes_schedule_mangle   # output low result
452         movdqa  %xmm0,  %xmm6           # save cur_lo in xmm6
453
454         # high round
455         call    .Laes_schedule_round
456         dec     %rsi
457         jz      .Laes_schedule_mangle_last
458         call    .Laes_schedule_mangle
459
460         # low round. swap xmm7 and xmm6
461         pshufd  $0xFF,  %xmm0,  %xmm0
462         movdqa  %xmm7,  %xmm5
463         movdqa  %xmm6,  %xmm7
464         call    .Laes_schedule_low_round
465         movdqa  %xmm5,  %xmm7
466
467         jmp     .Laes_schedule_256_L
468
469 ##
470 ##  .Laes_schedule_round
471 ##
472 ##  Runs one main round of the key schedule on %xmm0, %xmm7
473 ##
474 ##  Specifically, runs subbytes on the high dword of %xmm0
475 ##  then rotates it by one byte and xors into the low dword of
476 ##  %xmm7.
477 ##
478 ##  Adds rcon from low byte of %xmm8, then rotates %xmm8 for
479 ##  next rcon.
480 ##
481 ##  Smears the dwords of %xmm7 by xoring the low into the
482 ##  second low, result into third, result into highest.
483 ##
484 ##  Returns results in %xmm7 = %xmm0.
485 ##  Clobbers %xmm1-%xmm4, %r11.
486 ##
487 .Laes_schedule_round:
488         # extract rcon from xmm8
489         pxor    %xmm1,  %xmm1
490         palignr $15,    %xmm8,  %xmm1
491         palignr $15,    %xmm8,  %xmm8
492         pxor    %xmm1,  %xmm7
493
494         # rotate
495         pshufd  $0xFF,  %xmm0,  %xmm0
496         palignr $1,     %xmm0,  %xmm0
497
498         # fall through...
499
500         # low round: same as high round, but no rotation and no rcon.
501 .Laes_schedule_low_round:
502         # smear xmm7
503         movdqa  %xmm7,  %xmm1
504         pslldq  $4,     %xmm7
505         pxor    %xmm1,  %xmm7
506         movdqa  %xmm7,  %xmm1
507         pslldq  $8,     %xmm7
508         pxor    %xmm1,  %xmm7
509         pxor    .Lk_s63(%r10), %xmm7
510
511         # subbytes
512         movdqa  %xmm9,  %xmm1
513         pandn   %xmm0,  %xmm1
514         psrld   $4,     %xmm1           # 1 = i
515         pand    %xmm9,  %xmm0           # 0 = k
516         movdqa  %xmm11, %xmm2           # 2 : a/k
517         pshufb  %xmm0,  %xmm2           # 2 = a/k
518         pxor    %xmm1,  %xmm0           # 0 = j
519         movdqa  %xmm10, %xmm3           # 3 : 1/i
520         pshufb  %xmm1,  %xmm3           # 3 = 1/i
521         pxor    %xmm2,  %xmm3           # 3 = iak = 1/i + a/k
522         movdqa  %xmm10, %xmm4           # 4 : 1/j
523         pshufb  %xmm0,  %xmm4           # 4 = 1/j
524         pxor    %xmm2,  %xmm4           # 4 = jak = 1/j + a/k
525         movdqa  %xmm10, %xmm2           # 2 : 1/iak
526         pshufb  %xmm3,  %xmm2           # 2 = 1/iak
527         pxor    %xmm0,  %xmm2           # 2 = io
528         movdqa  %xmm10, %xmm3           # 3 : 1/jak
529         pshufb  %xmm4,  %xmm3           # 3 = 1/jak
530         pxor    %xmm1,  %xmm3           # 3 = jo
531         movdqa  .Lk_sb1(%r10), %xmm4    # 4 : sbou
532         pshufb  %xmm2,  %xmm4           # 4 = sbou
533         movdqa  .Lk_sb1+16(%r10), %xmm0 # 0 : sbot
534         pshufb  %xmm3,  %xmm0           # 0 = sb1t
535         pxor    %xmm4,  %xmm0           # 0 = sbox output
536
537         # add in smeared stuff
538         pxor    %xmm7,  %xmm0
539         movdqa  %xmm0,  %xmm7
540         ret
541
542 ##
543 ##  .Laes_schedule_transform
544 ##
545 ##  Linear-transform %xmm0 according to tables at (%r11)
546 ##
547 ##  Requires that %xmm9 = 0x0F0F... as in preheat
548 ##  Output in %xmm0
549 ##  Clobbers %xmm1, %xmm2
550 ##
551 .Laes_schedule_transform:
552         movdqa  %xmm9,  %xmm1
553         pandn   %xmm0,  %xmm1
554         psrld   $4,     %xmm1
555         pand    %xmm9,  %xmm0
556         movdqa  (%r11), %xmm2   # lo
557         pshufb  %xmm0,  %xmm2
558         movdqa  16(%r11), %xmm0 # hi
559         pshufb  %xmm1,  %xmm0
560         pxor    %xmm2,  %xmm0
561         ret
562
563 ##
564 ##  .Laes_schedule_mangle
565 ##
566 ##  Mangle xmm0 from (basis-transformed) standard version
567 ##  to our version.
568 ##
569 ##  On encrypt,
570 ##    xor with 0x63
571 ##    multiply by circulant 0,1,1,1
572 ##    apply shiftrows transform
573 ##
574 ##  On decrypt,
575 ##    xor with 0x63
576 ##    multiply by 'inverse mixcolumns' circulant E,B,D,9
577 ##    deskew
578 ##    apply shiftrows transform
579 ##
580 ##
581 ##  Writes out to (%rdx), and increments or decrements it
582 ##  Keeps track of round number mod 4 in %r8
583 ##  Preserves xmm0
584 ##  Clobbers xmm1-xmm5
585 ##
586 .Laes_schedule_mangle:
587         movdqa  %xmm0,  %xmm4   # save xmm0 for later
588         movdqa  .Lk_mc_forward(%r10),%xmm5
589         test    %rcx,   %rcx
590         jnz     .Laes_schedule_mangle_dec
591
592         # encrypting
593         add     $16,    %rdx
594         pxor    .Lk_s63(%r10),%xmm4
595         pshufb  %xmm5,  %xmm4
596         movdqa  %xmm4,  %xmm3
597         pshufb  %xmm5,  %xmm4
598         pxor    %xmm4,  %xmm3
599         pshufb  %xmm5,  %xmm4
600         pxor    %xmm4,  %xmm3
601
602         jmp     .Laes_schedule_mangle_both
603
604 .Laes_schedule_mangle_dec:
605         lea     .Lk_dks_1(%r10), %r11   # first table: *9
606         call    .Laes_schedule_transform
607         movdqa  %xmm0,  %xmm3
608         pshufb  %xmm5,  %xmm3
609
610         add     $32,    %r11            # next table:  *B
611         call    .Laes_schedule_transform
612         pxor    %xmm0,  %xmm3
613         pshufb  %xmm5,  %xmm3
614
615         add     $32,    %r11            # next table:  *D
616         call    .Laes_schedule_transform
617         pxor    %xmm0,  %xmm3
618         pshufb  %xmm5,  %xmm3
619
620         add     $32,    %r11            # next table:  *E
621         call    .Laes_schedule_transform
622         pxor    %xmm0,  %xmm3
623         pshufb  %xmm5,  %xmm3
624
625         movdqa  %xmm4,  %xmm0           # restore %xmm0
626         add     $-16,   %rdx
627
628 .Laes_schedule_mangle_both:
629         pshufb  .Lk_sr(%r8,%r10),%xmm3
630         add     $-16,   %r8
631         and     $48,    %r8
632         movdqa  %xmm3,  (%rdx)
633         ret
634
635 ##
636 ##  .Laes_schedule_mangle_last
637 ##
638 ##  Mangler for last round of key schedule
639 ##  Mangles %xmm0
640 ##    when encrypting, outputs out(%xmm0) ^ 63
641 ##    when decrypting, outputs unskew(%xmm0)
642 ##
643 ##  Always called right before return... jumps to cleanup and exits
644 ##
645 .Laes_schedule_mangle_last:
646         # schedule last round key from xmm0
647         lea     .Lk_deskew(%r10),%r11   # prepare to deskew
648         test    %rcx,   %rcx
649         jnz     .Laes_schedule_mangle_last_dec
650
651         # encrypting
652         pshufb  .Lk_sr(%r8,%r10),%xmm0  # output permute
653         lea     .Lk_opt(%r10),  %r11    # prepare to output transform
654         add     $32,    %rdx
655
656 .Laes_schedule_mangle_last_dec:
657         add     $-16,   %rdx
658         pxor    .Lk_s63(%r10),  %xmm0
659         call    .Laes_schedule_transform # output transform
660         movdqa  %xmm0,  (%rdx)          # save last key
661
662         #_aes_cleanup
663         pxor    %xmm0,  %xmm0
664         pxor    %xmm1,  %xmm1
665         pxor    %xmm2,  %xmm2
666         pxor    %xmm3,  %xmm3
667         pxor    %xmm4,  %xmm4
668         pxor    %xmm5,  %xmm5
669         pxor    %xmm6,  %xmm6
670         pxor    %xmm7,  %xmm7
671         pxor    %xmm8,  %xmm8
672         EXIT_SYSV_FUNC
673         ret
674 ELF(.size _gcry_aes_ssse3_schedule_core,.-_gcry_aes_ssse3_schedule_core)
675
676 ########################################################
677 ##                                                    ##
678 ##                     Constants                      ##
679 ##                                                    ##
680 ########################################################
681
682 .align 16
683 ELF(.type _aes_consts,@object)
684 .Laes_consts:
685 _aes_consts:
686         # s0F
687         .Lk_s0F = .-.Laes_consts
688         .quad   0x0F0F0F0F0F0F0F0F
689         .quad   0x0F0F0F0F0F0F0F0F
690
691         # input transform (lo, hi)
692         .Lk_ipt = .-.Laes_consts
693         .quad   0xC2B2E8985A2A7000
694         .quad   0xCABAE09052227808
695         .quad   0x4C01307D317C4D00
696         .quad   0xCD80B1FCB0FDCC81
697
698         # inv, inva
699         .Lk_inv = .-.Laes_consts
700         .quad   0x0E05060F0D080180
701         .quad   0x040703090A0B0C02
702         .quad   0x01040A060F0B0780
703         .quad   0x030D0E0C02050809
704
705         # sb1u, sb1t
706         .Lk_sb1 = .-.Laes_consts
707         .quad   0xB19BE18FCB503E00
708         .quad   0xA5DF7A6E142AF544
709         .quad   0x3618D415FAE22300
710         .quad   0x3BF7CCC10D2ED9EF
711
712
713         # sb2u, sb2t
714         .Lk_sb2 = .-.Laes_consts
715         .quad   0xE27A93C60B712400
716         .quad   0x5EB7E955BC982FCD
717         .quad   0x69EB88400AE12900
718         .quad   0xC2A163C8AB82234A
719
720         # sbou, sbot
721         .Lk_sbo = .-.Laes_consts
722         .quad   0xD0D26D176FBDC700
723         .quad   0x15AABF7AC502A878
724         .quad   0xCFE474A55FBB6A00
725         .quad   0x8E1E90D1412B35FA
726
727         # mc_forward
728         .Lk_mc_forward = .-.Laes_consts
729         .quad   0x0407060500030201
730         .quad   0x0C0F0E0D080B0A09
731         .quad   0x080B0A0904070605
732         .quad   0x000302010C0F0E0D
733         .quad   0x0C0F0E0D080B0A09
734         .quad   0x0407060500030201
735         .quad   0x000302010C0F0E0D
736         .quad   0x080B0A0904070605
737
738         # mc_backward
739         .Lk_mc_backward = .-.Laes_consts
740         .quad   0x0605040702010003
741         .quad   0x0E0D0C0F0A09080B
742         .quad   0x020100030E0D0C0F
743         .quad   0x0A09080B06050407
744         .quad   0x0E0D0C0F0A09080B
745         .quad   0x0605040702010003
746         .quad   0x0A09080B06050407
747         .quad   0x020100030E0D0C0F
748
749         # sr
750         .Lk_sr = .-.Laes_consts
751         .quad   0x0706050403020100
752         .quad   0x0F0E0D0C0B0A0908
753         .quad   0x030E09040F0A0500
754         .quad   0x0B06010C07020D08
755         .quad   0x0F060D040B020900
756         .quad   0x070E050C030A0108
757         .quad   0x0B0E0104070A0D00
758         .quad   0x0306090C0F020508
759
760         # rcon
761         .Lk_rcon = .-.Laes_consts
762         .quad   0x1F8391B9AF9DEEB6
763         .quad   0x702A98084D7C7D81
764
765         # s63: all equal to 0x63 transformed
766         .Lk_s63 = .-.Laes_consts
767         .quad   0x5B5B5B5B5B5B5B5B
768         .quad   0x5B5B5B5B5B5B5B5B
769
770         # output transform
771         .Lk_opt = .-.Laes_consts
772         .quad   0xFF9F4929D6B66000
773         .quad   0xF7974121DEBE6808
774         .quad   0x01EDBD5150BCEC00
775         .quad   0xE10D5DB1B05C0CE0
776
777         # deskew tables: inverts the sbox's 'skew'
778         .Lk_deskew = .-.Laes_consts
779         .quad   0x07E4A34047A4E300
780         .quad   0x1DFEB95A5DBEF91A
781         .quad   0x5F36B5DC83EA6900
782         .quad   0x2841C2ABF49D1E77
783
784 ##
785 ##  Decryption stuff
786 ##  Key schedule constants
787 ##
788         # decryption key schedule: x -> invskew x*9
789         .Lk_dks_1 = .-.Laes_consts
790         .quad   0xB6116FC87ED9A700
791         .quad   0x4AED933482255BFC
792         .quad   0x4576516227143300
793         .quad   0x8BB89FACE9DAFDCE
794
795         # decryption key schedule: invskew x*9 -> invskew x*D
796         .Lk_dks_2 = .-.Laes_consts
797         .quad   0x27438FEBCCA86400
798         .quad   0x4622EE8AADC90561
799         .quad   0x815C13CE4F92DD00
800         .quad   0x73AEE13CBD602FF2
801
802         # decryption key schedule: invskew x*D -> invskew x*B
803         .Lk_dks_3 = .-.Laes_consts
804         .quad   0x03C4C50201C6C700
805         .quad   0xF83F3EF9FA3D3CFB
806         .quad   0xEE1921D638CFF700
807         .quad   0xA5526A9D7384BC4B
808
809         # decryption key schedule: invskew x*B -> invskew x*E + 0x63
810         .Lk_dks_4 = .-.Laes_consts
811         .quad   0xE3C390B053732000
812         .quad   0xA080D3F310306343
813         .quad   0xA0CA214B036982E8
814         .quad   0x2F45AEC48CE60D67
815
816 ##
817 ##  Decryption stuff
818 ##  Round function constants
819 ##
820         # decryption input transform
821         .Lk_dipt = .-.Laes_consts
822         .quad   0x0F505B040B545F00
823         .quad   0x154A411E114E451A
824         .quad   0x86E383E660056500
825         .quad   0x12771772F491F194
826
827         # decryption sbox output *9*u, *9*t
828         .Lk_dsb9 = .-.Laes_consts
829         .quad   0x851C03539A86D600
830         .quad   0xCAD51F504F994CC9
831         .quad   0xC03B1789ECD74900
832         .quad   0x725E2C9EB2FBA565
833
834         # decryption sbox output *D*u, *D*t
835         .Lk_dsbd = .-.Laes_consts
836         .quad   0x7D57CCDFE6B1A200
837         .quad   0xF56E9B13882A4439
838         .quad   0x3CE2FAF724C6CB00
839         .quad   0x2931180D15DEEFD3
840
841         # decryption sbox output *B*u, *B*t
842         .Lk_dsbb = .-.Laes_consts
843         .quad   0xD022649296B44200
844         .quad   0x602646F6B0F2D404
845         .quad   0xC19498A6CD596700
846         .quad   0xF3FF0C3E3255AA6B
847
848         # decryption sbox output *E*u, *E*t
849         .Lk_dsbe = .-.Laes_consts
850         .quad   0x46F2929626D4D000
851         .quad   0x2242600464B4F6B0
852         .quad   0x0C55A6CDFFAAC100
853         .quad   0x9467F36B98593E32
854
855         # decryption sbox final output
856         .Lk_dsbo = .-.Laes_consts
857         .quad   0x1387EA537EF94000
858         .quad   0xC7AA6DB9D4943E2D
859         .quad   0x12D7560F93441D00
860         .quad   0xCA4B8159D8C58E9C
861 ELF(.size _aes_consts,.-_aes_consts)
862
863 #endif
864 #endif