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