bsaes-x86_64.pl: add bsaes_xts_[en|de]crypt.
[openssl.git] / crypto / aes / asm / bsaes-x86_64.pl
1 #!/usr/bin/env perl
2
3 ###################################################################
4 ### AES-128 [originally in CTR mode]                            ###
5 ### bitsliced implementation for Intel Core 2 processors        ###
6 ### requires support of SSE extensions up to SSSE3              ###
7 ### Author: Emilia Käsper and Peter Schwabe                    ###
8 ### Date: 2009-03-19                                            ###
9 ### Public domain                                               ###
10 ###                                                             ###
11 ### See http://homes.esat.kuleuven.be/~ekasper/#software for    ###
12 ### further information.                                        ###
13 ###################################################################
14 #
15 # September 2011.
16 #
17 # Started as transliteration to "perlasm" the original code has
18 # undergone following changes:
19 #
20 # - code was made position-independent;
21 # - rounds were folded into a loop resulting in >5x size reduction
22 #   from 12.5KB to 2.2KB;
23 # - above was possibile thanks to mixcolumns() modification that
24 #   allowed to feed its output back to aesenc[last], this was
25 #   achieved at cost of two additional inter-registers moves;
26 # - some instruction reordering and interleaving;
27 # - this module doesn't implement key setup subroutine, instead it
28 #   relies on conversion of "conventional" key schedule as returned
29 #   by AES_set_encrypt_key (see discussion below);
30 # - first and last round keys are treated differently, which allowed
31 #   to skip one shiftrows(), reduce bit-sliced key schedule and
32 #   speed-up conversion by 22%;
33 # - support for 192- and 256-bit keys was added;
34 #
35 # Resulting performance in CPU cycles spent to encrypt one byte out
36 # of 4096-byte buffer with 128-bit key is:
37 #
38 #               Emilia's        this(*)         difference
39 #
40 # Core 2        9.30            8.69            +7%
41 # Nehalem(**)   7.63            6.98            +9%
42 # Atom          17.1            17.4            -2%(***)
43 #
44 # (*)   Comparison is not completely fair, because "this" is ECB,
45 #       i.e. no extra processing such as counter values calculation
46 #       and xor-ing input as in Emilia's CTR implementation is
47 #       performed. However, the CTR calculations stand for not more
48 #       than 1% of total time, so comparison is *rather* fair.
49 #
50 # (**)  Results were collected on Westmere, which is considered to
51 #       be equivalent to Nehalem for this code.
52 #
53 # (***) Slowdown on Atom is rather strange per se, because original
54 #       implementation has a number of 9+-bytes instructions, which
55 #       are bad for Atom front-end, and which I eliminated completely.
56 #       In attempt to address deterioration sbox() was tested in FP
57 #       SIMD "domain" (movaps instead of movdqa, xorps instead of
58 #       pxor, etc.). While it resulted in nominal 4% improvement on
59 #       Atom, it hurted Westmere by more than 2x factor.
60 #
61 # As for key schedule conversion subroutine. Interface to OpenSSL
62 # relies on per-invocation on-the-fly conversion. This naturally
63 # has impact on performance, especially for short inputs. Conversion
64 # time in CPU cycles and its ratio to CPU cycles spent in 8x block
65 # function is:
66 #
67 #               conversion      conversion/8x block
68 # Core 2        410             0.37
69 # Nehalem       310             0.35
70 # Atom          570             0.26
71 #
72 # The ratio values mean that 128-byte blocks will be processed
73 # 21-27% slower, 256-byte blocks - 12-16%, 384-byte blocks - 8-11%,
74 # etc. Then keep in mind that input sizes not divisible by 128 are
75 # *effectively* slower, especially shortest ones, e.g. consecutive
76 # 144-byte blocks are processed 44% slower than one would expect,
77 # 272 - 29%, 400 - 22%, etc. Yet, despite all these "shortcomings"
78 # it's still faster than ["hyper-threading-safe" code path in]
79 # aes-x86_64.pl on all lengths above 64 bytes...
80 #
81 # October 2011.
82 #
83 # Add decryption procedure. Performance in CPU cycles spent to decrypt
84 # one byte out of 4096-byte buffer with 128-bit key is:
85 #
86 # Core 2        11.0
87 # Nehalem       9.16
88 #
89 # November 2011.
90 #
91 # Add bsaes_xts_[en|de]crypt. Small-block performance is suboptimal,
92 # but XTS is meant to be used with larger blocks...
93 #
94 #                                               <appro@openssl.org>
95
96 $flavour = shift;
97 $output  = shift;
98 if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
99
100 $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
101
102 $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
103 ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
104 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
105 die "can't locate x86_64-xlate.pl";
106
107 open STDOUT,"| $^X $xlate $flavour $output";
108
109 my ($inp,$out,$len,$key,$ivp)=("%rdi","%rsi","%rdx","%rcx");
110 my @XMM=map("%xmm$_",(15,0..14));       # best on Atom, +10% over (0..15)
111
112 {
113 my ($key,$rounds,$const)=("%rax","%r10d","%r11");
114
115 sub Sbox {
116 # input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
117 # output in lsb > [b0, b1, b4, b6, b3, b7, b2, b5] < msb
118 my @b=@_[0..7];
119 my @t=@_[8..11];
120 my @s=@_[12..15];
121         &InBasisChange  (@b);
122         &Inv_GF256      (@b[6,5,0,3,7,1,4,2],@t,@s);
123         &OutBasisChange (@b[7,1,4,2,6,5,0,3]);
124 }
125
126 sub InBasisChange {
127 # input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
128 # output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb 
129 my @b=@_[0..7];
130 $code.=<<___;
131         pxor    @b[6], @b[5]
132         pxor    @b[1], @b[2]
133         pxor    @b[0], @b[3]
134         pxor    @b[2], @b[6]
135         pxor    @b[0], @b[5]
136
137         pxor    @b[3], @b[6]
138         pxor    @b[7], @b[3]
139         pxor    @b[5], @b[7]
140         pxor    @b[4], @b[3]
141         pxor    @b[5], @b[4]
142         pxor    @b[1], @b[3]
143
144         pxor    @b[7], @b[2]
145         pxor    @b[5], @b[1]
146 ___
147 }
148
149 sub OutBasisChange {
150 # input in  lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
151 # output in lsb > [b6, b1, b2, b4, b7, b0, b3, b5] < msb
152 my @b=@_[0..7];
153 $code.=<<___;
154         pxor    @b[6], @b[0]
155         pxor    @b[4], @b[1]
156         pxor    @b[0], @b[2]
157         pxor    @b[6], @b[4]
158         pxor    @b[1], @b[6]
159
160         pxor    @b[5], @b[1]
161         pxor    @b[3], @b[5]
162         pxor    @b[7], @b[3]
163         pxor    @b[5], @b[7]
164         pxor    @b[5], @b[2]
165
166         pxor    @b[7], @b[4]
167 ___
168 }
169
170 sub InvSbox {
171 # input in lsb  > [b0, b1, b2, b3, b4, b5, b6, b7] < msb
172 # output in lsb > [b0, b1, b6, b4, b2, b7, b3, b5] < msb
173 my @b=@_[0..7];
174 my @t=@_[8..11];
175 my @s=@_[12..15];
176         &InvInBasisChange       (@b);
177         &Inv_GF256              (@b[5,1,2,6,3,7,0,4],@t,@s);
178         &InvOutBasisChange      (@b[3,7,0,4,5,1,2,6]);
179 }
180
181 sub InvInBasisChange {          # OutBasisChange in reverse
182 my @b=@_[5,1,2,6,3,7,0,4];
183 $code.=<<___
184         pxor    @b[7], @b[4]
185
186         pxor    @b[5], @b[7]
187         pxor    @b[5], @b[2]
188         pxor    @b[7], @b[3]
189         pxor    @b[3], @b[5]
190         pxor    @b[5], @b[1]
191
192         pxor    @b[1], @b[6]
193         pxor    @b[0], @b[2]
194         pxor    @b[6], @b[4]
195         pxor    @b[6], @b[0]
196         pxor    @b[4], @b[1]
197 ___
198 }
199
200 sub InvOutBasisChange {         # InBasisChange in reverse
201 my @b=@_[2,5,7,3,6,1,0,4];
202 $code.=<<___;
203         pxor    @b[5], @b[1]
204         pxor    @b[7], @b[2]
205
206         pxor    @b[1], @b[3]
207         pxor    @b[5], @b[4]
208         pxor    @b[5], @b[7]
209         pxor    @b[4], @b[3]
210          pxor   @b[0], @b[5]
211         pxor    @b[7], @b[3]
212          pxor   @b[2], @b[6]
213          pxor   @b[1], @b[2]
214         pxor    @b[3], @b[6]
215
216         pxor    @b[0], @b[3]
217         pxor    @b[6], @b[5]
218 ___
219 }
220
221 sub Mul_GF4 {
222 #;*************************************************************
223 #;* Mul_GF4: Input x0-x1,y0-y1 Output x0-x1 Temp t0 (8) *
224 #;*************************************************************
225 my ($x0,$x1,$y0,$y1,$t0)=@_;
226 $code.=<<___;
227         movdqa  $y0, $t0
228         pxor    $y1, $t0
229         pand    $x0, $t0
230         pxor    $x1, $x0
231         pand    $y0, $x1
232         pand    $y1, $x0
233         pxor    $x1, $x0
234         pxor    $t0, $x1
235 ___
236 }
237
238 sub Mul_GF4_N {                         # not used, see next subroutine
239 # multiply and scale by N
240 my ($x0,$x1,$y0,$y1,$t0)=@_;
241 $code.=<<___;
242         movdqa  $y0, $t0
243         pxor    $y1, $t0
244         pand    $x0, $t0
245         pxor    $x1, $x0
246         pand    $y0, $x1
247         pand    $y1, $x0
248         pxor    $x0, $x1
249         pxor    $t0, $x0
250 ___
251 }
252
253 sub Mul_GF4_N_GF4 {
254 # interleaved Mul_GF4_N and Mul_GF4
255 my ($x0,$x1,$y0,$y1,$t0,
256     $x2,$x3,$y2,$y3,$t1)=@_;
257 $code.=<<___;
258         movdqa  $y0, $t0
259          movdqa $y2, $t1
260         pxor    $y1, $t0
261          pxor   $y3, $t1
262         pand    $x0, $t0
263          pand   $x2, $t1
264         pxor    $x1, $x0
265          pxor   $x3, $x2
266         pand    $y0, $x1
267          pand   $y2, $x3
268         pand    $y1, $x0
269          pand   $y3, $x2
270         pxor    $x0, $x1
271          pxor   $x3, $x2
272         pxor    $t0, $x0
273          pxor   $t1, $x3
274 ___
275 }
276 sub Mul_GF16_2 {
277 my @x=@_[0..7];
278 my @y=@_[8..11];
279 my @t=@_[12..15];
280 $code.=<<___;
281         movdqa  @x[0], @t[0]
282         movdqa  @x[1], @t[1]
283 ___
284         &Mul_GF4        (@x[0], @x[1], @y[0], @y[1], @t[2]);
285 $code.=<<___;
286         pxor    @x[2], @t[0]
287         pxor    @x[3], @t[1]
288         pxor    @y[2], @y[0]
289         pxor    @y[3], @y[1]
290 ___
291         Mul_GF4_N_GF4   (@t[0], @t[1], @y[0], @y[1], @t[3],
292                          @x[2], @x[3], @y[2], @y[3], @t[2]);
293 $code.=<<___;
294         pxor    @t[0], @x[0]
295         pxor    @t[0], @x[2]
296         pxor    @t[1], @x[1]
297         pxor    @t[1], @x[3]
298
299         movdqa  @x[4], @t[0]
300         movdqa  @x[5], @t[1]
301         pxor    @x[6], @t[0]
302         pxor    @x[7], @t[1]
303 ___
304         &Mul_GF4_N_GF4  (@t[0], @t[1], @y[0], @y[1], @t[3],
305                          @x[6], @x[7], @y[2], @y[3], @t[2]);
306 $code.=<<___;
307         pxor    @y[2], @y[0]
308         pxor    @y[3], @y[1]
309 ___
310         &Mul_GF4        (@x[4], @x[5], @y[0], @y[1], @t[3]);
311 $code.=<<___;
312         pxor    @t[0], @x[4]
313         pxor    @t[0], @x[6]
314         pxor    @t[1], @x[5]
315         pxor    @t[1], @x[7]
316 ___
317 }
318 sub Inv_GF256 {
319 #;********************************************************************
320 #;* Inv_GF256: Input x0-x7 Output x0-x7 Temp t0-t3,s0-s3 (144)       *
321 #;********************************************************************
322 my @x=@_[0..7];
323 my @t=@_[8..11];
324 my @s=@_[12..15];
325 # direct optimizations from hardware
326 $code.=<<___;
327         movdqa  @x[4], @t[3]
328         movdqa  @x[5], @t[2]
329         movdqa  @x[1], @t[1]
330         movdqa  @x[7], @s[1]
331         movdqa  @x[0], @s[0]
332
333         pxor    @x[6], @t[3]
334         pxor    @x[7], @t[2]
335         pxor    @x[3], @t[1]
336          movdqa @t[3], @s[2]
337         pxor    @x[6], @s[1]
338          movdqa @t[2], @t[0]
339         pxor    @x[2], @s[0]
340          movdqa @t[3], @s[3]
341
342         por     @t[1], @t[2]
343         por     @s[0], @t[3]
344         pxor    @t[0], @s[3]
345         pand    @s[0], @s[2]
346         pxor    @t[1], @s[0]
347         pand    @t[1], @t[0]
348         pand    @s[0], @s[3]
349         movdqa  @x[3], @s[0]
350         pxor    @x[2], @s[0]
351         pand    @s[0], @s[1]
352         pxor    @s[1], @t[3]
353         pxor    @s[1], @t[2]
354         movdqa  @x[4], @s[1]
355         movdqa  @x[1], @s[0]
356         pxor    @x[5], @s[1]
357         pxor    @x[0], @s[0]
358         movdqa  @s[1], @t[1]
359         pand    @s[0], @s[1]
360         por     @s[0], @t[1]
361         pxor    @s[1], @t[0]
362         pxor    @s[3], @t[3]
363         pxor    @s[2], @t[2]
364         pxor    @s[3], @t[1]
365         movdqa  @x[7], @s[0]
366         pxor    @s[2], @t[0]
367         movdqa  @x[6], @s[1]
368         pxor    @s[2], @t[1]
369         movdqa  @x[5], @s[2]
370         pand    @x[3], @s[0]
371         movdqa  @x[4], @s[3]
372         pand    @x[2], @s[1]
373         pand    @x[1], @s[2]
374         por     @x[0], @s[3]
375         pxor    @s[0], @t[3]
376         pxor    @s[1], @t[2]
377         pxor    @s[2], @t[1]
378         pxor    @s[3], @t[0] 
379
380         #Inv_GF16 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
381
382         # new smaller inversion
383
384         movdqa  @t[3], @s[0]
385         pand    @t[1], @t[3]
386         pxor    @t[2], @s[0]
387
388         movdqa  @t[0], @s[2]
389         movdqa  @s[0], @s[3]
390         pxor    @t[3], @s[2]
391         pand    @s[2], @s[3]
392
393         movdqa  @t[1], @s[1]
394         pxor    @t[2], @s[3]
395         pxor    @t[0], @s[1]
396
397         pxor    @t[2], @t[3]
398
399         pand    @t[3], @s[1]
400
401         movdqa  @s[2], @t[2]
402         pxor    @t[0], @s[1]
403
404         pxor    @s[1], @t[2]
405         pxor    @s[1], @t[1]
406
407         pand    @t[0], @t[2]
408
409         pxor    @t[2], @s[2]
410         pxor    @t[2], @t[1]
411
412         pand    @s[3], @s[2]
413
414         pxor    @s[0], @s[2]
415 ___
416 # output in s3, s2, s1, t1
417
418 # Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \t2, \t3, \t0, \t1, \s0, \s1, \s2, \s3
419
420 # Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3
421         &Mul_GF16_2(@x,@s[3,2,1],@t[1],@s[0],@t[0,2,3]);
422
423 ### output msb > [x3,x2,x1,x0,x7,x6,x5,x4] < lsb
424 }
425
426 # AES linear components
427
428 sub ShiftRows {
429 my @x=@_[0..7];
430 my $mask=pop;
431 $code.=<<___;
432         pxor    0x00($key),@x[0]
433         pxor    0x10($key),@x[1]
434         pshufb  $mask,@x[0]
435         pxor    0x20($key),@x[2]
436         pshufb  $mask,@x[1]
437         pxor    0x30($key),@x[3]
438         pshufb  $mask,@x[2]
439         pxor    0x40($key),@x[4]
440         pshufb  $mask,@x[3]
441         pxor    0x50($key),@x[5]
442         pshufb  $mask,@x[4]
443         pxor    0x60($key),@x[6]
444         pshufb  $mask,@x[5]
445         pxor    0x70($key),@x[7]
446         pshufb  $mask,@x[6]
447         lea     0x80($key),$key
448         pshufb  $mask,@x[7]
449 ___
450 }
451
452 sub MixColumns {
453 # modified to emit output in order suitable for feeding back to aesenc[last]
454 my @x=@_[0..7];
455 my @t=@_[8..15];
456 $code.=<<___;
457         pshufd  \$0x93, @x[0], @t[0]    # x0 <<< 32
458         pshufd  \$0x93, @x[1], @t[1]
459          pxor   @t[0], @x[0]            # x0 ^ (x0 <<< 32)
460         pshufd  \$0x93, @x[2], @t[2]
461          pxor   @t[1], @x[1]
462         pshufd  \$0x93, @x[3], @t[3]
463          pxor   @t[2], @x[2]
464         pshufd  \$0x93, @x[4], @t[4]
465          pxor   @t[3], @x[3]
466         pshufd  \$0x93, @x[5], @t[5]
467          pxor   @t[4], @x[4]
468         pshufd  \$0x93, @x[6], @t[6]
469          pxor   @t[5], @x[5]
470         pshufd  \$0x93, @x[7], @t[7]
471          pxor   @t[6], @x[6]
472          pxor   @t[7], @x[7]
473
474         pxor    @x[0], @t[1]
475         pxor    @x[7], @t[0]
476         pxor    @x[7], @t[1]
477          pshufd \$0x4E, @x[0], @x[0]    # (x0 ^ (x0 <<< 32)) <<< 64)
478         pxor    @x[1], @t[2]
479          pshufd \$0x4E, @x[1], @x[1]
480         pxor    @x[4], @t[5]
481          pxor   @t[0], @x[0]
482         pxor    @x[5], @t[6]
483          pxor   @t[1], @x[1]
484         pxor    @x[3], @t[4]
485          pshufd \$0x4E, @x[4], @t[0]
486         pxor    @x[6], @t[7]
487          pshufd \$0x4E, @x[5], @t[1]
488         pxor    @x[2], @t[3]
489          pshufd \$0x4E, @x[3], @x[4]
490         pxor    @x[7], @t[3]
491          pshufd \$0x4E, @x[7], @x[5]
492         pxor    @x[7], @t[4]
493          pshufd \$0x4E, @x[6], @x[3]
494         pxor    @t[4], @t[0]
495          pshufd \$0x4E, @x[2], @x[6]
496         pxor    @t[5], @t[1]
497
498         pxor    @t[3], @x[4]
499         pxor    @t[7], @x[5]
500         pxor    @t[6], @x[3]
501          movdqa @t[0], @x[2]
502         pxor    @t[2], @x[6]
503          movdqa @t[1], @x[7]
504 ___
505 }
506
507 sub InvMixColumns {
508 my @x=@_[0..7];
509 my @t=@_[8..15];
510
511 $code.=<<___;
512         # multiplication by 0x0e
513         pshufd  \$0x93, @x[7], @t[7]
514         movdqa  @x[2], @t[2]
515         pxor    @x[5], @x[7]            # 7 5
516         pxor    @x[5], @x[2]            # 2 5
517         pshufd  \$0x93, @x[0], @t[0]
518         movdqa  @x[5], @t[5]
519         pxor    @x[0], @x[5]            # 5 0           [1]
520         pxor    @x[1], @x[0]            # 0 1
521         pshufd  \$0x93, @x[1], @t[1]
522         pxor    @x[2], @x[1]            # 1 25
523         pxor    @x[6], @x[0]            # 01 6          [2]
524         pxor    @x[3], @x[1]            # 125 3         [4]
525         pshufd  \$0x93, @x[3], @t[3]
526         pxor    @x[0], @x[2]            # 25 016        [3]
527         pxor    @x[7], @x[3]            # 3 75
528         pxor    @x[6], @x[7]            # 75 6          [0]
529         pshufd  \$0x93, @x[6], @t[6]
530         movdqa  @x[4], @t[4]
531         pxor    @x[4], @x[6]            # 6 4
532         pxor    @x[3], @x[4]            # 4 375         [6]
533         pxor    @x[7], @x[3]            # 375 756=36
534         pxor    @t[5], @x[6]            # 64 5          [7]
535         pxor    @t[2], @x[3]            # 36 2
536         pxor    @t[4], @x[3]            # 362 4         [5]
537         pshufd  \$0x93, @t[5], @t[5]
538 ___
539                                         my @y = @x[7,5,0,2,1,3,4,6];
540 $code.=<<___;
541         # multiplication by 0x0b
542         pxor    @y[0], @y[1]
543         pxor    @t[0], @y[0]
544         pxor    @t[1], @y[1]
545         pshufd  \$0x93, @t[2], @t[2]
546         pxor    @t[5], @y[0]
547         pxor    @t[6], @y[1]
548         pxor    @t[7], @y[0]
549         pshufd  \$0x93, @t[4], @t[4]
550         pxor    @t[6], @t[7]            # clobber t[7]
551         pxor    @y[0], @y[1]
552
553         pxor    @t[0], @y[3]
554         pshufd  \$0x93, @t[0], @t[0]
555         pxor    @t[1], @y[2]
556         pxor    @t[1], @y[4]
557         pxor    @t[2], @y[2]
558         pshufd  \$0x93, @t[1], @t[1]
559         pxor    @t[2], @y[3]
560         pxor    @t[2], @y[5]
561         pxor    @t[7], @y[2]
562         pshufd  \$0x93, @t[2], @t[2]
563         pxor    @t[3], @y[3]
564         pxor    @t[3], @y[6]
565         pxor    @t[3], @y[4]
566         pshufd  \$0x93, @t[3], @t[3]
567         pxor    @t[4], @y[7]
568         pxor    @t[4], @y[5]
569         pxor    @t[7], @y[7]
570         pxor    @t[5], @y[3]
571         pxor    @t[4], @y[4]
572         pxor    @t[5], @t[7]            # clobber t[7] even more
573
574         pxor    @t[7], @y[5]
575         pshufd  \$0x93, @t[4], @t[4]
576         pxor    @t[7], @y[6]
577         pxor    @t[7], @y[4]
578
579         pxor    @t[5], @t[7]
580         pshufd  \$0x93, @t[5], @t[5]
581         pxor    @t[6], @t[7]            # restore t[7]
582
583         # multiplication by 0x0d
584         pxor    @y[7], @y[4]
585         pxor    @t[4], @y[7]
586         pshufd  \$0x93, @t[6], @t[6]
587         pxor    @t[0], @y[2]
588         pxor    @t[5], @y[7]
589         pxor    @t[2], @y[2]
590         pshufd  \$0x93, @t[7], @t[7]
591
592         pxor    @y[1], @y[3]
593         pxor    @t[1], @y[1]
594         pxor    @t[0], @y[0]
595         pxor    @t[0], @y[3]
596         pxor    @t[5], @y[1]
597         pxor    @t[5], @y[0]
598         pxor    @t[7], @y[1]
599         pshufd  \$0x93, @t[0], @t[0]
600         pxor    @t[6], @y[0]
601         pxor    @y[1], @y[3]
602         pxor    @t[1], @y[4]
603         pshufd  \$0x93, @t[1], @t[1]
604
605         pxor    @t[7], @y[7]
606         pxor    @t[2], @y[4]
607         pxor    @t[2], @y[5]
608         pshufd  \$0x93, @t[2], @t[2]
609         pxor    @t[6], @y[2]
610         pxor    @t[3], @t[6]            # clobber t[6]
611         pxor    @y[7], @y[4]
612         pxor    @t[6], @y[3]
613
614         pxor    @t[6], @y[6]
615         pxor    @t[5], @y[5]
616         pxor    @t[4], @y[6]
617         pshufd  \$0x93, @t[4], @t[4]
618         pxor    @t[6], @y[5]
619         pxor    @t[7], @y[6]
620         pxor    @t[3], @t[6]            # restore t[6]
621
622         pshufd  \$0x93, @t[5], @t[5]
623         pshufd  \$0x93, @t[6], @t[6]
624         pshufd  \$0x93, @t[7], @t[7]
625         pshufd  \$0x93, @t[3], @t[3]
626
627         # multiplication by 0x09
628         pxor    @y[1], @y[4]
629         pxor    @y[1], @t[1]            # t[1]=y[1]
630         pxor    @t[5], @t[0]            # clobber t[0]
631         pxor    @t[5], @t[1]
632         pxor    @t[0], @y[3]
633         pxor    @y[0], @t[0]            # t[0]=y[0]
634         pxor    @t[6], @t[1]
635         pxor    @t[7], @t[6]            # clobber t[6]
636         pxor    @t[1], @y[4]
637         pxor    @t[4], @y[7]
638         pxor    @y[4], @t[4]            # t[4]=y[4]
639         pxor    @t[3], @y[6]
640         pxor    @y[3], @t[3]            # t[3]=y[3]
641         pxor    @t[2], @y[5]
642         pxor    @y[2], @t[2]            # t[2]=y[2]
643         pxor    @t[7], @t[3]
644         pxor    @y[5], @t[5]            # t[5]=y[5]
645         pxor    @t[6], @t[2]
646         pxor    @t[6], @t[5]
647         pxor    @y[6], @t[6]            # t[6]=y[6]
648         pxor    @y[7], @t[7]            # t[7]=y[7]
649
650         movdqa  @t[0],@XMM[0]
651         movdqa  @t[1],@XMM[1]
652         movdqa  @t[2],@XMM[2]
653         movdqa  @t[3],@XMM[3]
654         movdqa  @t[4],@XMM[4]
655         movdqa  @t[5],@XMM[5]
656         movdqa  @t[6],@XMM[6]
657         movdqa  @t[7],@XMM[7]
658 ___
659 }
660
661 sub aesenc {                            # not used
662 my @b=@_[0..7];
663 my @t=@_[8..15];
664 $code.=<<___;
665         movdqa  0x30($const),@t[0]      # .LSR
666 ___
667         &ShiftRows      (@b,@t[0]);
668         &Sbox           (@b,@t);
669         &MixColumns     (@b[0,1,4,6,3,7,2,5],@t);
670 }
671
672 sub aesenclast {                        # not used
673 my @b=@_[0..7];
674 my @t=@_[8..15];
675 $code.=<<___;
676         movdqa  0x40($const),@t[0]      # .LSRM0
677 ___
678         &ShiftRows      (@b,@t[0]);
679         &Sbox           (@b,@t);
680 $code.=<<___
681         pxor    0x00($key),@b[0]
682         pxor    0x10($key),@b[1]
683         pxor    0x20($key),@b[4]
684         pxor    0x30($key),@b[6]
685         pxor    0x40($key),@b[3]
686         pxor    0x50($key),@b[7]
687         pxor    0x60($key),@b[2]
688         pxor    0x70($key),@b[5]
689 ___
690 }
691
692 sub swapmove {
693 my ($a,$b,$n,$mask,$t)=@_;
694 $code.=<<___;
695         movdqa  $b,$t
696         psrlq   \$$n,$b
697         pxor    $a,$b
698         pand    $mask,$b
699         pxor    $b,$a
700         psllq   \$$n,$b
701         pxor    $t,$b
702 ___
703 }
704 sub swapmove2x {
705 my ($a0,$b0,$a1,$b1,$n,$mask,$t0,$t1)=@_;
706 $code.=<<___;
707         movdqa  $b0,$t0
708         psrlq   \$$n,$b0
709          movdqa $b1,$t1
710          psrlq  \$$n,$b1
711         pxor    $a0,$b0
712          pxor   $a1,$b1
713         pand    $mask,$b0
714          pand   $mask,$b1
715         pxor    $b0,$a0
716         psllq   \$$n,$b0
717          pxor   $b1,$a1
718          psllq  \$$n,$b1
719         pxor    $t0,$b0
720          pxor   $t1,$b1
721 ___
722 }
723
724 sub bitslice {
725 my @x=reverse(@_[0..7]);
726 my ($t0,$t1,$t2,$t3)=@_[8..11];
727 $code.=<<___;
728         movdqa  0x00($const),$t0        # .LBS0
729         movdqa  0x10($const),$t1        # .LBS1
730 ___
731         &swapmove2x(@x[0,1,2,3],1,$t0,$t2,$t3);
732         &swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
733 $code.=<<___;
734         movdqa  0x20($const),$t0        # .LBS2
735 ___
736         &swapmove2x(@x[0,2,1,3],2,$t1,$t2,$t3);
737         &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
738
739         &swapmove2x(@x[0,4,1,5],4,$t0,$t2,$t3);
740         &swapmove2x(@x[2,6,3,7],4,$t0,$t2,$t3);
741 }
742
743 $code.=<<___;
744 .text
745
746 .extern AES_encrypt
747 .extern AES_decrypt
748
749 .type   _bsaes_encrypt8,\@abi-omnipotent
750 .align  64
751 _bsaes_encrypt8:
752         lea     .LBS0(%rip), $const     # constants table
753
754         movdqa  ($key), @XMM[9]         # round 0 key
755         lea     0x10($key), $key
756         movdqa  0x60($const), @XMM[8]   # .LM0SR
757         pxor    @XMM[9], @XMM[0]        # xor with round0 key
758         pxor    @XMM[9], @XMM[1]
759          pshufb @XMM[8], @XMM[0]
760         pxor    @XMM[9], @XMM[2]
761          pshufb @XMM[8], @XMM[1]
762         pxor    @XMM[9], @XMM[3]
763          pshufb @XMM[8], @XMM[2]
764         pxor    @XMM[9], @XMM[4]
765          pshufb @XMM[8], @XMM[3]
766         pxor    @XMM[9], @XMM[5]
767          pshufb @XMM[8], @XMM[4]
768         pxor    @XMM[9], @XMM[6]
769          pshufb @XMM[8], @XMM[5]
770         pxor    @XMM[9], @XMM[7]
771          pshufb @XMM[8], @XMM[6]
772          pshufb @XMM[8], @XMM[7]
773 _bsaes_encrypt8_bitslice:
774 ___
775         &bitslice       (@XMM[0..7, 8..11]);
776 $code.=<<___;
777         dec     $rounds
778         jmp     .Lenc_sbox
779 .align  16
780 .Lenc_loop:
781 ___
782         &ShiftRows      (@XMM[0..7, 8]);
783 $code.=".Lenc_sbox:\n";
784         &Sbox           (@XMM[0..7, 8..15]);
785 $code.=<<___;
786         dec     $rounds
787         jl      .Lenc_done
788 ___
789         &MixColumns     (@XMM[0,1,4,6,3,7,2,5, 8..15]);
790 $code.=<<___;
791         movdqa  0x30($const), @XMM[8]   # .LSR
792         jnz     .Lenc_loop
793         movdqa  0x40($const), @XMM[8]   # .LSRM0
794         jmp     .Lenc_loop
795 .align  16
796 .Lenc_done:
797 ___
798         # output in lsb > [t0, t1, t4, t6, t3, t7, t2, t5] < msb
799         &bitslice       (@XMM[0,1,4,6,3,7,2,5, 8..11]);
800 $code.=<<___;
801         movdqa  ($key), @XMM[8]         # last round key
802         pxor    @XMM[8], @XMM[4]
803         pxor    @XMM[8], @XMM[6]
804         pxor    @XMM[8], @XMM[3]
805         pxor    @XMM[8], @XMM[7]
806         pxor    @XMM[8], @XMM[2]
807         pxor    @XMM[8], @XMM[5]
808         pxor    @XMM[8], @XMM[0]
809         pxor    @XMM[8], @XMM[1]
810         ret
811 .size   _bsaes_encrypt8,.-_bsaes_encrypt8
812
813 .type   _bsaes_decrypt8,\@abi-omnipotent
814 .align  64
815 _bsaes_decrypt8:
816         lea     .LBS0(%rip), $const     # constants table
817
818         movdqa  ($key), @XMM[9]         # round 0 key
819         lea     0x10($key), $key
820         movdqa  -0x30($const), @XMM[8]  # .LM0ISR
821         pxor    @XMM[9], @XMM[0]        # xor with round0 key
822         pxor    @XMM[9], @XMM[1]
823          pshufb @XMM[8], @XMM[0]
824         pxor    @XMM[9], @XMM[2]
825          pshufb @XMM[8], @XMM[1]
826         pxor    @XMM[9], @XMM[3]
827          pshufb @XMM[8], @XMM[2]
828         pxor    @XMM[9], @XMM[4]
829          pshufb @XMM[8], @XMM[3]
830         pxor    @XMM[9], @XMM[5]
831          pshufb @XMM[8], @XMM[4]
832         pxor    @XMM[9], @XMM[6]
833          pshufb @XMM[8], @XMM[5]
834         pxor    @XMM[9], @XMM[7]
835          pshufb @XMM[8], @XMM[6]
836          pshufb @XMM[8], @XMM[7]
837 ___
838         &bitslice       (@XMM[0..7, 8..11]);
839 $code.=<<___;
840         dec     $rounds
841         jmp     .Ldec_sbox
842 .align  16
843 .Ldec_loop:
844 ___
845         &ShiftRows      (@XMM[0..7, 8]);
846 $code.=".Ldec_sbox:\n";
847         &InvSbox        (@XMM[0..7, 8..15]);
848 $code.=<<___;
849         dec     $rounds
850         jl      .Ldec_done
851 ___
852         &InvMixColumns  (@XMM[0,1,6,4,2,7,3,5, 8..15]);
853 $code.=<<___;
854         movdqa  -0x10($const), @XMM[8]  # .LISR
855         jnz     .Ldec_loop
856         movdqa  -0x20($const), @XMM[8]  # .LISRM0
857         jmp     .Ldec_loop
858 .align  16
859 .Ldec_done:
860 ___
861         &bitslice       (@XMM[0,1,6,4,2,7,3,5, 8..11]);
862 $code.=<<___;
863         movdqa  ($key), @XMM[8]         # last round key
864         pxor    @XMM[8], @XMM[6]
865         pxor    @XMM[8], @XMM[4]
866         pxor    @XMM[8], @XMM[2]
867         pxor    @XMM[8], @XMM[7]
868         pxor    @XMM[8], @XMM[3]
869         pxor    @XMM[8], @XMM[5]
870         pxor    @XMM[8], @XMM[0]
871         pxor    @XMM[8], @XMM[1]
872         ret
873 .size   _bsaes_decrypt8,.-_bsaes_decrypt8
874 ___
875 }
876 {
877 my ($out,$inp,$rounds,$const)=("%rax","%rcx","%r10d","%r11");
878
879 sub bitslice_key {
880 my @x=reverse(@_[0..7]);
881 my ($bs0,$bs1,$bs2,$t2,$t3)=@_[8..12];
882
883         &swapmove       (@x[0,1],1,$bs0,$t2,$t3);
884 $code.=<<___;
885         #&swapmove(@x[2,3],1,$t0,$t2,$t3);
886         movdqa  @x[0], @x[2]
887         movdqa  @x[1], @x[3]
888 ___
889         #&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3);
890
891         &swapmove2x     (@x[0,2,1,3],2,$bs1,$t2,$t3);
892 $code.=<<___;
893         #&swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3);
894         movdqa  @x[0], @x[4]
895         movdqa  @x[2], @x[6]
896         movdqa  @x[1], @x[5]
897         movdqa  @x[3], @x[7]
898 ___
899         &swapmove2x     (@x[0,4,1,5],4,$bs2,$t2,$t3);
900         &swapmove2x     (@x[2,6,3,7],4,$bs2,$t2,$t3);
901 }
902
903 $code.=<<___;
904 .type   _bsaes_key_convert,\@abi-omnipotent
905 .align  16
906 _bsaes_key_convert:
907         lea     .LBS1(%rip), $const
908         movdqu  ($inp), %xmm7           # load round 0 key
909         movdqa  -0x10($const), %xmm8    # .LBS0
910         movdqa  0x00($const), %xmm9     # .LBS1
911         movdqa  0x10($const), %xmm10    # .LBS2
912         movdqa  0x40($const), %xmm13    # .LM0
913         movdqa  0x60($const), %xmm14    # .LNOT
914
915         movdqu  0x10($inp), %xmm6       # load round 1 key
916         lea     0x10($inp), $inp
917         movdqa  %xmm7, ($out)           # save round 0 key
918         lea     0x10($out), $out
919         dec     $rounds
920         jmp     .Lkey_loop
921 .align  16
922 .Lkey_loop:
923         pshufb  %xmm13, %xmm6           # .LM0
924         movdqa  %xmm6, %xmm7
925 ___
926         &bitslice_key   (map("%xmm$_",(0..7, 8..12)));
927 $code.=<<___;
928         pxor    %xmm14, %xmm5           # "pnot"
929         pxor    %xmm14, %xmm6
930         pxor    %xmm14, %xmm0
931         pxor    %xmm14, %xmm1
932         lea     0x10($inp), $inp
933         movdqa  %xmm0, 0x00($out)       # write bit-sliced round key
934         movdqa  %xmm1, 0x10($out)
935         movdqa  %xmm2, 0x20($out)
936         movdqa  %xmm3, 0x30($out)
937         movdqa  %xmm4, 0x40($out)
938         movdqa  %xmm5, 0x50($out)
939         movdqa  %xmm6, 0x60($out)
940         movdqa  %xmm7, 0x70($out)
941         lea     0x80($out),$out
942         movdqu  ($inp), %xmm6           # load next round key
943         dec     $rounds
944         jnz     .Lkey_loop
945
946         movdqa  0x70($const), %xmm7     # .L63
947         #movdqa %xmm6, ($out)           # don't save last round key
948         ret
949 .size   _bsaes_key_convert,.-_bsaes_key_convert
950 ___
951 }
952
953 if (1 && !$win64) {     # following four functions are unsupported interface
954                         # used for benchmarking...
955 $code.=<<___;
956 .globl  bsaes_enc_key_convert
957 .type   bsaes_enc_key_convert,\@function,2
958 .align  16
959 bsaes_enc_key_convert:
960         mov     240($inp),%r10d         # pass rounds
961         mov     $inp,%rcx               # pass key
962         mov     $out,%rax               # pass key schedule
963         call    _bsaes_key_convert
964         pxor    %xmm6,%xmm7             # fix up last round key
965         movdqa  %xmm7,(%rax)            # save last round key
966         ret
967 .size   bsaes_enc_key_convert,.-bsaes_enc_key_convert
968
969 .globl  bsaes_encrypt_128
970 .type   bsaes_encrypt_128,\@function,4
971 .align  16
972 bsaes_encrypt_128:
973 .Lenc128_loop:
974         movdqu  0x00($inp), @XMM[0]     # load input
975         movdqu  0x10($inp), @XMM[1]
976         movdqu  0x20($inp), @XMM[2]
977         movdqu  0x30($inp), @XMM[3]
978         movdqu  0x40($inp), @XMM[4]
979         movdqu  0x50($inp), @XMM[5]
980         movdqu  0x60($inp), @XMM[6]
981         movdqu  0x70($inp), @XMM[7]
982         mov     $key, %rax              # pass the $key
983         lea     0x80($inp), $inp
984         mov     \$10,%r10d
985
986         call    _bsaes_encrypt8
987
988         movdqu  @XMM[0], 0x00($out)     # write output
989         movdqu  @XMM[1], 0x10($out)
990         movdqu  @XMM[4], 0x20($out)
991         movdqu  @XMM[6], 0x30($out)
992         movdqu  @XMM[3], 0x40($out)
993         movdqu  @XMM[7], 0x50($out)
994         movdqu  @XMM[2], 0x60($out)
995         movdqu  @XMM[5], 0x70($out)
996         lea     0x80($out), $out
997         sub     \$0x80,$len
998         ja      .Lenc128_loop
999         ret
1000 .size   bsaes_encrypt_128,.-bsaes_encrypt_128
1001
1002 .globl  bsaes_dec_key_convert
1003 .type   bsaes_dec_key_convert,\@function,2
1004 .align  16
1005 bsaes_dec_key_convert:
1006         mov     240($inp),%r10d         # pass rounds
1007         mov     $inp,%rcx               # pass key
1008         mov     $out,%rax               # pass key schedule
1009         call    _bsaes_key_convert
1010         pxor    ($out),%xmm7            # fix up round 0 key
1011         movdqa  %xmm6,(%rax)            # save last round key
1012         movdqa  %xmm7,($out)
1013         ret
1014 .size   bsaes_dec_key_convert,.-bsaes_dec_key_convert
1015
1016 .globl  bsaes_decrypt_128
1017 .type   bsaes_decrypt_128,\@function,4
1018 .align  16
1019 bsaes_decrypt_128:
1020 .Ldec128_loop:
1021         movdqu  0x00($inp), @XMM[0]     # load input
1022         movdqu  0x10($inp), @XMM[1]
1023         movdqu  0x20($inp), @XMM[2]
1024         movdqu  0x30($inp), @XMM[3]
1025         movdqu  0x40($inp), @XMM[4]
1026         movdqu  0x50($inp), @XMM[5]
1027         movdqu  0x60($inp), @XMM[6]
1028         movdqu  0x70($inp), @XMM[7]
1029         mov     $key, %rax              # pass the $key
1030         lea     0x80($inp), $inp
1031         mov     \$10,%r10d
1032
1033         call    _bsaes_decrypt8
1034
1035         movdqu  @XMM[0], 0x00($out)     # write output
1036         movdqu  @XMM[1], 0x10($out)
1037         movdqu  @XMM[6], 0x20($out)
1038         movdqu  @XMM[4], 0x30($out)
1039         movdqu  @XMM[2], 0x40($out)
1040         movdqu  @XMM[7], 0x50($out)
1041         movdqu  @XMM[3], 0x60($out)
1042         movdqu  @XMM[5], 0x70($out)
1043         lea     0x80($out), $out
1044         sub     \$0x80,$len
1045         ja      .Ldec128_loop
1046         ret
1047 .size   bsaes_decrypt_128,.-bsaes_decrypt_128
1048 ___
1049 }
1050 {
1051 ######################################################################
1052 #
1053 # OpenSSL interface
1054 #
1055 my ($arg1,$arg2,$arg3,$arg4,$arg5,$arg6)=$win64 ? ("%rcx","%rdx","%r8","%r9","%r10","%r11d")
1056                                                 : ("%rdi","%rsi","%rdx","%rcx","%r8","%r9d");
1057 my ($inp,$out,$len,$key)=("%r12","%r13","%r14","%r15");
1058
1059 if (0) {        # suppress unreferenced ECB subroutines, spare some space...
1060 $code.=<<___;
1061 .globl  bsaes_ecb_encrypt_blocks
1062 .type   bsaes_ecb_encrypt_blocks,\@abi-omnipotent
1063 .align  16
1064 bsaes_ecb_encrypt_blocks:
1065         push    %rbp
1066         push    %rbx
1067         push    %r12
1068         push    %r13
1069         push    %r14
1070         push    %r15
1071         lea     -0x48(%rsp),%rsp
1072 ___
1073 $code.=<<___ if ($win64);
1074         lea     -0xa0(%rsp), %rsp
1075         movaps  %xmm6, 0x40(%rsp)
1076         movaps  %xmm7, 0x50(%rsp)
1077         movaps  %xmm8, 0x60(%rsp)
1078         movaps  %xmm9, 0x70(%rsp)
1079         movaps  %xmm10, 0x80(%rsp)
1080         movaps  %xmm11, 0x90(%rsp)
1081         movaps  %xmm12, 0xa0(%rsp)
1082         movaps  %xmm13, 0xb0(%rsp)
1083         movaps  %xmm14, 0xc0(%rsp)
1084         movaps  %xmm15, 0xd0(%rsp)
1085 .Lecb_enc_body:
1086 ___
1087 $code.=<<___;
1088         mov     %rsp,%rbp               # backup %rsp
1089         mov     240($arg4),%eax         # rounds
1090         mov     $arg1,$inp              # backup arguments
1091         mov     $arg2,$out
1092         mov     $arg3,$len
1093         mov     $arg4,$key
1094         cmp     \$8,$arg3
1095         jb      .Lecb_enc_short
1096
1097         mov     %eax,%ebx               # backup rounds
1098         shl     \$7,%rax                # 128 bytes per inner round key
1099         sub     \$`128-32`,%rax         # size of bit-sliced key schedule
1100         sub     %rax,%rsp
1101         mov     %rsp,%rax               # pass key schedule
1102         mov     $key,%rcx               # pass key
1103         mov     %ebx,%r10d              # pass rounds
1104         call    _bsaes_key_convert
1105         pxor    %xmm6,%xmm7             # fix up last round key
1106         movdqa  %xmm7,(%rax)            # save last round key
1107
1108         sub     \$8,$len
1109 .Lecb_enc_loop:
1110         movdqu  0x00($inp), @XMM[0]     # load input
1111         movdqu  0x10($inp), @XMM[1]
1112         movdqu  0x20($inp), @XMM[2]
1113         movdqu  0x30($inp), @XMM[3]
1114         movdqu  0x40($inp), @XMM[4]
1115         movdqu  0x50($inp), @XMM[5]
1116         mov     %rsp, %rax              # pass key schedule
1117         movdqu  0x60($inp), @XMM[6]
1118         mov     %ebx,%r10d              # pass rounds
1119         movdqu  0x70($inp), @XMM[7]
1120         lea     0x80($inp), $inp
1121
1122         call    _bsaes_encrypt8
1123
1124         movdqu  @XMM[0], 0x00($out)     # write output
1125         movdqu  @XMM[1], 0x10($out)
1126         movdqu  @XMM[4], 0x20($out)
1127         movdqu  @XMM[6], 0x30($out)
1128         movdqu  @XMM[3], 0x40($out)
1129         movdqu  @XMM[7], 0x50($out)
1130         movdqu  @XMM[2], 0x60($out)
1131         movdqu  @XMM[5], 0x70($out)
1132         lea     0x80($out), $out
1133         sub     \$8,$len
1134         jnc     .Lecb_enc_loop
1135
1136         add     \$8,$len
1137         jz      .Lecb_enc_done
1138
1139         movdqu  0x00($inp), @XMM[0]     # load input
1140         mov     %rsp, %rax              # pass key schedule
1141         mov     %ebx,%r10d              # pass rounds
1142         cmp     \$2,$len
1143         jb      .Lecb_enc_one
1144         movdqu  0x10($inp), @XMM[1]
1145         je      .Lecb_enc_two
1146         movdqu  0x20($inp), @XMM[2]
1147         cmp     \$4,$len
1148         jb      .Lecb_enc_three
1149         movdqu  0x30($inp), @XMM[3]
1150         je      .Lecb_enc_four
1151         movdqu  0x40($inp), @XMM[4]
1152         cmp     \$6,$len
1153         jb      .Lecb_enc_five
1154         movdqu  0x50($inp), @XMM[5]
1155         je      .Lecb_enc_six
1156         movdqu  0x60($inp), @XMM[6]
1157         call    _bsaes_encrypt8
1158         movdqu  @XMM[0], 0x00($out)     # write output
1159         movdqu  @XMM[1], 0x10($out)
1160         movdqu  @XMM[4], 0x20($out)
1161         movdqu  @XMM[6], 0x30($out)
1162         movdqu  @XMM[3], 0x40($out)
1163         movdqu  @XMM[7], 0x50($out)
1164         movdqu  @XMM[2], 0x60($out)
1165         jmp     .Lecb_enc_done
1166 .align  16
1167 .Lecb_enc_six:
1168         call    _bsaes_encrypt8
1169         movdqu  @XMM[0], 0x00($out)     # write output
1170         movdqu  @XMM[1], 0x10($out)
1171         movdqu  @XMM[4], 0x20($out)
1172         movdqu  @XMM[6], 0x30($out)
1173         movdqu  @XMM[3], 0x40($out)
1174         movdqu  @XMM[7], 0x50($out)
1175         jmp     .Lecb_enc_done
1176 .align  16
1177 .Lecb_enc_five:
1178         call    _bsaes_encrypt8
1179         movdqu  @XMM[0], 0x00($out)     # write output
1180         movdqu  @XMM[1], 0x10($out)
1181         movdqu  @XMM[4], 0x20($out)
1182         movdqu  @XMM[6], 0x30($out)
1183         movdqu  @XMM[3], 0x40($out)
1184         jmp     .Lecb_enc_done
1185 .align  16
1186 .Lecb_enc_four:
1187         call    _bsaes_encrypt8
1188         movdqu  @XMM[0], 0x00($out)     # write output
1189         movdqu  @XMM[1], 0x10($out)
1190         movdqu  @XMM[4], 0x20($out)
1191         movdqu  @XMM[6], 0x30($out)
1192         jmp     .Lecb_enc_done
1193 .align  16
1194 .Lecb_enc_three:
1195         call    _bsaes_encrypt8
1196         movdqu  @XMM[0], 0x00($out)     # write output
1197         movdqu  @XMM[1], 0x10($out)
1198         movdqu  @XMM[4], 0x20($out)
1199         jmp     .Lecb_enc_done
1200 .align  16
1201 .Lecb_enc_two:
1202         call    _bsaes_encrypt8
1203         movdqu  @XMM[0], 0x00($out)     # write output
1204         movdqu  @XMM[1], 0x10($out)
1205         jmp     .Lecb_enc_done
1206 .align  16
1207 .Lecb_enc_one:
1208         call    _bsaes_encrypt8
1209         movdqu  @XMM[0], 0x00($out)     # write output
1210         jmp     .Lecb_enc_done
1211 .align  16
1212 .Lecb_enc_short:
1213         lea     ($inp), $arg1
1214         lea     ($out), $arg2
1215         lea     ($key), $arg3
1216         call    AES_encrypt
1217         lea     16($inp), $inp
1218         lea     16($out), $out
1219         dec     $len
1220         jnz     .Lecb_enc_short
1221
1222 .Lecb_enc_done:
1223         lea     (%rsp),%rax
1224         pxor    %xmm0, %xmm0
1225 .Lecb_enc_bzero:                        # wipe key schedule [if any]
1226         movdqa  %xmm0, 0x00(%rax)
1227         movdqa  %xmm0, 0x10(%rax)
1228         lea     0x20(%rax), %rax
1229         cmp     %rax, %rbp
1230         jb      .Lecb_enc_bzero
1231
1232         lea     (%rbp),%rsp             # restore %rsp
1233 ___
1234 $code.=<<___ if ($win64);
1235         movaps  0x40(%rbp), %xmm6
1236         movaps  0x50(%rbp), %xmm7
1237         movaps  0x60(%rbp), %xmm8
1238         movaps  0x70(%rbp), %xmm9
1239         movaps  0x80(%rbp), %xmm10
1240         movaps  0x90(%rbp), %xmm11
1241         movaps  0xa0(%rbp), %xmm12
1242         movaps  0xb0(%rbp), %xmm13
1243         movaps  0xc0(%rbp), %xmm14
1244         movaps  0xd0(%rbp), %xmm15
1245         lea     0xa0(%rbp), %rsp
1246 ___
1247 $code.=<<___;
1248         mov     0x48(%rsp), %r15
1249         mov     0x50(%rsp), %r14
1250         mov     0x58(%rsp), %r13
1251         mov     0x60(%rsp), %r12
1252         mov     0x68(%rsp), %rbx
1253         mov     0x70(%rsp), %rbp
1254         lea     0x78(%rsp), %rsp
1255 .Lecb_enc_epilogue:
1256         ret
1257 .size   bsaes_ecb_encrypt_blocks,.-bsaes_ecb_encrypt_blocks
1258
1259 .globl  bsaes_ecb_decrypt_blocks
1260 .type   bsaes_ecb_decrypt_blocks,\@abi-omnipotent
1261 .align  16
1262 bsaes_ecb_decrypt_blocks:
1263         push    %rbp
1264         push    %rbx
1265         push    %r12
1266         push    %r13
1267         push    %r14
1268         push    %r15
1269         lea     -0x48(%rsp),%rsp
1270 ___
1271 $code.=<<___ if ($win64);
1272         lea     -0xa0(%rsp), %rsp
1273         movaps  %xmm6, 0x40(%rsp)
1274         movaps  %xmm7, 0x50(%rsp)
1275         movaps  %xmm8, 0x60(%rsp)
1276         movaps  %xmm9, 0x70(%rsp)
1277         movaps  %xmm10, 0x80(%rsp)
1278         movaps  %xmm11, 0x90(%rsp)
1279         movaps  %xmm12, 0xa0(%rsp)
1280         movaps  %xmm13, 0xb0(%rsp)
1281         movaps  %xmm14, 0xc0(%rsp)
1282         movaps  %xmm15, 0xd0(%rsp)
1283 .Lecb_dec_body:
1284 ___
1285 $code.=<<___;
1286         mov     %rsp,%rbp               # backup %rsp
1287         mov     240($arg4),%eax         # rounds
1288         mov     $arg1,$inp              # backup arguments
1289         mov     $arg2,$out
1290         mov     $arg3,$len
1291         mov     $arg4,$key
1292         cmp     \$8,$arg3
1293         jb      .Lecb_dec_short
1294
1295         mov     %eax,%ebx               # backup rounds
1296         shl     \$7,%rax                # 128 bytes per inner round key
1297         sub     \$`128-32`,%rax         # size of bit-sliced key schedule
1298         sub     %rax,%rsp
1299         mov     %rsp,%rax               # pass key schedule
1300         mov     $key,%rcx               # pass key
1301         mov     %ebx,%r10d              # pass rounds
1302         call    _bsaes_key_convert
1303         pxor    (%rsp),%xmm7            # fix up 0 round key
1304         movdqa  %xmm6,(%rax)            # save last round key
1305         movdqa  %xmm7,(%rsp)
1306
1307         sub     \$8,$len
1308 .Lecb_dec_loop:
1309         movdqu  0x00($inp), @XMM[0]     # load input
1310         movdqu  0x10($inp), @XMM[1]
1311         movdqu  0x20($inp), @XMM[2]
1312         movdqu  0x30($inp), @XMM[3]
1313         movdqu  0x40($inp), @XMM[4]
1314         movdqu  0x50($inp), @XMM[5]
1315         mov     %rsp, %rax              # pass key schedule
1316         movdqu  0x60($inp), @XMM[6]
1317         mov     %ebx,%r10d              # pass rounds
1318         movdqu  0x70($inp), @XMM[7]
1319         lea     0x80($inp), $inp
1320
1321         call    _bsaes_decrypt8
1322
1323         movdqu  @XMM[0], 0x00($out)     # write output
1324         movdqu  @XMM[1], 0x10($out)
1325         movdqu  @XMM[6], 0x20($out)
1326         movdqu  @XMM[4], 0x30($out)
1327         movdqu  @XMM[2], 0x40($out)
1328         movdqu  @XMM[7], 0x50($out)
1329         movdqu  @XMM[3], 0x60($out)
1330         movdqu  @XMM[5], 0x70($out)
1331         lea     0x80($out), $out
1332         sub     \$8,$len
1333         jnc     .Lecb_dec_loop
1334
1335         add     \$8,$len
1336         jz      .Lecb_dec_done
1337
1338         movdqu  0x00($inp), @XMM[0]     # load input
1339         mov     %rsp, %rax              # pass key schedule
1340         mov     %ebx,%r10d              # pass rounds
1341         cmp     \$2,$len
1342         jb      .Lecb_dec_one
1343         movdqu  0x10($inp), @XMM[1]
1344         je      .Lecb_dec_two
1345         movdqu  0x20($inp), @XMM[2]
1346         cmp     \$4,$len
1347         jb      .Lecb_dec_three
1348         movdqu  0x30($inp), @XMM[3]
1349         je      .Lecb_dec_four
1350         movdqu  0x40($inp), @XMM[4]
1351         cmp     \$6,$len
1352         jb      .Lecb_dec_five
1353         movdqu  0x50($inp), @XMM[5]
1354         je      .Lecb_dec_six
1355         movdqu  0x60($inp), @XMM[6]
1356         call    _bsaes_decrypt8
1357         movdqu  @XMM[0], 0x00($out)     # write output
1358         movdqu  @XMM[1], 0x10($out)
1359         movdqu  @XMM[6], 0x20($out)
1360         movdqu  @XMM[4], 0x30($out)
1361         movdqu  @XMM[2], 0x40($out)
1362         movdqu  @XMM[7], 0x50($out)
1363         movdqu  @XMM[3], 0x60($out)
1364         jmp     .Lecb_dec_done
1365 .align  16
1366 .Lecb_dec_six:
1367         call    _bsaes_decrypt8
1368         movdqu  @XMM[0], 0x00($out)     # write output
1369         movdqu  @XMM[1], 0x10($out)
1370         movdqu  @XMM[6], 0x20($out)
1371         movdqu  @XMM[4], 0x30($out)
1372         movdqu  @XMM[2], 0x40($out)
1373         movdqu  @XMM[7], 0x50($out)
1374         jmp     .Lecb_dec_done
1375 .align  16
1376 .Lecb_dec_five:
1377         call    _bsaes_decrypt8
1378         movdqu  @XMM[0], 0x00($out)     # write output
1379         movdqu  @XMM[1], 0x10($out)
1380         movdqu  @XMM[6], 0x20($out)
1381         movdqu  @XMM[4], 0x30($out)
1382         movdqu  @XMM[2], 0x40($out)
1383         jmp     .Lecb_dec_done
1384 .align  16
1385 .Lecb_dec_four:
1386         call    _bsaes_decrypt8
1387         movdqu  @XMM[0], 0x00($out)     # write output
1388         movdqu  @XMM[1], 0x10($out)
1389         movdqu  @XMM[6], 0x20($out)
1390         movdqu  @XMM[4], 0x30($out)
1391         jmp     .Lecb_dec_done
1392 .align  16
1393 .Lecb_dec_three:
1394         call    _bsaes_decrypt8
1395         movdqu  @XMM[0], 0x00($out)     # write output
1396         movdqu  @XMM[1], 0x10($out)
1397         movdqu  @XMM[6], 0x20($out)
1398         jmp     .Lecb_dec_done
1399 .align  16
1400 .Lecb_dec_two:
1401         call    _bsaes_decrypt8
1402         movdqu  @XMM[0], 0x00($out)     # write output
1403         movdqu  @XMM[1], 0x10($out)
1404         jmp     .Lecb_dec_done
1405 .align  16
1406 .Lecb_dec_one:
1407         call    _bsaes_decrypt8
1408         movdqu  @XMM[0], 0x00($out)     # write output
1409         jmp     .Lecb_dec_done
1410 .align  16
1411 .Lecb_dec_short:
1412         lea     ($inp), $arg1
1413         lea     ($out), $arg2
1414         lea     ($key), $arg3
1415         call    AES_decrypt
1416         lea     16($inp), $inp
1417         lea     16($out), $out
1418         dec     $len
1419         jnz     .Lecb_dec_short
1420
1421 .Lecb_dec_done:
1422         lea     (%rsp),%rax
1423         pxor    %xmm0, %xmm0
1424 .Lecb_dec_bzero:                        # wipe key schedule [if any]
1425         movdqa  %xmm0, 0x00(%rax)
1426         movdqa  %xmm0, 0x10(%rax)
1427         lea     0x20(%rax), %rax
1428         cmp     %rax, %rbp
1429         jb      .Lecb_dec_bzero
1430
1431         lea     (%rbp),%rsp             # restore %rsp
1432 ___
1433 $code.=<<___ if ($win64);
1434         movaps  0x40(%rbp), %xmm6
1435         movaps  0x50(%rbp), %xmm7
1436         movaps  0x60(%rbp), %xmm8
1437         movaps  0x70(%rbp), %xmm9
1438         movaps  0x80(%rbp), %xmm10
1439         movaps  0x90(%rbp), %xmm11
1440         movaps  0xa0(%rbp), %xmm12
1441         movaps  0xb0(%rbp), %xmm13
1442         movaps  0xc0(%rbp), %xmm14
1443         movaps  0xd0(%rbp), %xmm15
1444         lea     0xa0(%rbp), %rsp
1445 ___
1446 $code.=<<___;
1447         mov     0x48(%rsp), %r15
1448         mov     0x50(%rsp), %r14
1449         mov     0x58(%rsp), %r13
1450         mov     0x60(%rsp), %r12
1451         mov     0x68(%rsp), %rbx
1452         mov     0x70(%rsp), %rbp
1453         lea     0x78(%rsp), %rsp
1454 .Lecb_dec_epilogue:
1455         ret
1456 .size   bsaes_ecb_decrypt_blocks,.-bsaes_ecb_decrypt_blocks
1457 ___
1458 }
1459 $code.=<<___;
1460 .extern AES_cbc_encrypt
1461 .globl  bsaes_cbc_encrypt
1462 .type   bsaes_cbc_encrypt,\@abi-omnipotent
1463 .align  16
1464 bsaes_cbc_encrypt:
1465 ___
1466 $code.=<<___ if ($win64);
1467         mov     48(%rsp),$arg6          # pull direction flag
1468 ___
1469 $code.=<<___;
1470         cmp     \$0,$arg6
1471         jne     AES_cbc_encrypt
1472         cmp     \$128,$arg3
1473         jb      AES_cbc_encrypt
1474
1475         push    %rbp
1476         push    %rbx
1477         push    %r12
1478         push    %r13
1479         push    %r14
1480         push    %r15
1481         lea     -0x48(%rsp), %rsp
1482 ___
1483 $code.=<<___ if ($win64);
1484         mov     0xa0(%rsp),$arg5        # pull ivp
1485         lea     -0xa0(%rsp), %rsp
1486         movaps  %xmm6, 0x40(%rsp)
1487         movaps  %xmm7, 0x50(%rsp)
1488         movaps  %xmm8, 0x60(%rsp)
1489         movaps  %xmm9, 0x70(%rsp)
1490         movaps  %xmm10, 0x80(%rsp)
1491         movaps  %xmm11, 0x90(%rsp)
1492         movaps  %xmm12, 0xa0(%rsp)
1493         movaps  %xmm13, 0xb0(%rsp)
1494         movaps  %xmm14, 0xc0(%rsp)
1495         movaps  %xmm15, 0xd0(%rsp)
1496 .Lcbc_dec_body:
1497 ___
1498 $code.=<<___;
1499         mov     %rsp, %rbp              # backup %rsp
1500         mov     240($arg4), %eax        # rounds
1501         mov     $arg1, $inp             # backup arguments
1502         mov     $arg2, $out
1503         mov     $arg3, $len
1504         mov     $arg4, $key
1505         mov     $arg5, %rbx
1506         shr     \$4, $len               # bytes to blocks
1507
1508         mov     %eax, %edx              # rounds
1509         shl     \$7, %rax               # 128 bytes per inner round key
1510         sub     \$`128-32`, %rax        # size of bit-sliced key schedule
1511         sub     %rax, %rsp
1512
1513         mov     %rsp, %rax              # pass key schedule
1514         mov     $key, %rcx              # pass key
1515         mov     %edx, %r10d             # pass rounds
1516         call    _bsaes_key_convert
1517         pxor    (%rsp),%xmm7            # fix up 0 round key
1518         movdqa  %xmm6,(%rax)            # save last round key
1519         movdqa  %xmm7,(%rsp)
1520
1521         movdqu  (%rbx), @XMM[15]        # load IV
1522         sub     \$8,$len
1523 .Lcbc_dec_loop:
1524         movdqu  0x00($inp), @XMM[0]     # load input
1525         movdqu  0x10($inp), @XMM[1]
1526         movdqu  0x20($inp), @XMM[2]
1527         movdqu  0x30($inp), @XMM[3]
1528         movdqu  0x40($inp), @XMM[4]
1529         movdqu  0x50($inp), @XMM[5]
1530         mov     %rsp, %rax              # pass key schedule
1531         movdqu  0x60($inp), @XMM[6]
1532         mov     %edx,%r10d              # pass rounds
1533         movdqu  0x70($inp), @XMM[7]
1534         movdqa  @XMM[15], 0x20(%rbp)    # put aside IV
1535
1536         call    _bsaes_decrypt8
1537
1538         pxor    0x20(%rbp), @XMM[0]     # ^= IV
1539         movdqu  0x00($inp), @XMM[8]     # re-load input
1540         movdqu  0x10($inp), @XMM[9]
1541         pxor    @XMM[8], @XMM[1]
1542         movdqu  0x20($inp), @XMM[10]
1543         pxor    @XMM[9], @XMM[6]
1544         movdqu  0x30($inp), @XMM[11]
1545         pxor    @XMM[10], @XMM[4]
1546         movdqu  0x40($inp), @XMM[12]
1547         pxor    @XMM[11], @XMM[2]
1548         movdqu  0x50($inp), @XMM[13]
1549         pxor    @XMM[12], @XMM[7]
1550         movdqu  0x60($inp), @XMM[14]
1551         pxor    @XMM[13], @XMM[3]
1552         movdqu  0x70($inp), @XMM[15]    # IV
1553         pxor    @XMM[14], @XMM[5]
1554         movdqu  @XMM[0], 0x00($out)     # write output
1555         lea     0x80($inp), $inp
1556         movdqu  @XMM[1], 0x10($out)
1557         movdqu  @XMM[6], 0x20($out)
1558         movdqu  @XMM[4], 0x30($out)
1559         movdqu  @XMM[2], 0x40($out)
1560         movdqu  @XMM[7], 0x50($out)
1561         movdqu  @XMM[3], 0x60($out)
1562         movdqu  @XMM[5], 0x70($out)
1563         lea     0x80($out), $out
1564         sub     \$8,$len
1565         jnc     .Lcbc_dec_loop
1566
1567         add     \$8,$len
1568         jz      .Lcbc_dec_done
1569
1570         movdqu  0x00($inp), @XMM[0]     # load input
1571         mov     %rsp, %rax              # pass key schedule
1572         mov     %edx, %r10d             # pass rounds
1573         cmp     \$2,$len
1574         jb      .Lcbc_dec_one
1575         movdqu  0x10($inp), @XMM[1]
1576         je      .Lcbc_dec_two
1577         movdqu  0x20($inp), @XMM[2]
1578         cmp     \$4,$len
1579         jb      .Lcbc_dec_three
1580         movdqu  0x30($inp), @XMM[3]
1581         je      .Lcbc_dec_four
1582         movdqu  0x40($inp), @XMM[4]
1583         cmp     \$6,$len
1584         jb      .Lcbc_dec_five
1585         movdqu  0x50($inp), @XMM[5]
1586         je      .Lcbc_dec_six
1587         movdqu  0x60($inp), @XMM[6]
1588         movdqa  @XMM[15], 0x20(%rbp)    # put aside IV
1589         call    _bsaes_decrypt8
1590         pxor    0x20(%rbp), @XMM[0]     # ^= IV
1591         movdqu  0x00($inp), @XMM[8]     # re-load input
1592         movdqu  0x10($inp), @XMM[9]
1593         pxor    @XMM[8], @XMM[1]
1594         movdqu  0x20($inp), @XMM[10]
1595         pxor    @XMM[9], @XMM[6]
1596         movdqu  0x30($inp), @XMM[11]
1597         pxor    @XMM[10], @XMM[4]
1598         movdqu  0x40($inp), @XMM[12]
1599         pxor    @XMM[11], @XMM[2]
1600         movdqu  0x50($inp), @XMM[13]
1601         pxor    @XMM[12], @XMM[7]
1602         movdqu  0x60($inp), @XMM[15]    # IV
1603         pxor    @XMM[13], @XMM[3]
1604         movdqu  @XMM[0], 0x00($out)     # write output
1605         movdqu  @XMM[1], 0x10($out)
1606         movdqu  @XMM[6], 0x20($out)
1607         movdqu  @XMM[4], 0x30($out)
1608         movdqu  @XMM[2], 0x40($out)
1609         movdqu  @XMM[7], 0x50($out)
1610         movdqu  @XMM[3], 0x60($out)
1611         jmp     .Lcbc_dec_done
1612 .align  16
1613 .Lcbc_dec_six:
1614         movdqa  @XMM[15], 0x20(%rbp)    # put aside IV
1615         call    _bsaes_decrypt8
1616         pxor    0x20(%rbp), @XMM[0]     # ^= IV
1617         movdqu  0x00($inp), @XMM[8]     # re-load input
1618         movdqu  0x10($inp), @XMM[9]
1619         pxor    @XMM[8], @XMM[1]
1620         movdqu  0x20($inp), @XMM[10]
1621         pxor    @XMM[9], @XMM[6]
1622         movdqu  0x30($inp), @XMM[11]
1623         pxor    @XMM[10], @XMM[4]
1624         movdqu  0x40($inp), @XMM[12]
1625         pxor    @XMM[11], @XMM[2]
1626         movdqu  0x50($inp), @XMM[15]    # IV
1627         pxor    @XMM[12], @XMM[7]
1628         movdqu  @XMM[0], 0x00($out)     # write output
1629         movdqu  @XMM[1], 0x10($out)
1630         movdqu  @XMM[6], 0x20($out)
1631         movdqu  @XMM[4], 0x30($out)
1632         movdqu  @XMM[2], 0x40($out)
1633         movdqu  @XMM[7], 0x50($out)
1634         jmp     .Lcbc_dec_done
1635 .align  16
1636 .Lcbc_dec_five:
1637         movdqa  @XMM[15], 0x20(%rbp)    # put aside IV
1638         call    _bsaes_decrypt8
1639         pxor    0x20(%rbp), @XMM[0]     # ^= IV
1640         movdqu  0x00($inp), @XMM[8]     # re-load input
1641         movdqu  0x10($inp), @XMM[9]
1642         pxor    @XMM[8], @XMM[1]
1643         movdqu  0x20($inp), @XMM[10]
1644         pxor    @XMM[9], @XMM[6]
1645         movdqu  0x30($inp), @XMM[11]
1646         pxor    @XMM[10], @XMM[4]
1647         movdqu  0x40($inp), @XMM[15]    # IV
1648         pxor    @XMM[11], @XMM[2]
1649         movdqu  @XMM[0], 0x00($out)     # write output
1650         movdqu  @XMM[1], 0x10($out)
1651         movdqu  @XMM[6], 0x20($out)
1652         movdqu  @XMM[4], 0x30($out)
1653         movdqu  @XMM[2], 0x40($out)
1654         jmp     .Lcbc_dec_done
1655 .align  16
1656 .Lcbc_dec_four:
1657         movdqa  @XMM[15], 0x20(%rbp)    # put aside IV
1658         call    _bsaes_decrypt8
1659         pxor    0x20(%rbp), @XMM[0]     # ^= IV
1660         movdqu  0x00($inp), @XMM[8]     # re-load input
1661         movdqu  0x10($inp), @XMM[9]
1662         pxor    @XMM[8], @XMM[1]
1663         movdqu  0x20($inp), @XMM[10]
1664         pxor    @XMM[9], @XMM[6]
1665         movdqu  0x30($inp), @XMM[15]    # IV
1666         pxor    @XMM[10], @XMM[4]
1667         movdqu  @XMM[0], 0x00($out)     # write output
1668         movdqu  @XMM[1], 0x10($out)
1669         movdqu  @XMM[6], 0x20($out)
1670         movdqu  @XMM[4], 0x30($out)
1671         jmp     .Lcbc_dec_done
1672 .align  16
1673 .Lcbc_dec_three:
1674         movdqa  @XMM[15], 0x20(%rbp)    # put aside IV
1675         call    _bsaes_decrypt8
1676         pxor    0x20(%rbp), @XMM[0]     # ^= IV
1677         movdqu  0x00($inp), @XMM[8]     # re-load input
1678         movdqu  0x10($inp), @XMM[9]
1679         pxor    @XMM[8], @XMM[1]
1680         movdqu  0x20($inp), @XMM[15]    # IV
1681         pxor    @XMM[9], @XMM[6]
1682         movdqu  @XMM[0], 0x00($out)     # write output
1683         movdqu  @XMM[1], 0x10($out)
1684         movdqu  @XMM[6], 0x20($out)
1685         jmp     .Lcbc_dec_done
1686 .align  16
1687 .Lcbc_dec_two:
1688         movdqa  @XMM[15], 0x20(%rbp)    # put aside IV
1689         call    _bsaes_decrypt8
1690         pxor    0x20(%rbp), @XMM[0]     # ^= IV
1691         movdqu  0x00($inp), @XMM[8]     # re-load input
1692         movdqu  0x10($inp), @XMM[15]    # IV
1693         pxor    @XMM[8], @XMM[1]
1694         movdqu  @XMM[0], 0x00($out)     # write output
1695         movdqu  @XMM[1], 0x10($out)
1696         jmp     .Lcbc_dec_done
1697 .align  16
1698 .Lcbc_dec_one:
1699         lea     ($inp), $arg1
1700         lea     0x20(%rbp), $arg2       # buffer output
1701         lea     ($key), $arg3
1702         call    AES_decrypt             # doesn't touch %xmm
1703         pxor    0x20(%rbp), @XMM[15]    # ^= IV
1704         movdqu  @XMM[15], ($out)        # write output
1705         movdqa  @XMM[0], @XMM[15]       # IV
1706
1707 .Lcbc_dec_done:
1708         movdqu  @XMM[15], (%rbx)        # return IV
1709         lea     (%rsp), %rax
1710         pxor    %xmm0, %xmm0
1711 .Lcbc_dec_bzero:                        # wipe key schedule [if any]
1712         movdqa  %xmm0, 0x00(%rax)
1713         movdqa  %xmm0, 0x10(%rax)
1714         lea     0x20(%rax), %rax
1715         cmp     %rax, %rbp
1716         ja      .Lcbc_dec_bzero
1717
1718         lea     (%rbp),%rsp             # restore %rsp
1719 ___
1720 $code.=<<___ if ($win64);
1721         movaps  0x40(%rbp), %xmm6
1722         movaps  0x50(%rbp), %xmm7
1723         movaps  0x60(%rbp), %xmm8
1724         movaps  0x70(%rbp), %xmm9
1725         movaps  0x80(%rbp), %xmm10
1726         movaps  0x90(%rbp), %xmm11
1727         movaps  0xa0(%rbp), %xmm12
1728         movaps  0xb0(%rbp), %xmm13
1729         movaps  0xc0(%rbp), %xmm14
1730         movaps  0xd0(%rbp), %xmm15
1731         lea     0xa0(%rbp), %rsp
1732 ___
1733 $code.=<<___;
1734         mov     0x48(%rsp), %r15
1735         mov     0x50(%rsp), %r14
1736         mov     0x58(%rsp), %r13
1737         mov     0x60(%rsp), %r12
1738         mov     0x68(%rsp), %rbx
1739         mov     0x70(%rsp), %rbp
1740         lea     0x78(%rsp), %rsp
1741 .Lcbc_dec_epilogue:
1742         ret
1743 .size   bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
1744
1745 .globl  bsaes_ctr32_encrypt_blocks
1746 .type   bsaes_ctr32_encrypt_blocks,\@abi-omnipotent
1747 .align  16
1748 bsaes_ctr32_encrypt_blocks:
1749         push    %rbp
1750         push    %rbx
1751         push    %r12
1752         push    %r13
1753         push    %r14
1754         push    %r15
1755         lea     -0x48(%rsp), %rsp
1756 ___
1757 $code.=<<___ if ($win64);
1758         mov     0xa0(%rsp),$arg5        # pull ivp
1759         lea     -0xa0(%rsp), %rsp
1760         movaps  %xmm6, 0x40(%rsp)
1761         movaps  %xmm7, 0x50(%rsp)
1762         movaps  %xmm8, 0x60(%rsp)
1763         movaps  %xmm9, 0x70(%rsp)
1764         movaps  %xmm10, 0x80(%rsp)
1765         movaps  %xmm11, 0x90(%rsp)
1766         movaps  %xmm12, 0xa0(%rsp)
1767         movaps  %xmm13, 0xb0(%rsp)
1768         movaps  %xmm14, 0xc0(%rsp)
1769         movaps  %xmm15, 0xd0(%rsp)
1770 .Lctr_enc_body:
1771 ___
1772 $code.=<<___;
1773         mov     %rsp, %rbp              # backup %rsp
1774         movdqu  ($arg5), %xmm0          # load counter
1775         mov     240($arg4), %eax        # rounds
1776         mov     $arg1, $inp             # backup arguments
1777         mov     $arg2, $out
1778         mov     $arg3, $len
1779         mov     $arg4, $key
1780         movdqa  %xmm0, 0x20(%rbp)       # copy counter
1781         cmp     \$8, $arg3
1782         jb      .Lctr_enc_short
1783
1784         mov     %eax, %ebx              # rounds
1785         shl     \$7, %rax               # 128 bytes per inner round key
1786         sub     \$`128-32`, %rax        # size of bit-sliced key schedule
1787         sub     %rax, %rsp
1788
1789         mov     %rsp, %rax              # pass key schedule
1790         mov     $key, %rcx              # pass key
1791         mov     %ebx, %r10d             # pass rounds
1792         call    _bsaes_key_convert
1793         pxor    %xmm6,%xmm7             # fix up last round key
1794         movdqa  %xmm7,(%rax)            # save last round key
1795
1796         movdqa  (%rsp), @XMM[9]         # load round0 key
1797         lea     .LADD1(%rip), %r11
1798         movdqa  0x20(%rbp), @XMM[0]     # counter copy
1799         movdqa  -0x20(%r11), @XMM[8]    # .LSWPUP
1800         pshufb  @XMM[8], @XMM[9]        # byte swap upper part
1801         pshufb  @XMM[8], @XMM[0]
1802         movdqa  @XMM[9], (%rsp)         # save adjusted round0 key
1803         jmp     .Lctr_enc_loop
1804 .align  16
1805 .Lctr_enc_loop:
1806         movdqa  @XMM[0], 0x20(%rbp)     # save counter
1807         movdqa  @XMM[0], @XMM[1]        # prepare 8 counter values
1808         movdqa  @XMM[0], @XMM[2]
1809         paddd   0x00(%r11), @XMM[1]     # .LADD1
1810         movdqa  @XMM[0], @XMM[3]
1811         paddd   0x10(%r11), @XMM[2]     # .LADD2
1812         movdqa  @XMM[0], @XMM[4]
1813         paddd   0x20(%r11), @XMM[3]     # .LADD3
1814         movdqa  @XMM[0], @XMM[5]
1815         paddd   0x30(%r11), @XMM[4]     # .LADD4
1816         movdqa  @XMM[0], @XMM[6]
1817         paddd   0x40(%r11), @XMM[5]     # .LADD5
1818         movdqa  @XMM[0], @XMM[7]
1819         paddd   0x50(%r11), @XMM[6]     # .LADD6
1820         paddd   0x60(%r11), @XMM[7]     # .LADD7
1821
1822         # Borrow prologue from _bsaes_encrypt8 to use the opportunity
1823         # to flip byte order in 32-bit counter
1824         movdqa  (%rsp), @XMM[9]         # round 0 key
1825         lea     0x10(%rsp), %rax        # pass key schedule
1826         movdqa  -0x10(%r11), @XMM[8]    # .LSWPUPM0SR
1827         pxor    @XMM[9], @XMM[0]        # xor with round0 key
1828         pxor    @XMM[9], @XMM[1]
1829          pshufb @XMM[8], @XMM[0]
1830         pxor    @XMM[9], @XMM[2]
1831          pshufb @XMM[8], @XMM[1]
1832         pxor    @XMM[9], @XMM[3]
1833          pshufb @XMM[8], @XMM[2]
1834         pxor    @XMM[9], @XMM[4]
1835          pshufb @XMM[8], @XMM[3]
1836         pxor    @XMM[9], @XMM[5]
1837          pshufb @XMM[8], @XMM[4]
1838         pxor    @XMM[9], @XMM[6]
1839          pshufb @XMM[8], @XMM[5]
1840         pxor    @XMM[9], @XMM[7]
1841          pshufb @XMM[8], @XMM[6]
1842         lea     .LBS0(%rip), %r11       # constants table
1843          pshufb @XMM[8], @XMM[7]
1844         mov     %ebx,%r10d              # pass rounds
1845
1846         call    _bsaes_encrypt8_bitslice
1847
1848         sub     \$8,$len
1849         jc      .Lctr_enc_loop_done
1850
1851         movdqu  0x00($inp), @XMM[8]     # load input
1852         movdqu  0x10($inp), @XMM[9]
1853         movdqu  0x20($inp), @XMM[10]
1854         movdqu  0x30($inp), @XMM[11]
1855         movdqu  0x40($inp), @XMM[12]
1856         movdqu  0x50($inp), @XMM[13]
1857         movdqu  0x60($inp), @XMM[14]
1858         movdqu  0x70($inp), @XMM[15]
1859         lea     0x80($inp),$inp
1860         pxor    @XMM[0], @XMM[8]
1861         movdqa  0x20(%rbp), @XMM[0]     # load counter
1862         pxor    @XMM[9], @XMM[1]
1863         movdqu  @XMM[8], 0x00($out)     # write output
1864         pxor    @XMM[10], @XMM[4]
1865         movdqu  @XMM[1], 0x10($out)
1866         pxor    @XMM[11], @XMM[6]
1867         movdqu  @XMM[4], 0x20($out)
1868         pxor    @XMM[12], @XMM[3]
1869         movdqu  @XMM[6], 0x30($out)
1870         pxor    @XMM[13], @XMM[7]
1871         movdqu  @XMM[3], 0x40($out)
1872         pxor    @XMM[14], @XMM[2]
1873         movdqu  @XMM[7], 0x50($out)
1874         pxor    @XMM[15], @XMM[5]
1875         movdqu  @XMM[2], 0x60($out)
1876         lea     .LADD1(%rip), %r11
1877         movdqu  @XMM[5], 0x70($out)
1878         lea     0x80($out), $out
1879         paddd   0x70(%r11), @XMM[0]     # .LADD8
1880         jnz     .Lctr_enc_loop
1881
1882         jmp     .Lctr_enc_done
1883 .align  16
1884 .Lctr_enc_loop_done:
1885         movdqu  0x00($inp), @XMM[8]     # load input
1886         pxor    @XMM[8], @XMM[0]
1887         movdqu  @XMM[0], 0x00($out)     # write output
1888         cmp     \$2,$len
1889         jb      .Lctr_enc_done
1890         movdqu  0x10($inp), @XMM[9]
1891         pxor    @XMM[9], @XMM[1]
1892         movdqu  @XMM[1], 0x10($out)
1893         je      .Lctr_enc_done
1894         movdqu  0x20($inp), @XMM[10]
1895         pxor    @XMM[10], @XMM[4]
1896         movdqu  @XMM[4], 0x20($out)
1897         cmp     \$4,$len
1898         jb      .Lctr_enc_done
1899         movdqu  0x30($inp), @XMM[11]
1900         pxor    @XMM[11], @XMM[6]
1901         movdqu  @XMM[6], 0x30($out)
1902         je      .Lctr_enc_done
1903         movdqu  0x40($inp), @XMM[12]
1904         pxor    @XMM[12], @XMM[3]
1905         movdqu  @XMM[3], 0x40($out)
1906         cmp     \$6,$len
1907         jb      .Lctr_enc_done
1908         movdqu  0x50($inp), @XMM[13]
1909         pxor    @XMM[13], @XMM[7]
1910         movdqu  @XMM[7], 0x50($out)
1911         je      .Lctr_enc_done
1912         movdqu  0x60($inp), @XMM[14]
1913         pxor    @XMM[14], @XMM[2]
1914         movdqu  @XMM[2], 0x60($out)
1915         jmp     .Lctr_enc_done
1916
1917 .align  16
1918 .Lctr_enc_short:
1919         lea     0x20(%rbp), $arg1
1920         lea     0x30(%rbp), $arg2
1921         lea     ($key), $arg3
1922         call    AES_encrypt
1923         movdqu  ($inp), @XMM[1]
1924         lea     16($inp), $inp
1925         mov     0x2c(%rbp), %eax        # load 32-bit counter
1926         bswap   %eax
1927         pxor    0x30(%rbp), @XMM[1]
1928         inc     %eax                    # increment
1929         movdqu  @XMM[1], ($out)
1930         bswap   %eax
1931         lea     16($out), $out
1932         mov     %eax, 0x2c(%rsp)        # save 32-bit counter
1933         dec     $len
1934         jnz     .Lctr_enc_short
1935
1936 .Lctr_enc_done:
1937         lea     (%rsp), %rax
1938         pxor    %xmm0, %xmm0
1939 .Lctr_enc_bzero:                        # wipe key schedule [if any]
1940         movdqa  %xmm0, 0x00(%rax)
1941         movdqa  %xmm0, 0x10(%rax)
1942         lea     0x20(%rax), %rax
1943         cmp     %rax, %rbp
1944         ja      .Lctr_enc_bzero
1945
1946         lea     (%rbp),%rsp             # restore %rsp
1947 ___
1948 $code.=<<___ if ($win64);
1949         movaps  0x40(%rbp), %xmm6
1950         movaps  0x50(%rbp), %xmm7
1951         movaps  0x60(%rbp), %xmm8
1952         movaps  0x70(%rbp), %xmm9
1953         movaps  0x80(%rbp), %xmm10
1954         movaps  0x90(%rbp), %xmm11
1955         movaps  0xa0(%rbp), %xmm12
1956         movaps  0xb0(%rbp), %xmm13
1957         movaps  0xc0(%rbp), %xmm14
1958         movaps  0xd0(%rbp), %xmm15
1959         lea     0xa0(%rbp), %rsp
1960 ___
1961 $code.=<<___;
1962         mov     0x48(%rsp), %r15
1963         mov     0x50(%rsp), %r14
1964         mov     0x58(%rsp), %r13
1965         mov     0x60(%rsp), %r12
1966         mov     0x68(%rsp), %rbx
1967         mov     0x70(%rsp), %rbp
1968         lea     0x78(%rsp), %rsp
1969 .Lctr_enc_epilogue:
1970         ret
1971 .size   bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
1972 ___
1973 ######################################################################
1974 # void bsaes_xts_[en|de]crypt(const char *inp,char *out,size_t len,
1975 #       const AES_KEY *key1, const AES_KEY *key2,
1976 #       const unsigned char iv[16]);
1977 #
1978 my ($twmask,$twres,$twtmp)=@XMM[13..15];
1979 $code.=<<___;
1980 .globl  bsaes_xts_encrypt
1981 .type   bsaes_xts_encrypt,\@abi-omnipotent
1982 .align  16
1983 bsaes_xts_encrypt:
1984         push    %rbp
1985         push    %rbx
1986         push    %r12
1987         push    %r13
1988         push    %r14
1989         push    %r15
1990         lea     -0x48(%rsp), %rsp
1991 ___
1992 $code.=<<___ if ($win64);
1993         mov     0xa0(%rsp),$arg5        # pull key2
1994         mov     0xa8(%rsp),$arg6        # pull ivp
1995         lea     -0xa0(%rsp), %rsp
1996         movaps  %xmm6, 0x40(%rsp)
1997         movaps  %xmm7, 0x50(%rsp)
1998         movaps  %xmm8, 0x60(%rsp)
1999         movaps  %xmm9, 0x70(%rsp)
2000         movaps  %xmm10, 0x80(%rsp)
2001         movaps  %xmm11, 0x90(%rsp)
2002         movaps  %xmm12, 0xa0(%rsp)
2003         movaps  %xmm13, 0xb0(%rsp)
2004         movaps  %xmm14, 0xc0(%rsp)
2005         movaps  %xmm15, 0xd0(%rsp)
2006 .Lxts_enc_body:
2007 ___
2008 $code.=<<___;
2009         mov     %rsp, %rbp              # backup %rsp
2010         mov     $arg1, $inp             # backup arguments
2011         mov     $arg2, $out
2012         mov     $arg3, $len
2013         mov     $arg4, $key
2014
2015         lea     ($arg6), $arg1
2016         lea     0x20(%rbp), $arg2
2017         lea     ($arg5), $arg3
2018         call    AES_encrypt             # generate initial tweak
2019
2020         mov     240($key), %eax         # rounds
2021         mov     $len, %rbx              # backup $len
2022
2023         mov     %eax, %edx              # rounds
2024         shl     \$7, %rax               # 128 bytes per inner round key
2025         sub     \$`128-32`, %rax        # size of bit-sliced key schedule
2026         sub     %rax, %rsp
2027
2028         mov     %rsp, %rax              # pass key schedule
2029         mov     $key, %rcx              # pass key
2030         mov     %edx, %r10d             # pass rounds
2031         call    _bsaes_key_convert
2032         pxor    %xmm6, %xmm7            # fix up last round key
2033         movdqa  %xmm7, (%rax)           # save last round key
2034
2035         and     \$-16, $len
2036         sub     \$0x80, %rsp            # place for tweak[8]
2037         movdqa  0x20(%rbp), @XMM[7]     # initial tweak
2038
2039         pxor    $twtmp, $twtmp
2040         movdqa  .Lxts_magic(%rip), $twmask
2041         pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
2042
2043         sub     \$0x80, $len
2044         jc      .Lxts_enc_short
2045         jmp     .Lxts_enc_loop
2046
2047 .align  16
2048 .Lxts_enc_loop:
2049 ___
2050     for ($i=0;$i<7;$i++) {
2051     $code.=<<___;
2052         pshufd  \$0x13, $twtmp, $twres
2053         pxor    $twtmp, $twtmp
2054         movdqa  @XMM[7], @XMM[$i]
2055         movdqa  @XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
2056         paddq   @XMM[7], @XMM[7]        # psllq 1,$tweak
2057         pand    $twmask, $twres         # isolate carry and residue
2058         pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
2059         pxor    $twres, @XMM[7]
2060 ___
2061     $code.=<<___ if ($i>=1);
2062         movdqu  `0x10*($i-1)`($inp), @XMM[8+$i-1]
2063 ___
2064     $code.=<<___ if ($i>=2);
2065         pxor    @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
2066 ___
2067     }
2068 $code.=<<___;
2069         movdqu  0x60($inp), @XMM[8+6]
2070         pxor    @XMM[8+5], @XMM[5]
2071         movdqu  0x70($inp), @XMM[8+7]
2072         lea     0x80($inp), $inp
2073         movdqa  @XMM[7], 0x70(%rsp)
2074         pxor    @XMM[8+6], @XMM[6]
2075         lea     0x80(%rsp), %rax        # pass key schedule
2076         pxor    @XMM[8+7], @XMM[7]
2077         mov     %edx, %r10d             # pass rounds
2078
2079         call    _bsaes_encrypt8
2080
2081         pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
2082         pxor    0x10(%rsp), @XMM[1]
2083         movdqu  @XMM[0], 0x00($out)     # write output
2084         pxor    0x20(%rsp), @XMM[4]
2085         movdqu  @XMM[1], 0x10($out)
2086         pxor    0x30(%rsp), @XMM[6]
2087         movdqu  @XMM[4], 0x20($out)
2088         pxor    0x40(%rsp), @XMM[3]
2089         movdqu  @XMM[6], 0x30($out)
2090         pxor    0x50(%rsp), @XMM[7]
2091         movdqu  @XMM[3], 0x40($out)
2092         pxor    0x60(%rsp), @XMM[2]
2093         movdqu  @XMM[7], 0x50($out)
2094         pxor    0x70(%rsp), @XMM[5]
2095         movdqu  @XMM[2], 0x60($out)
2096         movdqu  @XMM[5], 0x70($out)
2097         lea     0x80($out), $out
2098
2099         movdqa  0x70(%rsp), @XMM[7]     # prepare next iteration tweak
2100         pxor    $twtmp, $twtmp
2101         movdqa  .Lxts_magic(%rip), $twmask
2102         pcmpgtd @XMM[7], $twtmp
2103         pshufd  \$0x13, $twtmp, $twres
2104         pxor    $twtmp, $twtmp
2105         paddq   @XMM[7], @XMM[7]        # psllq 1,$tweak
2106         pand    $twmask, $twres         # isolate carry and residue
2107         pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
2108         pxor    $twres, @XMM[7]
2109
2110         sub     \$0x80,$len
2111         jnc     .Lxts_enc_loop
2112
2113 .Lxts_enc_short:
2114         add     \$0x80, $len
2115         jz      .Lxts_enc_done
2116 ___
2117     for ($i=0;$i<7;$i++) {
2118     $code.=<<___;
2119         pshufd  \$0x13, $twtmp, $twres
2120         pxor    $twtmp, $twtmp
2121         movdqa  @XMM[7], @XMM[$i]
2122         movdqa  @XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
2123         paddq   @XMM[7], @XMM[7]        # psllq 1,$tweak
2124         pand    $twmask, $twres         # isolate carry and residue
2125         pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
2126         pxor    $twres, @XMM[7]
2127 ___
2128     $code.=<<___ if ($i>=1);
2129         movdqu  `0x10*($i-1)`($inp), @XMM[8+$i-1]
2130         cmp     \$`0x10*$i`,$len
2131         je      .Lxts_enc_$i
2132 ___
2133     $code.=<<___ if ($i>=2);
2134         pxor    @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
2135 ___
2136     }
2137 $code.=<<___;
2138         movdqu  0x60($inp), @XMM[8+6]
2139         pxor    @XMM[8+5], @XMM[5]
2140         movdqa  @XMM[7], 0x70(%rsp)
2141         lea     0x70($inp), $inp
2142         pxor    @XMM[8+6], @XMM[6]
2143         lea     0x80(%rsp), %rax        # pass key schedule
2144         mov     %edx, %r10d             # pass rounds
2145
2146         call    _bsaes_encrypt8
2147
2148         pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
2149         pxor    0x10(%rsp), @XMM[1]
2150         movdqu  @XMM[0], 0x00($out)     # write output
2151         pxor    0x20(%rsp), @XMM[4]
2152         movdqu  @XMM[1], 0x10($out)
2153         pxor    0x30(%rsp), @XMM[6]
2154         movdqu  @XMM[4], 0x20($out)
2155         pxor    0x40(%rsp), @XMM[3]
2156         movdqu  @XMM[6], 0x30($out)
2157         pxor    0x50(%rsp), @XMM[7]
2158         movdqu  @XMM[3], 0x40($out)
2159         pxor    0x60(%rsp), @XMM[2]
2160         movdqu  @XMM[7], 0x50($out)
2161         movdqu  @XMM[2], 0x60($out)
2162         lea     0x70($out), $out
2163
2164         movdqa  0x70(%rsp), @XMM[7]     # next iteration tweak
2165         jmp     .Lxts_enc_done
2166 .align  16
2167 .Lxts_enc_6:
2168         pxor    @XMM[8+4], @XMM[4]
2169         lea     0x60($inp), $inp
2170         pxor    @XMM[8+5], @XMM[5]
2171         lea     0x80(%rsp), %rax        # pass key schedule
2172         mov     %edx, %r10d             # pass rounds
2173
2174         call    _bsaes_encrypt8
2175
2176         pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
2177         pxor    0x10(%rsp), @XMM[1]
2178         movdqu  @XMM[0], 0x00($out)     # write output
2179         pxor    0x20(%rsp), @XMM[4]
2180         movdqu  @XMM[1], 0x10($out)
2181         pxor    0x30(%rsp), @XMM[6]
2182         movdqu  @XMM[4], 0x20($out)
2183         pxor    0x40(%rsp), @XMM[3]
2184         movdqu  @XMM[6], 0x30($out)
2185         pxor    0x50(%rsp), @XMM[7]
2186         movdqu  @XMM[3], 0x40($out)
2187         movdqu  @XMM[7], 0x50($out)
2188         lea     0x60($out), $out
2189
2190         movdqa  0x60(%rsp), @XMM[7]     # next iteration tweak
2191         jmp     .Lxts_enc_done
2192 .align  16
2193 .Lxts_enc_5:
2194         pxor    @XMM[8+3], @XMM[3]
2195         lea     0x50($inp), $inp
2196         pxor    @XMM[8+4], @XMM[4]
2197         lea     0x80(%rsp), %rax        # pass key schedule
2198         mov     %edx, %r10d             # pass rounds
2199
2200         call    _bsaes_encrypt8
2201
2202         pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
2203         pxor    0x10(%rsp), @XMM[1]
2204         movdqu  @XMM[0], 0x00($out)     # write output
2205         pxor    0x20(%rsp), @XMM[4]
2206         movdqu  @XMM[1], 0x10($out)
2207         pxor    0x30(%rsp), @XMM[6]
2208         movdqu  @XMM[4], 0x20($out)
2209         pxor    0x40(%rsp), @XMM[3]
2210         movdqu  @XMM[6], 0x30($out)
2211         movdqu  @XMM[3], 0x40($out)
2212         lea     0x50($out), $out
2213
2214         movdqa  0x50(%rsp), @XMM[7]     # next iteration tweak
2215         jmp     .Lxts_enc_done
2216 .align  16
2217 .Lxts_enc_4:
2218         pxor    @XMM[8+2], @XMM[2]
2219         lea     0x40($inp), $inp
2220         pxor    @XMM[8+3], @XMM[3]
2221         lea     0x80(%rsp), %rax        # pass key schedule
2222         mov     %edx, %r10d             # pass rounds
2223
2224         call    _bsaes_encrypt8
2225
2226         pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
2227         pxor    0x10(%rsp), @XMM[1]
2228         movdqu  @XMM[0], 0x00($out)     # write output
2229         pxor    0x20(%rsp), @XMM[4]
2230         movdqu  @XMM[1], 0x10($out)
2231         pxor    0x30(%rsp), @XMM[6]
2232         movdqu  @XMM[4], 0x20($out)
2233         movdqu  @XMM[6], 0x30($out)
2234         lea     0x40($out), $out
2235
2236         movdqa  0x40(%rsp), @XMM[7]     # next iteration tweak
2237         jmp     .Lxts_enc_done
2238 .align  16
2239 .Lxts_enc_3:
2240         pxor    @XMM[8+1], @XMM[1]
2241         lea     0x30($inp), $inp
2242         pxor    @XMM[8+2], @XMM[2]
2243         lea     0x80(%rsp), %rax        # pass key schedule
2244         mov     %edx, %r10d             # pass rounds
2245
2246         call    _bsaes_encrypt8
2247
2248         pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
2249         pxor    0x10(%rsp), @XMM[1]
2250         movdqu  @XMM[0], 0x00($out)     # write output
2251         pxor    0x20(%rsp), @XMM[4]
2252         movdqu  @XMM[1], 0x10($out)
2253         movdqu  @XMM[4], 0x20($out)
2254         lea     0x30($out), $out
2255
2256         movdqa  0x30(%rsp), @XMM[7]     # next iteration tweak
2257         jmp     .Lxts_enc_done
2258 .align  16
2259 .Lxts_enc_2:
2260         pxor    @XMM[8+0], @XMM[0]
2261         lea     0x20($inp), $inp
2262         pxor    @XMM[8+1], @XMM[1]
2263         lea     0x80(%rsp), %rax        # pass key schedule
2264         mov     %edx, %r10d             # pass rounds
2265
2266         call    _bsaes_encrypt8
2267
2268         pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
2269         pxor    0x10(%rsp), @XMM[1]
2270         movdqu  @XMM[0], 0x00($out)     # write output
2271         movdqu  @XMM[1], 0x10($out)
2272         lea     0x20($out), $out
2273
2274         movdqa  0x20(%rsp), @XMM[7]     # next iteration tweak
2275         jmp     .Lxts_enc_done
2276 .align  16
2277 .Lxts_enc_1:
2278         pxor    @XMM[0], @XMM[8]
2279         lea     0x10($inp), $inp
2280         movdqa  @XMM[8], 0x20(%rbp)
2281         lea     0x20(%rbp), $arg1
2282         lea     0x20(%rbp), $arg2
2283         lea     ($key), $arg3
2284         call    AES_encrypt             # doesn't touch %xmm
2285         pxor    0x20(%rbp), @XMM[0]     # ^= tweak[]
2286         #pxor   @XMM[8], @XMM[0]
2287         #lea    0x80(%rsp), %rax        # pass key schedule
2288         #mov    %edx, %r10d             # pass rounds
2289         #call   _bsaes_encrypt8
2290         #pxor   0x00(%rsp), @XMM[0]     # ^= tweak[]
2291         movdqu  @XMM[0], 0x00($out)     # write output
2292         lea     0x10($out), $out
2293
2294         movdqa  0x10(%rsp), @XMM[7]     # next iteration tweak
2295
2296 .Lxts_enc_done:
2297         and     \$15, %ebx
2298         jz      .Lxts_enc_ret
2299         mov     $out, %rdx
2300
2301 .Lxts_enc_steal:
2302         movzb   ($inp), %eax
2303         movzb   -16(%rdx), %ecx
2304         lea     1($inp), $inp
2305         mov     %al, -16(%rdx)
2306         mov     %cl, 0(%rdx)
2307         lea     1(%rdx), %rdx
2308         sub     \$1,%ebx
2309         jnz     .Lxts_enc_steal
2310
2311         movdqu  -16($out), @XMM[0]
2312         lea     0x20(%rbp), $arg1
2313         pxor    @XMM[7], @XMM[0]
2314         lea     0x20(%rbp), $arg2
2315         movdqa  @XMM[0], 0x20(%rbp)
2316         lea     ($key), $arg3
2317         call    AES_encrypt             # doesn't touch %xmm
2318         pxor    0x20(%rbp), @XMM[7]
2319         movdqu  @XMM[7], -16($out)
2320
2321 .Lxts_enc_ret:
2322         lea     (%rsp), %rax
2323         pxor    %xmm0, %xmm0
2324 .Lxts_enc_bzero:                        # wipe key schedule [if any]
2325         movdqa  %xmm0, 0x00(%rax)
2326         movdqa  %xmm0, 0x10(%rax)
2327         lea     0x20(%rax), %rax
2328         cmp     %rax, %rbp
2329         ja      .Lxts_enc_bzero
2330
2331         lea     (%rbp),%rsp             # restore %rsp
2332 ___
2333 $code.=<<___ if ($win64);
2334         movaps  0x40(%rbp), %xmm6
2335         movaps  0x50(%rbp), %xmm7
2336         movaps  0x60(%rbp), %xmm8
2337         movaps  0x70(%rbp), %xmm9
2338         movaps  0x80(%rbp), %xmm10
2339         movaps  0x90(%rbp), %xmm11
2340         movaps  0xa0(%rbp), %xmm12
2341         movaps  0xb0(%rbp), %xmm13
2342         movaps  0xc0(%rbp), %xmm14
2343         movaps  0xd0(%rbp), %xmm15
2344         lea     0xa0(%rbp), %rsp
2345 ___
2346 $code.=<<___;
2347         mov     0x48(%rsp), %r15
2348         mov     0x50(%rsp), %r14
2349         mov     0x58(%rsp), %r13
2350         mov     0x60(%rsp), %r12
2351         mov     0x68(%rsp), %rbx
2352         mov     0x70(%rsp), %rbp
2353         lea     0x78(%rsp), %rsp
2354 .Lxts_enc_epilogue:
2355         ret
2356 .size   bsaes_xts_encrypt,.-bsaes_xts_encrypt
2357
2358 .globl  bsaes_xts_decrypt
2359 .type   bsaes_xts_decrypt,\@abi-omnipotent
2360 .align  16
2361 bsaes_xts_decrypt:
2362         push    %rbp
2363         push    %rbx
2364         push    %r12
2365         push    %r13
2366         push    %r14
2367         push    %r15
2368         lea     -0x48(%rsp), %rsp
2369 ___
2370 $code.=<<___ if ($win64);
2371         mov     0xa0(%rsp),$arg5        # pull key2
2372         mov     0xa8(%rsp),$arg6        # pull ivp
2373         lea     -0xa0(%rsp), %rsp
2374         movaps  %xmm6, 0x40(%rsp)
2375         movaps  %xmm7, 0x50(%rsp)
2376         movaps  %xmm8, 0x60(%rsp)
2377         movaps  %xmm9, 0x70(%rsp)
2378         movaps  %xmm10, 0x80(%rsp)
2379         movaps  %xmm11, 0x90(%rsp)
2380         movaps  %xmm12, 0xa0(%rsp)
2381         movaps  %xmm13, 0xb0(%rsp)
2382         movaps  %xmm14, 0xc0(%rsp)
2383         movaps  %xmm15, 0xd0(%rsp)
2384 .Lxts_dec_body:
2385 ___
2386 $code.=<<___;
2387         mov     %rsp, %rbp              # backup %rsp
2388         mov     $arg1, $inp             # backup arguments
2389         mov     $arg2, $out
2390         mov     $arg3, $len
2391         mov     $arg4, $key
2392
2393         lea     ($arg6), $arg1
2394         lea     0x20(%rbp), $arg2
2395         lea     ($arg5), $arg3
2396         call    AES_encrypt             # generate initial tweak
2397
2398         mov     240($key), %eax         # rounds
2399         mov     $len, %rbx              # backup $len
2400
2401         mov     %eax, %edx              # rounds
2402         shl     \$7, %rax               # 128 bytes per inner round key
2403         sub     \$`128-32`, %rax        # size of bit-sliced key schedule
2404         sub     %rax, %rsp
2405
2406         mov     %rsp, %rax              # pass key schedule
2407         mov     $key, %rcx              # pass key
2408         mov     %edx, %r10d             # pass rounds
2409         call    _bsaes_key_convert
2410         pxor    (%rsp), %xmm7           # fix up round 0 key
2411         movdqa  %xmm6, (%rax)           # save last round key
2412         movdqa  %xmm7, (%rsp)
2413
2414         xor     %eax, %eax              # if ($len%16) len-=16;
2415         and     \$-16, $len
2416         test    \$15, %ebx
2417         setnz   %al
2418         shl     \$4, %rax
2419         sub     %rax, $len
2420
2421         sub     \$0x80, %rsp            # place for tweak[8]
2422         movdqa  0x20(%rbp), @XMM[7]     # initial tweak
2423
2424         pxor    $twtmp, $twtmp
2425         movdqa  .Lxts_magic(%rip), $twmask
2426         pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
2427
2428         sub     \$0x80, $len
2429         jc      .Lxts_dec_short
2430         jmp     .Lxts_dec_loop
2431
2432 .align  16
2433 .Lxts_dec_loop:
2434 ___
2435     for ($i=0;$i<7;$i++) {
2436     $code.=<<___;
2437         pshufd  \$0x13, $twtmp, $twres
2438         pxor    $twtmp, $twtmp
2439         movdqa  @XMM[7], @XMM[$i]
2440         movdqa  @XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
2441         paddq   @XMM[7], @XMM[7]        # psllq 1,$tweak
2442         pand    $twmask, $twres         # isolate carry and residue
2443         pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
2444         pxor    $twres, @XMM[7]
2445 ___
2446     $code.=<<___ if ($i>=1);
2447         movdqu  `0x10*($i-1)`($inp), @XMM[8+$i-1]
2448 ___
2449     $code.=<<___ if ($i>=2);
2450         pxor    @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
2451 ___
2452     }
2453 $code.=<<___;
2454         movdqu  0x60($inp), @XMM[8+6]
2455         pxor    @XMM[8+5], @XMM[5]
2456         movdqu  0x70($inp), @XMM[8+7]
2457         lea     0x80($inp), $inp
2458         movdqa  @XMM[7], 0x70(%rsp)
2459         pxor    @XMM[8+6], @XMM[6]
2460         lea     0x80(%rsp), %rax        # pass key schedule
2461         pxor    @XMM[8+7], @XMM[7]
2462         mov     %edx, %r10d             # pass rounds
2463
2464         call    _bsaes_decrypt8
2465
2466         pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
2467         pxor    0x10(%rsp), @XMM[1]
2468         movdqu  @XMM[0], 0x00($out)     # write output
2469         pxor    0x20(%rsp), @XMM[6]
2470         movdqu  @XMM[1], 0x10($out)
2471         pxor    0x30(%rsp), @XMM[4]
2472         movdqu  @XMM[6], 0x20($out)
2473         pxor    0x40(%rsp), @XMM[2]
2474         movdqu  @XMM[4], 0x30($out)
2475         pxor    0x50(%rsp), @XMM[7]
2476         movdqu  @XMM[2], 0x40($out)
2477         pxor    0x60(%rsp), @XMM[3]
2478         movdqu  @XMM[7], 0x50($out)
2479         pxor    0x70(%rsp), @XMM[5]
2480         movdqu  @XMM[3], 0x60($out)
2481         movdqu  @XMM[5], 0x70($out)
2482         lea     0x80($out), $out
2483
2484         movdqa  0x70(%rsp), @XMM[7]     # prepare next iteration tweak
2485         pxor    $twtmp, $twtmp
2486         movdqa  .Lxts_magic(%rip), $twmask
2487         pcmpgtd @XMM[7], $twtmp
2488         pshufd  \$0x13, $twtmp, $twres
2489         pxor    $twtmp, $twtmp
2490         paddq   @XMM[7], @XMM[7]        # psllq 1,$tweak
2491         pand    $twmask, $twres         # isolate carry and residue
2492         pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
2493         pxor    $twres, @XMM[7]
2494
2495         sub     \$0x80,$len
2496         jnc     .Lxts_dec_loop
2497
2498 .Lxts_dec_short:
2499         add     \$0x80, $len
2500         jz      .Lxts_dec_done
2501 ___
2502     for ($i=0;$i<7;$i++) {
2503     $code.=<<___;
2504         pshufd  \$0x13, $twtmp, $twres
2505         pxor    $twtmp, $twtmp
2506         movdqa  @XMM[7], @XMM[$i]
2507         movdqa  @XMM[7], `0x10*$i`(%rsp)# save tweak[$i]
2508         paddq   @XMM[7], @XMM[7]        # psllq 1,$tweak
2509         pand    $twmask, $twres         # isolate carry and residue
2510         pcmpgtd @XMM[7], $twtmp         # broadcast upper bits
2511         pxor    $twres, @XMM[7]
2512 ___
2513     $code.=<<___ if ($i>=1);
2514         movdqu  `0x10*($i-1)`($inp), @XMM[8+$i-1]
2515         cmp     \$`0x10*$i`,$len
2516         je      .Lxts_dec_$i
2517 ___
2518     $code.=<<___ if ($i>=2);
2519         pxor    @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[]
2520 ___
2521     }
2522 $code.=<<___;
2523         movdqu  0x60($inp), @XMM[8+6]
2524         pxor    @XMM[8+5], @XMM[5]
2525         movdqa  @XMM[7], 0x70(%rsp)
2526         lea     0x70($inp), $inp
2527         pxor    @XMM[8+6], @XMM[6]
2528         lea     0x80(%rsp), %rax        # pass key schedule
2529         mov     %edx, %r10d             # pass rounds
2530
2531         call    _bsaes_decrypt8
2532
2533         pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
2534         pxor    0x10(%rsp), @XMM[1]
2535         movdqu  @XMM[0], 0x00($out)     # write output
2536         pxor    0x20(%rsp), @XMM[6]
2537         movdqu  @XMM[1], 0x10($out)
2538         pxor    0x30(%rsp), @XMM[4]
2539         movdqu  @XMM[6], 0x20($out)
2540         pxor    0x40(%rsp), @XMM[2]
2541         movdqu  @XMM[4], 0x30($out)
2542         pxor    0x50(%rsp), @XMM[7]
2543         movdqu  @XMM[2], 0x40($out)
2544         pxor    0x60(%rsp), @XMM[3]
2545         movdqu  @XMM[7], 0x50($out)
2546         movdqu  @XMM[3], 0x60($out)
2547         lea     0x70($out), $out
2548
2549         movdqa  0x70(%rsp), @XMM[7]     # next iteration tweak
2550         jmp     .Lxts_dec_done
2551 .align  16
2552 .Lxts_dec_6:
2553         pxor    @XMM[8+4], @XMM[4]
2554         lea     0x60($inp), $inp
2555         pxor    @XMM[8+5], @XMM[5]
2556         lea     0x80(%rsp), %rax        # pass key schedule
2557         mov     %edx, %r10d             # pass rounds
2558
2559         call    _bsaes_decrypt8
2560
2561         pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
2562         pxor    0x10(%rsp), @XMM[1]
2563         movdqu  @XMM[0], 0x00($out)     # write output
2564         pxor    0x20(%rsp), @XMM[6]
2565         movdqu  @XMM[1], 0x10($out)
2566         pxor    0x30(%rsp), @XMM[4]
2567         movdqu  @XMM[6], 0x20($out)
2568         pxor    0x40(%rsp), @XMM[2]
2569         movdqu  @XMM[4], 0x30($out)
2570         pxor    0x50(%rsp), @XMM[7]
2571         movdqu  @XMM[2], 0x40($out)
2572         movdqu  @XMM[7], 0x50($out)
2573         lea     0x60($out), $out
2574
2575         movdqa  0x60(%rsp), @XMM[7]     # next iteration tweak
2576         jmp     .Lxts_dec_done
2577 .align  16
2578 .Lxts_dec_5:
2579         pxor    @XMM[8+3], @XMM[3]
2580         lea     0x50($inp), $inp
2581         pxor    @XMM[8+4], @XMM[4]
2582         lea     0x80(%rsp), %rax        # pass key schedule
2583         mov     %edx, %r10d             # pass rounds
2584
2585         call    _bsaes_decrypt8
2586
2587         pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
2588         pxor    0x10(%rsp), @XMM[1]
2589         movdqu  @XMM[0], 0x00($out)     # write output
2590         pxor    0x20(%rsp), @XMM[6]
2591         movdqu  @XMM[1], 0x10($out)
2592         pxor    0x30(%rsp), @XMM[4]
2593         movdqu  @XMM[6], 0x20($out)
2594         pxor    0x40(%rsp), @XMM[2]
2595         movdqu  @XMM[4], 0x30($out)
2596         movdqu  @XMM[2], 0x40($out)
2597         lea     0x50($out), $out
2598
2599         movdqa  0x50(%rsp), @XMM[7]     # next iteration tweak
2600         jmp     .Lxts_dec_done
2601 .align  16
2602 .Lxts_dec_4:
2603         pxor    @XMM[8+2], @XMM[2]
2604         lea     0x40($inp), $inp
2605         pxor    @XMM[8+3], @XMM[3]
2606         lea     0x80(%rsp), %rax        # pass key schedule
2607         mov     %edx, %r10d             # pass rounds
2608
2609         call    _bsaes_decrypt8
2610
2611         pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
2612         pxor    0x10(%rsp), @XMM[1]
2613         movdqu  @XMM[0], 0x00($out)     # write output
2614         pxor    0x20(%rsp), @XMM[6]
2615         movdqu  @XMM[1], 0x10($out)
2616         pxor    0x30(%rsp), @XMM[4]
2617         movdqu  @XMM[6], 0x20($out)
2618         movdqu  @XMM[4], 0x30($out)
2619         lea     0x40($out), $out
2620
2621         movdqa  0x40(%rsp), @XMM[7]     # next iteration tweak
2622         jmp     .Lxts_dec_done
2623 .align  16
2624 .Lxts_dec_3:
2625         pxor    @XMM[8+1], @XMM[1]
2626         lea     0x30($inp), $inp
2627         pxor    @XMM[8+2], @XMM[2]
2628         lea     0x80(%rsp), %rax        # pass key schedule
2629         mov     %edx, %r10d             # pass rounds
2630
2631         call    _bsaes_decrypt8
2632
2633         pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
2634         pxor    0x10(%rsp), @XMM[1]
2635         movdqu  @XMM[0], 0x00($out)     # write output
2636         pxor    0x20(%rsp), @XMM[6]
2637         movdqu  @XMM[1], 0x10($out)
2638         movdqu  @XMM[6], 0x20($out)
2639         lea     0x30($out), $out
2640
2641         movdqa  0x30(%rsp), @XMM[7]     # next iteration tweak
2642         jmp     .Lxts_dec_done
2643 .align  16
2644 .Lxts_dec_2:
2645         pxor    @XMM[8+0], @XMM[0]
2646         lea     0x20($inp), $inp
2647         pxor    @XMM[8+1], @XMM[1]
2648         lea     0x80(%rsp), %rax        # pass key schedule
2649         mov     %edx, %r10d             # pass rounds
2650
2651         call    _bsaes_decrypt8
2652
2653         pxor    0x00(%rsp), @XMM[0]     # ^= tweak[]
2654         pxor    0x10(%rsp), @XMM[1]
2655         movdqu  @XMM[0], 0x00($out)     # write output
2656         movdqu  @XMM[1], 0x10($out)
2657         lea     0x20($out), $out
2658
2659         movdqa  0x20(%rsp), @XMM[7]     # next iteration tweak
2660         jmp     .Lxts_dec_done
2661 .align  16
2662 .Lxts_dec_1:
2663         pxor    @XMM[0], @XMM[8]
2664         lea     0x10($inp), $inp
2665         movdqa  @XMM[8], 0x20(%rbp)
2666         lea     0x20(%rbp), $arg1
2667         lea     0x20(%rbp), $arg2
2668         lea     ($key), $arg3
2669         call    AES_decrypt             # doesn't touch %xmm
2670         pxor    0x20(%rbp), @XMM[0]     # ^= tweak[]
2671         #pxor   @XMM[8], @XMM[0]
2672         #lea    0x80(%rsp), %rax        # pass key schedule
2673         #mov    %edx, %r10d             # pass rounds
2674         #call   _bsaes_decrypt8
2675         #pxor   0x00(%rsp), @XMM[0]     # ^= tweak[]
2676         movdqu  @XMM[0], 0x00($out)     # write output
2677         lea     0x10($out), $out
2678
2679         movdqa  0x10(%rsp), @XMM[7]     # next iteration tweak
2680
2681 .Lxts_dec_done:
2682         and     \$15, %ebx
2683         jz      .Lxts_dec_ret
2684
2685         pxor    $twtmp, $twtmp
2686         movdqa  .Lxts_magic(%rip), $twmask
2687         pcmpgtd @XMM[7], $twtmp
2688         pshufd  \$0x13, $twtmp, $twres
2689         movdqa  @XMM[7], @XMM[6]
2690         paddq   @XMM[7], @XMM[7]        # psllq 1,$tweak
2691         pand    $twmask, $twres         # isolate carry and residue
2692         movdqu  ($inp), @XMM[0]
2693         pxor    $twres, @XMM[7]
2694
2695         lea     0x20(%rbp), $arg1
2696         pxor    @XMM[7], @XMM[0]
2697         lea     0x20(%rbp), $arg2
2698         movdqa  @XMM[0], 0x20(%rbp)
2699         lea     ($key), $arg3
2700         call    AES_decrypt             # doesn't touch %xmm
2701         pxor    0x20(%rbp), @XMM[7]
2702         mov     $out, %rdx
2703         movdqu  @XMM[7], ($out)
2704
2705 .Lxts_dec_steal:
2706         movzb   16($inp), %eax
2707         movzb   (%rdx), %ecx
2708         lea     1($inp), $inp
2709         mov     %al, (%rdx)
2710         mov     %cl, 16(%rdx)
2711         lea     1(%rdx), %rdx
2712         sub     \$1,%ebx
2713         jnz     .Lxts_dec_steal
2714
2715         movdqu  ($out), @XMM[0]
2716         lea     0x20(%rbp), $arg1
2717         pxor    @XMM[6], @XMM[0]
2718         lea     0x20(%rbp), $arg2
2719         movdqa  @XMM[0], 0x20(%rbp)
2720         lea     ($key), $arg3
2721         call    AES_decrypt             # doesn't touch %xmm
2722         pxor    0x20(%rbp), @XMM[6]
2723         movdqu  @XMM[6], ($out)
2724
2725 .Lxts_dec_ret:
2726         lea     (%rsp), %rax
2727         pxor    %xmm0, %xmm0
2728 .Lxts_dec_bzero:                        # wipe key schedule [if any]
2729         movdqa  %xmm0, 0x00(%rax)
2730         movdqa  %xmm0, 0x10(%rax)
2731         lea     0x20(%rax), %rax
2732         cmp     %rax, %rbp
2733         ja      .Lxts_dec_bzero
2734
2735         lea     (%rbp),%rsp             # restore %rsp
2736 ___
2737 $code.=<<___ if ($win64);
2738         movaps  0x40(%rbp), %xmm6
2739         movaps  0x50(%rbp), %xmm7
2740         movaps  0x60(%rbp), %xmm8
2741         movaps  0x70(%rbp), %xmm9
2742         movaps  0x80(%rbp), %xmm10
2743         movaps  0x90(%rbp), %xmm11
2744         movaps  0xa0(%rbp), %xmm12
2745         movaps  0xb0(%rbp), %xmm13
2746         movaps  0xc0(%rbp), %xmm14
2747         movaps  0xd0(%rbp), %xmm15
2748         lea     0xa0(%rbp), %rsp
2749 ___
2750 $code.=<<___;
2751         mov     0x48(%rsp), %r15
2752         mov     0x50(%rsp), %r14
2753         mov     0x58(%rsp), %r13
2754         mov     0x60(%rsp), %r12
2755         mov     0x68(%rsp), %rbx
2756         mov     0x70(%rsp), %rbp
2757         lea     0x78(%rsp), %rsp
2758 .Lxts_dec_epilogue:
2759         ret
2760 .size   bsaes_xts_decrypt,.-bsaes_xts_decrypt
2761 ___
2762 }
2763 $code.=<<___;
2764 .type   _bsaes_const,\@object
2765 .align  64
2766 _bsaes_const:
2767 .LM0ISR:        # InvShiftRows constants
2768         .quad   0x0a0e0206070b0f03, 0x0004080c0d010509
2769 .LISRM0:
2770         .quad   0x01040b0e0205080f, 0x0306090c00070a0d
2771 .LISR:
2772         .quad   0x0504070602010003, 0x0f0e0d0c080b0a09
2773 .LBS0:          # bit-slice constants
2774         .quad   0x5555555555555555, 0x5555555555555555
2775 .LBS1:
2776         .quad   0x3333333333333333, 0x3333333333333333
2777 .LBS2:
2778         .quad   0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f
2779 .LSR:           # shiftrows constants
2780         .quad   0x0504070600030201, 0x0f0e0d0c0a09080b
2781 .LSRM0:
2782         .quad   0x0304090e00050a0f, 0x01060b0c0207080d
2783 .LM0:
2784         .quad   0x02060a0e03070b0f, 0x0004080c0105090d
2785 .LM0SR:
2786         .quad   0x0a0e02060f03070b, 0x0004080c05090d01
2787 .LNOT:          # magic constants
2788         .quad   0xffffffffffffffff, 0xffffffffffffffff
2789 .L63:
2790         .quad   0x6363636363636363, 0x6363636363636363
2791 .LSWPUP:        # byte-swap upper dword
2792         .quad   0x0706050403020100, 0x0c0d0e0f0b0a0908
2793 .LSWPUPM0SR:
2794         .quad   0x0a0d02060c03070b, 0x0004080f05090e01
2795 .LADD1:         # counter increment constants
2796         .quad   0x0000000000000000, 0x0000000100000000
2797 .LADD2:
2798         .quad   0x0000000000000000, 0x0000000200000000
2799 .LADD3:
2800         .quad   0x0000000000000000, 0x0000000300000000
2801 .LADD4:
2802         .quad   0x0000000000000000, 0x0000000400000000
2803 .LADD5:
2804         .quad   0x0000000000000000, 0x0000000500000000
2805 .LADD6:
2806         .quad   0x0000000000000000, 0x0000000600000000
2807 .LADD7:
2808         .quad   0x0000000000000000, 0x0000000700000000
2809 .LADD8:
2810         .quad   0x0000000000000000, 0x0000000800000000
2811 .Lxts_magic:
2812         .long   0x87,0,1,0
2813 .asciz  "Bit-sliced AES for x86_64/SSSE3, Emilia Käsper, Peter Schwabe, Andy Polyakov"
2814 .align  64
2815 .size   _bsaes_const,.-_bsaes_const
2816 ___
2817
2818 $code =~ s/\`([^\`]*)\`/eval($1)/gem;
2819
2820 print $code;
2821
2822 close STDOUT;