Use Perl to generate bsaes-armv8.S
[openssl.git] / crypto / aes / asm / bsaes-armv8.pl
1 #!/usr/bin/env perl
2 # Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
3 #
4 # Licensed under the Apache License 2.0 (the "License").  You may not use
5 # this file except in compliance with the License.  You can obtain a copy
6 # in the file LICENSE in the source distribution or at
7 # https://www.openssl.org/source/license.html
8
9 use strict;
10
11 my $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
12 my $flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
13 my $xlate;
14
15 $0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1;
16 ( $xlate="${dir}arm-xlate.pl" and -f $xlate  ) or
17 ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate ) or
18 die "can't locate arm-xlate.pl";
19
20 open OUT,"| \"$^X\" $xlate $flavour $output";
21 *STDOUT=*OUT;
22
23 my $code = data();
24 print $code;
25
26 close STDOUT or die "error closing STDOUT: $!"; # enforce flush
27
28 sub data
29 {
30     local $/;
31     return <DATA>;
32 }
33
34 __END__
35 // Copyright 2021 The OpenSSL Project Authors. All Rights Reserved.
36 //
37 // Licensed under the OpenSSL license (the "License").  You may not use
38 // this file except in compliance with the License.  You can obtain a copy
39 // in the file LICENSE in the source distribution or at
40 // https://www.openssl.org/source/license.html
41 //
42 // ====================================================================
43 // Written by Ben Avison <bavison@riscosopen.org> for the OpenSSL
44 // project. Rights for redistribution and usage in source and binary
45 // forms are granted according to the OpenSSL license.
46 // ====================================================================
47 //
48 // This implementation is a translation of bsaes-armv7 for AArch64.
49 // No attempt has been made to carry across the build switches for
50 // kernel targets, since the Linux kernel crypto support has moved on
51 // from when it was based on OpenSSL.
52
53 // A lot of hand-scheduling has been performed. Consequently, this code
54 // doesn't factor out neatly into macros in the same way that the
55 // AArch32 version did, and there is little to be gained by wrapping it
56 // up in Perl, and it is presented as pure assembly.
57
58
59 #include "crypto/arm_arch.h"
60
61 .text
62
63 .extern AES_cbc_encrypt
64 .extern AES_encrypt
65 .extern AES_decrypt
66
67 .type   _bsaes_decrypt8,%function
68 .align  4
69 // On entry:
70 //   x9 -> key (previously expanded using _bsaes_key_convert)
71 //   x10 = number of rounds
72 //   v0-v7 input data
73 // On exit:
74 //   x9-x11 corrupted
75 //   other general-purpose registers preserved
76 //   v0-v7 output data
77 //   v11-v15 preserved
78 //   other SIMD registers corrupted
79 _bsaes_decrypt8:
80         ldr     q8, [x9], #16
81         adr     x11, .LM0ISR
82         movi    v9.16b, #0x55
83         ldr     q10, [x11], #16
84         movi    v16.16b, #0x33
85         movi    v17.16b, #0x0f
86         sub     x10, x10, #1
87         eor     v0.16b, v0.16b, v8.16b
88         eor     v1.16b, v1.16b, v8.16b
89         eor     v2.16b, v2.16b, v8.16b
90         eor     v4.16b, v4.16b, v8.16b
91         eor     v3.16b, v3.16b, v8.16b
92         eor     v5.16b, v5.16b, v8.16b
93         tbl     v0.16b, {v0.16b}, v10.16b
94         tbl     v1.16b, {v1.16b}, v10.16b
95         tbl     v2.16b, {v2.16b}, v10.16b
96         tbl     v4.16b, {v4.16b}, v10.16b
97         eor     v6.16b, v6.16b, v8.16b
98         eor     v7.16b, v7.16b, v8.16b
99         tbl     v3.16b, {v3.16b}, v10.16b
100         tbl     v5.16b, {v5.16b}, v10.16b
101         tbl     v6.16b, {v6.16b}, v10.16b
102         ushr    v8.2d, v0.2d, #1
103         tbl     v7.16b, {v7.16b}, v10.16b
104         ushr    v10.2d, v4.2d, #1
105         ushr    v18.2d, v2.2d, #1
106         eor     v8.16b, v8.16b, v1.16b
107         ushr    v19.2d, v6.2d, #1
108         eor     v10.16b, v10.16b, v5.16b
109         eor     v18.16b, v18.16b, v3.16b
110         and     v8.16b, v8.16b, v9.16b
111         eor     v19.16b, v19.16b, v7.16b
112         and     v10.16b, v10.16b, v9.16b
113         and     v18.16b, v18.16b, v9.16b
114         eor     v1.16b, v1.16b, v8.16b
115         shl     v8.2d, v8.2d, #1
116         and     v9.16b, v19.16b, v9.16b
117         eor     v5.16b, v5.16b, v10.16b
118         shl     v10.2d, v10.2d, #1
119         eor     v3.16b, v3.16b, v18.16b
120         shl     v18.2d, v18.2d, #1
121         eor     v0.16b, v0.16b, v8.16b
122         shl     v8.2d, v9.2d, #1
123         eor     v7.16b, v7.16b, v9.16b
124         eor     v4.16b, v4.16b, v10.16b
125         eor     v2.16b, v2.16b, v18.16b
126         ushr    v9.2d, v1.2d, #2
127         eor     v6.16b, v6.16b, v8.16b
128         ushr    v8.2d, v0.2d, #2
129         ushr    v10.2d, v5.2d, #2
130         ushr    v18.2d, v4.2d, #2
131         eor     v9.16b, v9.16b, v3.16b
132         eor     v8.16b, v8.16b, v2.16b
133         eor     v10.16b, v10.16b, v7.16b
134         eor     v18.16b, v18.16b, v6.16b
135         and     v9.16b, v9.16b, v16.16b
136         and     v8.16b, v8.16b, v16.16b
137         and     v10.16b, v10.16b, v16.16b
138         and     v16.16b, v18.16b, v16.16b
139         eor     v3.16b, v3.16b, v9.16b
140         shl     v9.2d, v9.2d, #2
141         eor     v2.16b, v2.16b, v8.16b
142         shl     v8.2d, v8.2d, #2
143         eor     v7.16b, v7.16b, v10.16b
144         shl     v10.2d, v10.2d, #2
145         eor     v6.16b, v6.16b, v16.16b
146         shl     v16.2d, v16.2d, #2
147         eor     v1.16b, v1.16b, v9.16b
148         eor     v0.16b, v0.16b, v8.16b
149         eor     v5.16b, v5.16b, v10.16b
150         eor     v4.16b, v4.16b, v16.16b
151         ushr    v8.2d, v3.2d, #4
152         ushr    v9.2d, v2.2d, #4
153         ushr    v10.2d, v1.2d, #4
154         ushr    v16.2d, v0.2d, #4
155         eor     v8.16b, v8.16b, v7.16b
156         eor     v9.16b, v9.16b, v6.16b
157         eor     v10.16b, v10.16b, v5.16b
158         eor     v16.16b, v16.16b, v4.16b
159         and     v8.16b, v8.16b, v17.16b
160         and     v9.16b, v9.16b, v17.16b
161         and     v10.16b, v10.16b, v17.16b
162         and     v16.16b, v16.16b, v17.16b
163         eor     v7.16b, v7.16b, v8.16b
164         shl     v8.2d, v8.2d, #4
165         eor     v6.16b, v6.16b, v9.16b
166         shl     v9.2d, v9.2d, #4
167         eor     v5.16b, v5.16b, v10.16b
168         shl     v10.2d, v10.2d, #4
169         eor     v4.16b, v4.16b, v16.16b
170         shl     v16.2d, v16.2d, #4
171         eor     v3.16b, v3.16b, v8.16b
172         eor     v2.16b, v2.16b, v9.16b
173         eor     v1.16b, v1.16b, v10.16b
174         eor     v0.16b, v0.16b, v16.16b
175         b       .Ldec_sbox
176 .align  4
177 .Ldec_loop:
178         ld1     {v16.16b, v17.16b, v18.16b, v19.16b}, [x9], #64
179         ldp     q8, q9, [x9], #32
180         eor     v0.16b, v16.16b, v0.16b
181         ldr     q10, [x9], #16
182         eor     v1.16b, v17.16b, v1.16b
183         ldr     q16, [x9], #16
184         eor     v2.16b, v18.16b, v2.16b
185         eor     v3.16b, v19.16b, v3.16b
186         eor     v4.16b, v8.16b, v4.16b
187         eor     v5.16b, v9.16b, v5.16b
188         eor     v6.16b, v10.16b, v6.16b
189         eor     v7.16b, v16.16b, v7.16b
190         tbl     v0.16b, {v0.16b}, v28.16b
191         tbl     v1.16b, {v1.16b}, v28.16b
192         tbl     v2.16b, {v2.16b}, v28.16b
193         tbl     v3.16b, {v3.16b}, v28.16b
194         tbl     v4.16b, {v4.16b}, v28.16b
195         tbl     v5.16b, {v5.16b}, v28.16b
196         tbl     v6.16b, {v6.16b}, v28.16b
197         tbl     v7.16b, {v7.16b}, v28.16b
198 .Ldec_sbox:
199         eor     v1.16b, v1.16b, v4.16b
200         eor     v3.16b, v3.16b, v4.16b
201         subs    x10, x10, #1
202         eor     v4.16b, v4.16b, v7.16b
203         eor     v2.16b, v2.16b, v7.16b
204         eor     v1.16b, v1.16b, v6.16b
205         eor     v6.16b, v6.16b, v4.16b
206         eor     v2.16b, v2.16b, v5.16b
207         eor     v0.16b, v0.16b, v1.16b
208         eor     v7.16b, v7.16b, v6.16b
209         eor     v8.16b, v6.16b, v2.16b
210         and     v9.16b, v4.16b, v6.16b
211         eor     v10.16b, v2.16b, v6.16b
212         eor     v3.16b, v3.16b, v0.16b
213         eor     v5.16b, v5.16b, v0.16b
214         eor     v16.16b, v7.16b, v4.16b
215         eor     v17.16b, v4.16b, v0.16b
216         and     v18.16b, v0.16b, v2.16b
217         eor     v19.16b, v7.16b, v4.16b
218         eor     v1.16b, v1.16b, v3.16b
219         eor     v20.16b, v3.16b, v0.16b
220         eor     v21.16b, v5.16b, v2.16b
221         eor     v22.16b, v3.16b, v7.16b
222         and     v8.16b, v17.16b, v8.16b
223         orr     v17.16b, v3.16b, v5.16b
224         eor     v23.16b, v1.16b, v6.16b
225         eor     v24.16b, v20.16b, v16.16b
226         eor     v25.16b, v1.16b, v5.16b
227         orr     v26.16b, v20.16b, v21.16b
228         and     v20.16b, v20.16b, v21.16b
229         and     v27.16b, v7.16b, v1.16b
230         eor     v21.16b, v21.16b, v23.16b
231         orr     v28.16b, v16.16b, v23.16b
232         orr     v29.16b, v22.16b, v25.16b
233         eor     v26.16b, v26.16b, v8.16b
234         and     v16.16b, v16.16b, v23.16b
235         and     v22.16b, v22.16b, v25.16b
236         and     v21.16b, v24.16b, v21.16b
237         eor     v8.16b, v28.16b, v8.16b
238         eor     v23.16b, v5.16b, v2.16b
239         eor     v24.16b, v1.16b, v6.16b
240         eor     v16.16b, v16.16b, v22.16b
241         eor     v22.16b, v3.16b, v0.16b
242         eor     v25.16b, v29.16b, v21.16b
243         eor     v21.16b, v26.16b, v21.16b
244         eor     v8.16b, v8.16b, v20.16b
245         eor     v26.16b, v23.16b, v24.16b
246         eor     v16.16b, v16.16b, v20.16b
247         eor     v28.16b, v22.16b, v19.16b
248         eor     v20.16b, v25.16b, v20.16b
249         eor     v9.16b, v21.16b, v9.16b
250         eor     v8.16b, v8.16b, v18.16b
251         eor     v18.16b, v5.16b, v1.16b
252         eor     v21.16b, v16.16b, v17.16b
253         eor     v16.16b, v16.16b, v17.16b
254         eor     v17.16b, v20.16b, v27.16b
255         eor     v20.16b, v3.16b, v7.16b
256         eor     v25.16b, v9.16b, v8.16b
257         eor     v27.16b, v0.16b, v4.16b
258         and     v29.16b, v9.16b, v17.16b
259         eor     v30.16b, v8.16b, v29.16b
260         eor     v31.16b, v21.16b, v29.16b
261         eor     v29.16b, v21.16b, v29.16b
262         bsl     v30.16b, v17.16b, v21.16b
263         bsl     v31.16b, v9.16b, v8.16b
264         bsl     v16.16b, v30.16b, v29.16b
265         bsl     v21.16b, v29.16b, v30.16b
266         eor     v8.16b, v31.16b, v30.16b
267         and     v1.16b, v1.16b, v31.16b
268         and     v9.16b, v16.16b, v31.16b
269         and     v6.16b, v6.16b, v30.16b
270         eor     v16.16b, v17.16b, v21.16b
271         and     v4.16b, v4.16b, v30.16b
272         eor     v17.16b, v8.16b, v30.16b
273         and     v21.16b, v24.16b, v8.16b
274         eor     v9.16b, v9.16b, v25.16b
275         and     v19.16b, v19.16b, v8.16b
276         eor     v24.16b, v30.16b, v16.16b
277         eor     v25.16b, v30.16b, v16.16b
278         and     v7.16b, v7.16b, v17.16b
279         and     v10.16b, v10.16b, v16.16b
280         eor     v29.16b, v9.16b, v16.16b
281         eor     v30.16b, v31.16b, v9.16b
282         and     v0.16b, v24.16b, v0.16b
283         and     v9.16b, v18.16b, v9.16b
284         and     v2.16b, v25.16b, v2.16b
285         eor     v10.16b, v10.16b, v6.16b
286         eor     v18.16b, v29.16b, v16.16b
287         and     v5.16b, v30.16b, v5.16b
288         eor     v24.16b, v8.16b, v29.16b
289         and     v25.16b, v26.16b, v29.16b
290         and     v26.16b, v28.16b, v29.16b
291         eor     v8.16b, v8.16b, v29.16b
292         eor     v17.16b, v17.16b, v18.16b
293         eor     v5.16b, v1.16b, v5.16b
294         and     v23.16b, v24.16b, v23.16b
295         eor     v21.16b, v21.16b, v25.16b
296         eor     v19.16b, v19.16b, v26.16b
297         eor     v0.16b, v4.16b, v0.16b
298         and     v3.16b, v17.16b, v3.16b
299         eor     v1.16b, v9.16b, v1.16b
300         eor     v9.16b, v25.16b, v23.16b
301         eor     v5.16b, v5.16b, v21.16b
302         eor     v2.16b, v6.16b, v2.16b
303         and     v6.16b, v8.16b, v22.16b
304         eor     v3.16b, v7.16b, v3.16b
305         and     v8.16b, v20.16b, v18.16b
306         eor     v10.16b, v10.16b, v9.16b
307         eor     v0.16b, v0.16b, v19.16b
308         eor     v9.16b, v1.16b, v9.16b
309         eor     v1.16b, v2.16b, v21.16b
310         eor     v3.16b, v3.16b, v19.16b
311         and     v16.16b, v27.16b, v16.16b
312         eor     v17.16b, v26.16b, v6.16b
313         eor     v6.16b, v8.16b, v7.16b
314         eor     v7.16b, v1.16b, v9.16b
315         eor     v1.16b, v5.16b, v3.16b
316         eor     v2.16b, v10.16b, v3.16b
317         eor     v4.16b, v16.16b, v4.16b
318         eor     v8.16b, v6.16b, v17.16b
319         eor     v5.16b, v9.16b, v3.16b
320         eor     v9.16b, v0.16b, v1.16b
321         eor     v6.16b, v7.16b, v1.16b
322         eor     v0.16b, v4.16b, v17.16b
323         eor     v4.16b, v8.16b, v7.16b
324         eor     v7.16b, v9.16b, v2.16b
325         eor     v8.16b, v3.16b, v0.16b
326         eor     v7.16b, v7.16b, v5.16b
327         eor     v3.16b, v4.16b, v7.16b
328         eor     v4.16b, v7.16b, v0.16b
329         eor     v7.16b, v8.16b, v3.16b
330         bcc     .Ldec_done
331         ext     v8.16b, v0.16b, v0.16b, #8
332         ext     v9.16b, v1.16b, v1.16b, #8
333         ldr     q28, [x11]                  // load from .LISR in common case (x10 > 0)
334         ext     v10.16b, v6.16b, v6.16b, #8
335         ext     v16.16b, v3.16b, v3.16b, #8
336         ext     v17.16b, v5.16b, v5.16b, #8
337         ext     v18.16b, v4.16b, v4.16b, #8
338         eor     v8.16b, v8.16b, v0.16b
339         eor     v9.16b, v9.16b, v1.16b
340         eor     v10.16b, v10.16b, v6.16b
341         eor     v16.16b, v16.16b, v3.16b
342         eor     v17.16b, v17.16b, v5.16b
343         ext     v19.16b, v2.16b, v2.16b, #8
344         ext     v20.16b, v7.16b, v7.16b, #8
345         eor     v18.16b, v18.16b, v4.16b
346         eor     v6.16b, v6.16b, v8.16b
347         eor     v8.16b, v2.16b, v10.16b
348         eor     v4.16b, v4.16b, v9.16b
349         eor     v2.16b, v19.16b, v2.16b
350         eor     v9.16b, v20.16b, v7.16b
351         eor     v0.16b, v0.16b, v16.16b
352         eor     v1.16b, v1.16b, v16.16b
353         eor     v6.16b, v6.16b, v17.16b
354         eor     v8.16b, v8.16b, v16.16b
355         eor     v7.16b, v7.16b, v18.16b
356         eor     v4.16b, v4.16b, v16.16b
357         eor     v2.16b, v3.16b, v2.16b
358         eor     v1.16b, v1.16b, v17.16b
359         eor     v3.16b, v5.16b, v9.16b
360         eor     v5.16b, v8.16b, v17.16b
361         eor     v7.16b, v7.16b, v17.16b
362         ext     v8.16b, v0.16b, v0.16b, #12
363         ext     v9.16b, v6.16b, v6.16b, #12
364         ext     v10.16b, v4.16b, v4.16b, #12
365         ext     v16.16b, v1.16b, v1.16b, #12
366         ext     v17.16b, v5.16b, v5.16b, #12
367         ext     v18.16b, v7.16b, v7.16b, #12
368         eor     v0.16b, v0.16b, v8.16b
369         eor     v6.16b, v6.16b, v9.16b
370         eor     v4.16b, v4.16b, v10.16b
371         ext     v19.16b, v2.16b, v2.16b, #12
372         ext     v20.16b, v3.16b, v3.16b, #12
373         eor     v1.16b, v1.16b, v16.16b
374         eor     v5.16b, v5.16b, v17.16b
375         eor     v7.16b, v7.16b, v18.16b
376         eor     v2.16b, v2.16b, v19.16b
377         eor     v16.16b, v16.16b, v0.16b
378         eor     v3.16b, v3.16b, v20.16b
379         eor     v17.16b, v17.16b, v4.16b
380         eor     v10.16b, v10.16b, v6.16b
381         ext     v0.16b, v0.16b, v0.16b, #8
382         eor     v9.16b, v9.16b, v1.16b
383         ext     v1.16b, v1.16b, v1.16b, #8
384         eor     v8.16b, v8.16b, v3.16b
385         eor     v16.16b, v16.16b, v3.16b
386         eor     v18.16b, v18.16b, v5.16b
387         eor     v19.16b, v19.16b, v7.16b
388         ext     v21.16b, v5.16b, v5.16b, #8
389         ext     v5.16b, v7.16b, v7.16b, #8
390         eor     v7.16b, v20.16b, v2.16b
391         ext     v4.16b, v4.16b, v4.16b, #8
392         ext     v20.16b, v3.16b, v3.16b, #8
393         eor     v17.16b, v17.16b, v3.16b
394         ext     v2.16b, v2.16b, v2.16b, #8
395         eor     v3.16b, v10.16b, v3.16b
396         ext     v10.16b, v6.16b, v6.16b, #8
397         eor     v0.16b, v0.16b, v8.16b
398         eor     v1.16b, v1.16b, v16.16b
399         eor     v5.16b, v5.16b, v18.16b
400         eor     v3.16b, v3.16b, v4.16b
401         eor     v7.16b, v20.16b, v7.16b
402         eor     v6.16b, v2.16b, v19.16b
403         eor     v4.16b, v21.16b, v17.16b
404         eor     v2.16b, v10.16b, v9.16b
405         bne     .Ldec_loop
406         ldr     q28, [x11, #16]!            // load from .LISRM0 on last round (x10 == 0)
407         b       .Ldec_loop
408 .align  4
409 .Ldec_done:
410         ushr    v8.2d, v0.2d, #1
411         movi    v9.16b, #0x55
412         ldr     q10, [x9]
413         ushr    v16.2d, v2.2d, #1
414         movi    v17.16b, #0x33
415         ushr    v18.2d, v6.2d, #1
416         movi    v19.16b, #0x0f
417         eor     v8.16b, v8.16b, v1.16b
418         ushr    v20.2d, v3.2d, #1
419         eor     v16.16b, v16.16b, v7.16b
420         eor     v18.16b, v18.16b, v4.16b
421         and     v8.16b, v8.16b, v9.16b
422         eor     v20.16b, v20.16b, v5.16b
423         and     v16.16b, v16.16b, v9.16b
424         and     v18.16b, v18.16b, v9.16b
425         shl     v21.2d, v8.2d, #1
426         eor     v1.16b, v1.16b, v8.16b
427         and     v8.16b, v20.16b, v9.16b
428         eor     v7.16b, v7.16b, v16.16b
429         shl     v9.2d, v16.2d, #1
430         eor     v4.16b, v4.16b, v18.16b
431         shl     v16.2d, v18.2d, #1
432         eor     v0.16b, v0.16b, v21.16b
433         shl     v18.2d, v8.2d, #1
434         eor     v5.16b, v5.16b, v8.16b
435         eor     v2.16b, v2.16b, v9.16b
436         eor     v6.16b, v6.16b, v16.16b
437         ushr    v8.2d, v1.2d, #2
438         eor     v3.16b, v3.16b, v18.16b
439         ushr    v9.2d, v0.2d, #2
440         ushr    v16.2d, v7.2d, #2
441         ushr    v18.2d, v2.2d, #2
442         eor     v8.16b, v8.16b, v4.16b
443         eor     v9.16b, v9.16b, v6.16b
444         eor     v16.16b, v16.16b, v5.16b
445         eor     v18.16b, v18.16b, v3.16b
446         and     v8.16b, v8.16b, v17.16b
447         and     v9.16b, v9.16b, v17.16b
448         and     v16.16b, v16.16b, v17.16b
449         and     v17.16b, v18.16b, v17.16b
450         eor     v4.16b, v4.16b, v8.16b
451         shl     v8.2d, v8.2d, #2
452         eor     v6.16b, v6.16b, v9.16b
453         shl     v9.2d, v9.2d, #2
454         eor     v5.16b, v5.16b, v16.16b
455         shl     v16.2d, v16.2d, #2
456         eor     v3.16b, v3.16b, v17.16b
457         shl     v17.2d, v17.2d, #2
458         eor     v1.16b, v1.16b, v8.16b
459         eor     v0.16b, v0.16b, v9.16b
460         eor     v7.16b, v7.16b, v16.16b
461         eor     v2.16b, v2.16b, v17.16b
462         ushr    v8.2d, v4.2d, #4
463         ushr    v9.2d, v6.2d, #4
464         ushr    v16.2d, v1.2d, #4
465         ushr    v17.2d, v0.2d, #4
466         eor     v8.16b, v8.16b, v5.16b
467         eor     v9.16b, v9.16b, v3.16b
468         eor     v16.16b, v16.16b, v7.16b
469         eor     v17.16b, v17.16b, v2.16b
470         and     v8.16b, v8.16b, v19.16b
471         and     v9.16b, v9.16b, v19.16b
472         and     v16.16b, v16.16b, v19.16b
473         and     v17.16b, v17.16b, v19.16b
474         eor     v5.16b, v5.16b, v8.16b
475         shl     v8.2d, v8.2d, #4
476         eor     v3.16b, v3.16b, v9.16b
477         shl     v9.2d, v9.2d, #4
478         eor     v7.16b, v7.16b, v16.16b
479         shl     v16.2d, v16.2d, #4
480         eor     v2.16b, v2.16b, v17.16b
481         shl     v17.2d, v17.2d, #4
482         eor     v4.16b, v4.16b, v8.16b
483         eor     v6.16b, v6.16b, v9.16b
484         eor     v7.16b, v7.16b, v10.16b
485         eor     v1.16b, v1.16b, v16.16b
486         eor     v2.16b, v2.16b, v10.16b
487         eor     v0.16b, v0.16b, v17.16b
488         eor     v4.16b, v4.16b, v10.16b
489         eor     v6.16b, v6.16b, v10.16b
490         eor     v3.16b, v3.16b, v10.16b
491         eor     v5.16b, v5.16b, v10.16b
492         eor     v1.16b, v1.16b, v10.16b
493         eor     v0.16b, v0.16b, v10.16b
494         ret
495 .size   _bsaes_decrypt8,.-_bsaes_decrypt8
496
497 .type   _bsaes_const,%object
498 .align  6
499 _bsaes_const:
500 // InvShiftRows constants
501 // Used in _bsaes_decrypt8, which assumes contiguity
502 // .LM0ISR used with round 0 key
503 // .LISR   used with middle round keys
504 // .LISRM0 used with final round key
505 .LM0ISR:
506 .quad   0x0a0e0206070b0f03, 0x0004080c0d010509
507 .LISR:
508 .quad   0x0504070602010003, 0x0f0e0d0c080b0a09
509 .LISRM0:
510 .quad   0x01040b0e0205080f, 0x0306090c00070a0d
511
512 // ShiftRows constants
513 // Used in _bsaes_encrypt8, which assumes contiguity
514 // .LM0SR used with round 0 key
515 // .LSR   used with middle round keys
516 // .LSRM0 used with final round key
517 .LM0SR:
518 .quad   0x0a0e02060f03070b, 0x0004080c05090d01
519 .LSR:
520 .quad   0x0504070600030201, 0x0f0e0d0c0a09080b
521 .LSRM0:
522 .quad   0x0304090e00050a0f, 0x01060b0c0207080d
523
524 .LM0_bigendian:
525 .quad   0x02060a0e03070b0f, 0x0004080c0105090d
526 .LM0_littleendian:
527 .quad   0x0105090d0004080c, 0x03070b0f02060a0e
528
529 // Used in ossl_bsaes_ctr32_encrypt_blocks, prior to dropping into
530 // _bsaes_encrypt8_alt, for round 0 key in place of .LM0SR
531 .LREVM0SR:
532 .quad   0x090d01050c000408, 0x03070b0f060a0e02
533
534 .align  6
535 .size   _bsaes_const,.-_bsaes_const
536
537 .type   _bsaes_encrypt8,%function
538 .align  4
539 // On entry:
540 //   x9 -> key (previously expanded using _bsaes_key_convert)
541 //   x10 = number of rounds
542 //   v0-v7 input data
543 // On exit:
544 //   x9-x11 corrupted
545 //   other general-purpose registers preserved
546 //   v0-v7 output data
547 //   v11-v15 preserved
548 //   other SIMD registers corrupted
549 _bsaes_encrypt8:
550         ldr     q8, [x9], #16
551         adr     x11, .LM0SR
552         ldr     q9, [x11], #16
553 _bsaes_encrypt8_alt:
554         eor     v0.16b, v0.16b, v8.16b
555         eor     v1.16b, v1.16b, v8.16b
556         sub     x10, x10, #1
557         eor     v2.16b, v2.16b, v8.16b
558         eor     v4.16b, v4.16b, v8.16b
559         eor     v3.16b, v3.16b, v8.16b
560         eor     v5.16b, v5.16b, v8.16b
561         tbl     v0.16b, {v0.16b}, v9.16b
562         tbl     v1.16b, {v1.16b}, v9.16b
563         tbl     v2.16b, {v2.16b}, v9.16b
564         tbl     v4.16b, {v4.16b}, v9.16b
565         eor     v6.16b, v6.16b, v8.16b
566         eor     v7.16b, v7.16b, v8.16b
567         tbl     v3.16b, {v3.16b}, v9.16b
568         tbl     v5.16b, {v5.16b}, v9.16b
569         tbl     v6.16b, {v6.16b}, v9.16b
570         ushr    v8.2d, v0.2d, #1
571         movi    v10.16b, #0x55
572         tbl     v7.16b, {v7.16b}, v9.16b
573         ushr    v9.2d, v4.2d, #1
574         movi    v16.16b, #0x33
575         ushr    v17.2d, v2.2d, #1
576         eor     v8.16b, v8.16b, v1.16b
577         movi    v18.16b, #0x0f
578         ushr    v19.2d, v6.2d, #1
579         eor     v9.16b, v9.16b, v5.16b
580         eor     v17.16b, v17.16b, v3.16b
581         and     v8.16b, v8.16b, v10.16b
582         eor     v19.16b, v19.16b, v7.16b
583         and     v9.16b, v9.16b, v10.16b
584         and     v17.16b, v17.16b, v10.16b
585         eor     v1.16b, v1.16b, v8.16b
586         shl     v8.2d, v8.2d, #1
587         and     v10.16b, v19.16b, v10.16b
588         eor     v5.16b, v5.16b, v9.16b
589         shl     v9.2d, v9.2d, #1
590         eor     v3.16b, v3.16b, v17.16b
591         shl     v17.2d, v17.2d, #1
592         eor     v0.16b, v0.16b, v8.16b
593         shl     v8.2d, v10.2d, #1
594         eor     v7.16b, v7.16b, v10.16b
595         eor     v4.16b, v4.16b, v9.16b
596         eor     v2.16b, v2.16b, v17.16b
597         ushr    v9.2d, v1.2d, #2
598         eor     v6.16b, v6.16b, v8.16b
599         ushr    v8.2d, v0.2d, #2
600         ushr    v10.2d, v5.2d, #2
601         ushr    v17.2d, v4.2d, #2
602         eor     v9.16b, v9.16b, v3.16b
603         eor     v8.16b, v8.16b, v2.16b
604         eor     v10.16b, v10.16b, v7.16b
605         eor     v17.16b, v17.16b, v6.16b
606         and     v9.16b, v9.16b, v16.16b
607         and     v8.16b, v8.16b, v16.16b
608         and     v10.16b, v10.16b, v16.16b
609         and     v16.16b, v17.16b, v16.16b
610         eor     v3.16b, v3.16b, v9.16b
611         shl     v9.2d, v9.2d, #2
612         eor     v2.16b, v2.16b, v8.16b
613         shl     v8.2d, v8.2d, #2
614         eor     v7.16b, v7.16b, v10.16b
615         shl     v10.2d, v10.2d, #2
616         eor     v6.16b, v6.16b, v16.16b
617         shl     v16.2d, v16.2d, #2
618         eor     v1.16b, v1.16b, v9.16b
619         eor     v0.16b, v0.16b, v8.16b
620         eor     v5.16b, v5.16b, v10.16b
621         eor     v4.16b, v4.16b, v16.16b
622         ushr    v8.2d, v3.2d, #4
623         ushr    v9.2d, v2.2d, #4
624         ushr    v10.2d, v1.2d, #4
625         ushr    v16.2d, v0.2d, #4
626         eor     v8.16b, v8.16b, v7.16b
627         eor     v9.16b, v9.16b, v6.16b
628         eor     v10.16b, v10.16b, v5.16b
629         eor     v16.16b, v16.16b, v4.16b
630         and     v8.16b, v8.16b, v18.16b
631         and     v9.16b, v9.16b, v18.16b
632         and     v10.16b, v10.16b, v18.16b
633         and     v16.16b, v16.16b, v18.16b
634         eor     v7.16b, v7.16b, v8.16b
635         shl     v8.2d, v8.2d, #4
636         eor     v6.16b, v6.16b, v9.16b
637         shl     v9.2d, v9.2d, #4
638         eor     v5.16b, v5.16b, v10.16b
639         shl     v10.2d, v10.2d, #4
640         eor     v4.16b, v4.16b, v16.16b
641         shl     v16.2d, v16.2d, #4
642         eor     v3.16b, v3.16b, v8.16b
643         eor     v2.16b, v2.16b, v9.16b
644         eor     v1.16b, v1.16b, v10.16b
645         eor     v0.16b, v0.16b, v16.16b
646         b       .Lenc_sbox
647 .align  4
648 .Lenc_loop:
649         ld1     {v16.16b, v17.16b, v18.16b, v19.16b}, [x9], #64
650         ldp     q8, q9, [x9], #32
651         eor     v0.16b, v16.16b, v0.16b
652         ldr     q10, [x9], #16
653         eor     v1.16b, v17.16b, v1.16b
654         ldr     q16, [x9], #16
655         eor     v2.16b, v18.16b, v2.16b
656         eor     v3.16b, v19.16b, v3.16b
657         eor     v4.16b, v8.16b, v4.16b
658         eor     v5.16b, v9.16b, v5.16b
659         eor     v6.16b, v10.16b, v6.16b
660         eor     v7.16b, v16.16b, v7.16b
661         tbl     v0.16b, {v0.16b}, v28.16b
662         tbl     v1.16b, {v1.16b}, v28.16b
663         tbl     v2.16b, {v2.16b}, v28.16b
664         tbl     v3.16b, {v3.16b}, v28.16b
665         tbl     v4.16b, {v4.16b}, v28.16b
666         tbl     v5.16b, {v5.16b}, v28.16b
667         tbl     v6.16b, {v6.16b}, v28.16b
668         tbl     v7.16b, {v7.16b}, v28.16b
669 .Lenc_sbox:
670         eor     v5.16b, v5.16b, v6.16b
671         eor     v3.16b, v3.16b, v0.16b
672         subs    x10, x10, #1
673         eor     v2.16b, v2.16b, v1.16b
674         eor     v5.16b, v5.16b, v0.16b
675         eor     v8.16b, v3.16b, v7.16b
676         eor     v6.16b, v6.16b, v2.16b
677         eor     v7.16b, v7.16b, v5.16b
678         eor     v8.16b, v8.16b, v4.16b
679         eor     v3.16b, v6.16b, v3.16b
680         eor     v4.16b, v4.16b, v5.16b
681         eor     v6.16b, v1.16b, v5.16b
682         eor     v2.16b, v2.16b, v7.16b
683         eor     v1.16b, v8.16b, v1.16b
684         eor     v8.16b, v7.16b, v4.16b
685         eor     v9.16b, v3.16b, v0.16b
686         eor     v10.16b, v7.16b, v6.16b
687         eor     v16.16b, v5.16b, v3.16b
688         eor     v17.16b, v6.16b, v2.16b
689         eor     v18.16b, v5.16b, v1.16b
690         eor     v19.16b, v2.16b, v4.16b
691         eor     v20.16b, v1.16b, v0.16b
692         orr     v21.16b, v8.16b, v9.16b
693         orr     v22.16b, v10.16b, v16.16b
694         eor     v23.16b, v8.16b, v17.16b
695         eor     v24.16b, v9.16b, v18.16b
696         and     v19.16b, v19.16b, v20.16b
697         orr     v20.16b, v17.16b, v18.16b
698         and     v8.16b, v8.16b, v9.16b
699         and     v9.16b, v17.16b, v18.16b
700         and     v17.16b, v23.16b, v24.16b
701         and     v10.16b, v10.16b, v16.16b
702         eor     v16.16b, v21.16b, v19.16b
703         eor     v18.16b, v20.16b, v19.16b
704         and     v19.16b, v2.16b, v1.16b
705         and     v20.16b, v6.16b, v5.16b
706         eor     v21.16b, v22.16b, v17.16b
707         eor     v9.16b, v9.16b, v10.16b
708         eor     v10.16b, v16.16b, v17.16b
709         eor     v16.16b, v18.16b, v8.16b
710         and     v17.16b, v4.16b, v0.16b
711         orr     v18.16b, v7.16b, v3.16b
712         eor     v21.16b, v21.16b, v8.16b
713         eor     v8.16b, v9.16b, v8.16b
714         eor     v9.16b, v10.16b, v19.16b
715         eor     v10.16b, v3.16b, v0.16b
716         eor     v16.16b, v16.16b, v17.16b
717         eor     v17.16b, v5.16b, v1.16b
718         eor     v19.16b, v21.16b, v20.16b
719         eor     v20.16b, v8.16b, v18.16b
720         eor     v8.16b, v8.16b, v18.16b
721         eor     v18.16b, v7.16b, v4.16b
722         eor     v21.16b, v9.16b, v16.16b
723         eor     v22.16b, v6.16b, v2.16b
724         and     v23.16b, v9.16b, v19.16b
725         eor     v24.16b, v10.16b, v17.16b
726         eor     v25.16b, v0.16b, v1.16b
727         eor     v26.16b, v7.16b, v6.16b
728         eor     v27.16b, v18.16b, v22.16b
729         eor     v28.16b, v3.16b, v5.16b
730         eor     v29.16b, v16.16b, v23.16b
731         eor     v30.16b, v20.16b, v23.16b
732         eor     v23.16b, v20.16b, v23.16b
733         eor     v31.16b, v4.16b, v2.16b
734         bsl     v29.16b, v19.16b, v20.16b
735         bsl     v30.16b, v9.16b, v16.16b
736         bsl     v8.16b, v29.16b, v23.16b
737         bsl     v20.16b, v23.16b, v29.16b
738         eor     v9.16b, v30.16b, v29.16b
739         and     v5.16b, v5.16b, v30.16b
740         and     v8.16b, v8.16b, v30.16b
741         and     v1.16b, v1.16b, v29.16b
742         eor     v16.16b, v19.16b, v20.16b
743         and     v2.16b, v2.16b, v29.16b
744         eor     v19.16b, v9.16b, v29.16b
745         and     v17.16b, v17.16b, v9.16b
746         eor     v8.16b, v8.16b, v21.16b
747         and     v20.16b, v22.16b, v9.16b
748         eor     v21.16b, v29.16b, v16.16b
749         eor     v22.16b, v29.16b, v16.16b
750         and     v23.16b, v25.16b, v16.16b
751         and     v6.16b, v6.16b, v19.16b
752         eor     v25.16b, v8.16b, v16.16b
753         eor     v29.16b, v30.16b, v8.16b
754         and     v4.16b, v21.16b, v4.16b
755         and     v8.16b, v28.16b, v8.16b
756         and     v0.16b, v22.16b, v0.16b
757         eor     v21.16b, v23.16b, v1.16b
758         eor     v22.16b, v9.16b, v25.16b
759         eor     v9.16b, v9.16b, v25.16b
760         eor     v23.16b, v25.16b, v16.16b
761         and     v3.16b, v29.16b, v3.16b
762         and     v24.16b, v24.16b, v25.16b
763         and     v25.16b, v27.16b, v25.16b
764         and     v10.16b, v22.16b, v10.16b
765         and     v9.16b, v9.16b, v18.16b
766         eor     v18.16b, v19.16b, v23.16b
767         and     v19.16b, v26.16b, v23.16b
768         eor     v3.16b, v5.16b, v3.16b
769         eor     v17.16b, v17.16b, v24.16b
770         eor     v10.16b, v24.16b, v10.16b
771         and     v16.16b, v31.16b, v16.16b
772         eor     v20.16b, v20.16b, v25.16b
773         eor     v9.16b, v25.16b, v9.16b
774         eor     v4.16b, v2.16b, v4.16b
775         and     v7.16b, v18.16b, v7.16b
776         eor     v18.16b, v19.16b, v6.16b
777         eor     v5.16b, v8.16b, v5.16b
778         eor     v0.16b, v1.16b, v0.16b
779         eor     v1.16b, v21.16b, v10.16b
780         eor     v8.16b, v3.16b, v17.16b
781         eor     v2.16b, v16.16b, v2.16b
782         eor     v3.16b, v6.16b, v7.16b
783         eor     v6.16b, v18.16b, v9.16b
784         eor     v4.16b, v4.16b, v20.16b
785         eor     v10.16b, v5.16b, v10.16b
786         eor     v0.16b, v0.16b, v17.16b
787         eor     v9.16b, v2.16b, v9.16b
788         eor     v3.16b, v3.16b, v20.16b
789         eor     v7.16b, v6.16b, v1.16b
790         eor     v5.16b, v8.16b, v4.16b
791         eor     v6.16b, v10.16b, v1.16b
792         eor     v2.16b, v4.16b, v0.16b
793         eor     v4.16b, v3.16b, v10.16b
794         eor     v9.16b, v9.16b, v7.16b
795         eor     v3.16b, v0.16b, v5.16b
796         eor     v0.16b, v1.16b, v4.16b
797         eor     v1.16b, v4.16b, v8.16b
798         eor     v4.16b, v9.16b, v5.16b
799         eor     v6.16b, v6.16b, v3.16b
800         bcc     .Lenc_done
801         ext     v8.16b, v0.16b, v0.16b, #12
802         ext     v9.16b, v4.16b, v4.16b, #12
803         ldr     q28, [x11]
804         ext     v10.16b, v6.16b, v6.16b, #12
805         ext     v16.16b, v1.16b, v1.16b, #12
806         ext     v17.16b, v3.16b, v3.16b, #12
807         ext     v18.16b, v7.16b, v7.16b, #12
808         eor     v0.16b, v0.16b, v8.16b
809         eor     v4.16b, v4.16b, v9.16b
810         eor     v6.16b, v6.16b, v10.16b
811         ext     v19.16b, v2.16b, v2.16b, #12
812         ext     v20.16b, v5.16b, v5.16b, #12
813         eor     v1.16b, v1.16b, v16.16b
814         eor     v3.16b, v3.16b, v17.16b
815         eor     v7.16b, v7.16b, v18.16b
816         eor     v2.16b, v2.16b, v19.16b
817         eor     v16.16b, v16.16b, v0.16b
818         eor     v5.16b, v5.16b, v20.16b
819         eor     v17.16b, v17.16b, v6.16b
820         eor     v10.16b, v10.16b, v4.16b
821         ext     v0.16b, v0.16b, v0.16b, #8
822         eor     v9.16b, v9.16b, v1.16b
823         ext     v1.16b, v1.16b, v1.16b, #8
824         eor     v8.16b, v8.16b, v5.16b
825         eor     v16.16b, v16.16b, v5.16b
826         eor     v18.16b, v18.16b, v3.16b
827         eor     v19.16b, v19.16b, v7.16b
828         ext     v3.16b, v3.16b, v3.16b, #8
829         ext     v7.16b, v7.16b, v7.16b, #8
830         eor     v20.16b, v20.16b, v2.16b
831         ext     v6.16b, v6.16b, v6.16b, #8
832         ext     v21.16b, v5.16b, v5.16b, #8
833         eor     v17.16b, v17.16b, v5.16b
834         ext     v2.16b, v2.16b, v2.16b, #8
835         eor     v10.16b, v10.16b, v5.16b
836         ext     v22.16b, v4.16b, v4.16b, #8
837         eor     v0.16b, v0.16b, v8.16b
838         eor     v1.16b, v1.16b, v16.16b
839         eor     v5.16b, v7.16b, v18.16b
840         eor     v4.16b, v3.16b, v17.16b
841         eor     v3.16b, v6.16b, v10.16b
842         eor     v7.16b, v21.16b, v20.16b
843         eor     v6.16b, v2.16b, v19.16b
844         eor     v2.16b, v22.16b, v9.16b
845         bne     .Lenc_loop
846         ldr     q28, [x11, #16]!            // load from .LSRM0 on last round (x10 == 0)
847         b       .Lenc_loop
848 .align  4
849 .Lenc_done:
850         ushr    v8.2d, v0.2d, #1
851         movi    v9.16b, #0x55
852         ldr     q10, [x9]
853         ushr    v16.2d, v3.2d, #1
854         movi    v17.16b, #0x33
855         ushr    v18.2d, v4.2d, #1
856         movi    v19.16b, #0x0f
857         eor     v8.16b, v8.16b, v1.16b
858         ushr    v20.2d, v2.2d, #1
859         eor     v16.16b, v16.16b, v7.16b
860         eor     v18.16b, v18.16b, v6.16b
861         and     v8.16b, v8.16b, v9.16b
862         eor     v20.16b, v20.16b, v5.16b
863         and     v16.16b, v16.16b, v9.16b
864         and     v18.16b, v18.16b, v9.16b
865         shl     v21.2d, v8.2d, #1
866         eor     v1.16b, v1.16b, v8.16b
867         and     v8.16b, v20.16b, v9.16b
868         eor     v7.16b, v7.16b, v16.16b
869         shl     v9.2d, v16.2d, #1
870         eor     v6.16b, v6.16b, v18.16b
871         shl     v16.2d, v18.2d, #1
872         eor     v0.16b, v0.16b, v21.16b
873         shl     v18.2d, v8.2d, #1
874         eor     v5.16b, v5.16b, v8.16b
875         eor     v3.16b, v3.16b, v9.16b
876         eor     v4.16b, v4.16b, v16.16b
877         ushr    v8.2d, v1.2d, #2
878         eor     v2.16b, v2.16b, v18.16b
879         ushr    v9.2d, v0.2d, #2
880         ushr    v16.2d, v7.2d, #2
881         ushr    v18.2d, v3.2d, #2
882         eor     v8.16b, v8.16b, v6.16b
883         eor     v9.16b, v9.16b, v4.16b
884         eor     v16.16b, v16.16b, v5.16b
885         eor     v18.16b, v18.16b, v2.16b
886         and     v8.16b, v8.16b, v17.16b
887         and     v9.16b, v9.16b, v17.16b
888         and     v16.16b, v16.16b, v17.16b
889         and     v17.16b, v18.16b, v17.16b
890         eor     v6.16b, v6.16b, v8.16b
891         shl     v8.2d, v8.2d, #2
892         eor     v4.16b, v4.16b, v9.16b
893         shl     v9.2d, v9.2d, #2
894         eor     v5.16b, v5.16b, v16.16b
895         shl     v16.2d, v16.2d, #2
896         eor     v2.16b, v2.16b, v17.16b
897         shl     v17.2d, v17.2d, #2
898         eor     v1.16b, v1.16b, v8.16b
899         eor     v0.16b, v0.16b, v9.16b
900         eor     v7.16b, v7.16b, v16.16b
901         eor     v3.16b, v3.16b, v17.16b
902         ushr    v8.2d, v6.2d, #4
903         ushr    v9.2d, v4.2d, #4
904         ushr    v16.2d, v1.2d, #4
905         ushr    v17.2d, v0.2d, #4
906         eor     v8.16b, v8.16b, v5.16b
907         eor     v9.16b, v9.16b, v2.16b
908         eor     v16.16b, v16.16b, v7.16b
909         eor     v17.16b, v17.16b, v3.16b
910         and     v8.16b, v8.16b, v19.16b
911         and     v9.16b, v9.16b, v19.16b
912         and     v16.16b, v16.16b, v19.16b
913         and     v17.16b, v17.16b, v19.16b
914         eor     v5.16b, v5.16b, v8.16b
915         shl     v8.2d, v8.2d, #4
916         eor     v2.16b, v2.16b, v9.16b
917         shl     v9.2d, v9.2d, #4
918         eor     v7.16b, v7.16b, v16.16b
919         shl     v16.2d, v16.2d, #4
920         eor     v3.16b, v3.16b, v17.16b
921         shl     v17.2d, v17.2d, #4
922         eor     v6.16b, v6.16b, v8.16b
923         eor     v4.16b, v4.16b, v9.16b
924         eor     v7.16b, v7.16b, v10.16b
925         eor     v1.16b, v1.16b, v16.16b
926         eor     v3.16b, v3.16b, v10.16b
927         eor     v0.16b, v0.16b, v17.16b
928         eor     v6.16b, v6.16b, v10.16b
929         eor     v4.16b, v4.16b, v10.16b
930         eor     v2.16b, v2.16b, v10.16b
931         eor     v5.16b, v5.16b, v10.16b
932         eor     v1.16b, v1.16b, v10.16b
933         eor     v0.16b, v0.16b, v10.16b
934         ret
935 .size   _bsaes_encrypt8,.-_bsaes_encrypt8
936
937 .type   _bsaes_key_convert,%function
938 .align  4
939 // On entry:
940 //   x9 -> input key (big-endian)
941 //   x10 = number of rounds
942 //   x17 -> output key (native endianness)
943 // On exit:
944 //   x9, x10 corrupted
945 //   x11 -> .LM0_bigendian
946 //   x17 -> last quadword of output key
947 //   other general-purpose registers preserved
948 //   v2-v6 preserved
949 //   v7.16b[] = 0x63
950 //   v8-v14 preserved
951 //   v15 = last round key (converted to native endianness)
952 //   other SIMD registers corrupted
953 _bsaes_key_convert:
954 #ifdef __ARMEL__
955         adr     x11, .LM0_littleendian
956 #else
957         adr     x11, .LM0_bigendian
958 #endif
959         ldr     q0, [x9], #16               // load round 0 key
960         ldr     q1, [x11]                   // .LM0
961         ldr     q15, [x9], #16              // load round 1 key
962
963         movi    v7.16b, #0x63               // compose .L63
964         movi    v16.16b, #0x01              // bit masks
965         movi    v17.16b, #0x02
966         movi    v18.16b, #0x04
967         movi    v19.16b, #0x08
968         movi    v20.16b, #0x10
969         movi    v21.16b, #0x20
970         movi    v22.16b, #0x40
971         movi    v23.16b, #0x80
972
973 #ifdef __ARMEL__
974         rev32   v0.16b, v0.16b
975 #endif
976         sub     x10, x10, #1
977         str     q0, [x17], #16              // save round 0 key
978
979 .align  4
980 .Lkey_loop:
981         tbl     v0.16b, {v15.16b}, v1.16b
982         ldr     q15, [x9], #16              // load next round key
983
984         eor     v0.16b, v0.16b, v7.16b
985         cmtst   v24.16b, v0.16b, v16.16b
986         cmtst   v25.16b, v0.16b, v17.16b
987         cmtst   v26.16b, v0.16b, v18.16b
988         cmtst   v27.16b, v0.16b, v19.16b
989         cmtst   v28.16b, v0.16b, v20.16b
990         cmtst   v29.16b, v0.16b, v21.16b
991         cmtst   v30.16b, v0.16b, v22.16b
992         cmtst   v31.16b, v0.16b, v23.16b
993         sub     x10, x10, #1
994         st1     {v24.16b-v27.16b}, [x17], #64 // write bit-sliced round key
995         st1     {v28.16b-v31.16b}, [x17], #64
996         cbnz    x10, .Lkey_loop
997
998         // don't save last round key
999 #ifdef __ARMEL__
1000         rev32   v15.16b, v15.16b
1001         adr     x11, .LM0_bigendian
1002 #endif
1003         ret
1004 .size   _bsaes_key_convert,.-_bsaes_key_convert
1005
1006 .globl  ossl_bsaes_cbc_encrypt
1007 .type   ossl_bsaes_cbc_encrypt,%function
1008 .align  4
1009 // On entry:
1010 //   x0 -> input ciphertext
1011 //   x1 -> output plaintext
1012 //   x2 = size of ciphertext and plaintext in bytes (assumed a multiple of 16)
1013 //   x3 -> key
1014 //   x4 -> 128-bit initialisation vector (or preceding 128-bit block of ciphertext if continuing after an earlier call)
1015 //   w5 must be == 0
1016 // On exit:
1017 //   Output plaintext filled in
1018 //   Initialisation vector overwritten with last quadword of ciphertext
1019 //   No output registers, usual AAPCS64 register preservation
1020 ossl_bsaes_cbc_encrypt:
1021         cmp     x2, #128
1022 #ifdef __APPLE__
1023         bhs     .Lcbc_do_bsaes
1024         b       AES_cbc_encrypt
1025 .Lcbc_do_bsaes:
1026 #else
1027         blo     AES_cbc_encrypt
1028 #endif
1029
1030         // it is up to the caller to make sure we are called with enc == 0
1031
1032         stp     fp, lr, [sp, #-48]!
1033         stp     d8, d9, [sp, #16]
1034         stp     d10, d15, [sp, #32]
1035         lsr     x2, x2, #4                  // len in 16 byte blocks
1036
1037         ldr     w15, [x3, #240]             // get # of rounds
1038         mov     x14, sp
1039
1040         // allocate the key schedule on the stack
1041         add     x17, sp, #96
1042         sub     x17, x17, x15, lsl #7       // 128 bytes per inner round key, less 96 bytes
1043
1044         // populate the key schedule
1045         mov     x9, x3                      // pass key
1046         mov     x10, x15                    // pass # of rounds
1047         mov     sp, x17                     // sp is sp
1048         bl      _bsaes_key_convert
1049         ldr     q6,  [sp]
1050         str     q15, [x17]                  // save last round key
1051         eor     v6.16b, v6.16b, v7.16b      // fix up round 0 key (by XORing with 0x63)
1052         str     q6, [sp]
1053
1054         ldr     q15, [x4]                   // load IV
1055         b       .Lcbc_dec_loop
1056
1057 .align  4
1058 .Lcbc_dec_loop:
1059         subs    x2, x2, #0x8
1060         bmi     .Lcbc_dec_loop_finish
1061
1062         ldr     q0, [x0], #16               // load input
1063         mov     x9, sp                      // pass the key
1064         ldr     q1, [x0], #16
1065         mov     x10, x15
1066         ldr     q2, [x0], #16
1067         ldr     q3, [x0], #16
1068         ldr     q4, [x0], #16
1069         ldr     q5, [x0], #16
1070         ldr     q6, [x0], #16
1071         ldr     q7, [x0], #-7*16
1072
1073         bl      _bsaes_decrypt8
1074
1075         ldr     q16, [x0], #16              // reload input
1076         eor     v0.16b, v0.16b, v15.16b     // ^= IV
1077         eor     v1.16b, v1.16b, v16.16b
1078         str     q0, [x1], #16               // write output
1079         ldr     q0, [x0], #16
1080         str     q1, [x1], #16
1081         ldr     q1, [x0], #16
1082         eor     v1.16b, v4.16b, v1.16b
1083         ldr     q4, [x0], #16
1084         eor     v2.16b, v2.16b, v4.16b
1085         eor     v0.16b, v6.16b, v0.16b
1086         ldr     q4, [x0], #16
1087         str     q0, [x1], #16
1088         str     q1, [x1], #16
1089         eor     v0.16b, v7.16b, v4.16b
1090         ldr     q1, [x0], #16
1091         str     q2, [x1], #16
1092         ldr     q2, [x0], #16
1093         ldr     q15, [x0], #16
1094         str     q0, [x1], #16
1095         eor     v0.16b, v5.16b, v2.16b
1096         eor     v1.16b, v3.16b, v1.16b
1097         str     q1, [x1], #16
1098         str     q0, [x1], #16
1099
1100         b       .Lcbc_dec_loop
1101
1102 .Lcbc_dec_loop_finish:
1103         adds    x2, x2, #8
1104         beq     .Lcbc_dec_done
1105
1106         ldr     q0, [x0], #16               // load input
1107         cmp     x2, #2
1108         blo     .Lcbc_dec_one
1109         ldr     q1, [x0], #16
1110         mov     x9, sp                      // pass the key
1111         mov     x10, x15
1112         beq     .Lcbc_dec_two
1113         ldr     q2, [x0], #16
1114         cmp     x2, #4
1115         blo     .Lcbc_dec_three
1116         ldr     q3, [x0], #16
1117         beq     .Lcbc_dec_four
1118         ldr     q4, [x0], #16
1119         cmp     x2, #6
1120         blo     .Lcbc_dec_five
1121         ldr     q5, [x0], #16
1122         beq     .Lcbc_dec_six
1123         ldr     q6, [x0], #-6*16
1124
1125         bl      _bsaes_decrypt8
1126
1127         ldr     q5, [x0], #16               // reload input
1128         eor     v0.16b, v0.16b, v15.16b     // ^= IV
1129         ldr     q8, [x0], #16
1130         ldr     q9, [x0], #16
1131         ldr     q10, [x0], #16
1132         str     q0, [x1], #16               // write output
1133         ldr     q0, [x0], #16
1134         eor     v1.16b, v1.16b, v5.16b
1135         ldr     q5, [x0], #16
1136         eor     v6.16b, v6.16b, v8.16b
1137         ldr     q15, [x0]
1138         eor     v4.16b, v4.16b, v9.16b
1139         eor     v2.16b, v2.16b, v10.16b
1140         str     q1, [x1], #16
1141         eor     v0.16b, v7.16b, v0.16b
1142         str     q6, [x1], #16
1143         eor     v1.16b, v3.16b, v5.16b
1144         str     q4, [x1], #16
1145         str     q2, [x1], #16
1146         str     q0, [x1], #16
1147         str     q1, [x1]
1148         b       .Lcbc_dec_done
1149 .align  4
1150 .Lcbc_dec_six:
1151         sub     x0, x0, #0x60
1152         bl      _bsaes_decrypt8
1153         ldr     q3, [x0], #16               // reload input
1154         eor     v0.16b, v0.16b, v15.16b     // ^= IV
1155         ldr     q5, [x0], #16
1156         ldr     q8, [x0], #16
1157         ldr     q9, [x0], #16
1158         str     q0, [x1], #16               // write output
1159         ldr     q0, [x0], #16
1160         eor     v1.16b, v1.16b, v3.16b
1161         ldr     q15, [x0]
1162         eor     v3.16b, v6.16b, v5.16b
1163         eor     v4.16b, v4.16b, v8.16b
1164         eor     v2.16b, v2.16b, v9.16b
1165         str     q1, [x1], #16
1166         eor     v0.16b, v7.16b, v0.16b
1167         str     q3, [x1], #16
1168         str     q4, [x1], #16
1169         str     q2, [x1], #16
1170         str     q0, [x1]
1171         b       .Lcbc_dec_done
1172 .align  4
1173 .Lcbc_dec_five:
1174         sub     x0, x0, #0x50
1175         bl      _bsaes_decrypt8
1176         ldr     q3, [x0], #16               // reload input
1177         eor     v0.16b, v0.16b, v15.16b     // ^= IV
1178         ldr     q5, [x0], #16
1179         ldr     q7, [x0], #16
1180         ldr     q8, [x0], #16
1181         str     q0, [x1], #16               // write output
1182         ldr     q15, [x0]
1183         eor     v0.16b, v1.16b, v3.16b
1184         eor     v1.16b, v6.16b, v5.16b
1185         eor     v3.16b, v4.16b, v7.16b
1186         str     q0, [x1], #16
1187         eor     v0.16b, v2.16b, v8.16b
1188         str     q1, [x1], #16
1189         str     q3, [x1], #16
1190         str     q0, [x1]
1191         b       .Lcbc_dec_done
1192 .align  4
1193 .Lcbc_dec_four:
1194         sub     x0, x0, #0x40
1195         bl      _bsaes_decrypt8
1196         ldr     q2, [x0], #16               // reload input
1197         eor     v0.16b, v0.16b, v15.16b     // ^= IV
1198         ldr     q3, [x0], #16
1199         ldr     q5, [x0], #16
1200         str     q0, [x1], #16               // write output
1201         ldr     q15, [x0]
1202         eor     v0.16b, v1.16b, v2.16b
1203         eor     v1.16b, v6.16b, v3.16b
1204         eor     v2.16b, v4.16b, v5.16b
1205         str     q0, [x1], #16
1206         str     q1, [x1], #16
1207         str     q2, [x1]
1208         b       .Lcbc_dec_done
1209 .align  4
1210 .Lcbc_dec_three:
1211         sub     x0, x0, #0x30
1212         bl      _bsaes_decrypt8
1213         ldr     q2, [x0], #16               // reload input
1214         eor     v0.16b, v0.16b, v15.16b     // ^= IV
1215         ldr     q3, [x0], #16
1216         ldr     q15, [x0]
1217         str     q0, [x1], #16               // write output
1218         eor     v0.16b, v1.16b, v2.16b
1219         eor     v1.16b, v6.16b, v3.16b
1220         str     q0, [x1], #16
1221         str     q1, [x1]
1222         b       .Lcbc_dec_done
1223 .align  4
1224 .Lcbc_dec_two:
1225         sub     x0, x0, #0x20
1226         bl      _bsaes_decrypt8
1227         ldr     q2, [x0], #16               // reload input
1228         eor     v0.16b, v0.16b, v15.16b     // ^= IV
1229         ldr     q15, [x0]
1230         str     q0, [x1], #16               // write output
1231         eor     v0.16b, v1.16b, v2.16b
1232         str     q0, [x1]
1233         b       .Lcbc_dec_done
1234 .align  4
1235 .Lcbc_dec_one:
1236         sub     x0, x0, #0x10
1237         stp     x1, x4, [sp, #-32]!
1238         str     x14, [sp, #16]
1239         mov     v8.16b, v15.16b
1240         mov     v15.16b, v0.16b
1241         mov     x2, x3
1242         bl      AES_decrypt
1243         ldr     x14, [sp, #16]
1244         ldp     x1, x4, [sp], #32
1245         ldr     q0, [x1]                    // load result
1246         eor     v0.16b, v0.16b, v8.16b      // ^= IV
1247         str     q0, [x1]                    // write output
1248
1249 .align  4
1250 .Lcbc_dec_done:
1251         movi    v0.16b, #0
1252         movi    v1.16b, #0
1253 .Lcbc_dec_bzero:// wipe key schedule [if any]
1254         stp     q0, q1, [sp], #32
1255         cmp     sp, x14
1256         bne     .Lcbc_dec_bzero
1257         str     q15, [x4]                   // return IV
1258         ldp     d8, d9, [sp, #16]
1259         ldp     d10, d15, [sp, #32]
1260         ldp     fp, lr, [sp], #48
1261         ret
1262 .size   ossl_bsaes_cbc_encrypt,.-ossl_bsaes_cbc_encrypt
1263
1264 .globl  ossl_bsaes_ctr32_encrypt_blocks
1265 .type   ossl_bsaes_ctr32_encrypt_blocks,%function
1266 .align  4
1267 // On entry:
1268 //   x0 -> input text (whole 16-byte blocks)
1269 //   x1 -> output text (whole 16-byte blocks)
1270 //   x2 = number of 16-byte blocks to encrypt/decrypt (> 0)
1271 //   x3 -> key
1272 //   x4 -> initial value of 128-bit counter (stored big-endian) which increments, modulo 2^32, for each block
1273 // On exit:
1274 //   Output text filled in
1275 //   No output registers, usual AAPCS64 register preservation
1276 ossl_bsaes_ctr32_encrypt_blocks:
1277
1278         cmp     x2, #8                      // use plain AES for
1279         blo     .Lctr_enc_short             // small sizes
1280
1281         stp     fp, lr, [sp, #-80]!
1282         stp     d8, d9, [sp, #16]
1283         stp     d10, d11, [sp, #32]
1284         stp     d12, d13, [sp, #48]
1285         stp     d14, d15, [sp, #64]
1286
1287         ldr     w15, [x3, #240]             // get # of rounds
1288         mov     x14, sp
1289
1290         // allocate the key schedule on the stack
1291         add     x17, sp, #96
1292         sub     x17, x17, x15, lsl #7       // 128 bytes per inner round key, less 96 bytes
1293
1294         // populate the key schedule
1295         mov     x9, x3                      // pass key
1296         mov     x10, x15                    // pass # of rounds
1297         mov     sp, x17                     // sp is sp
1298         bl      _bsaes_key_convert
1299         eor     v7.16b, v7.16b, v15.16b     // fix up last round key
1300         str     q7, [x17]                   // save last round key
1301
1302         ldr     q0, [x4]                    // load counter
1303         add     x13, x11, #.LREVM0SR-.LM0_bigendian
1304         ldr     q4, [sp]                    // load round0 key
1305
1306         movi    v8.4s, #1                   // compose 1<<96
1307         movi    v9.16b, #0
1308         rev32   v15.16b, v0.16b
1309         rev32   v0.16b, v0.16b
1310         ext     v11.16b, v9.16b, v8.16b, #4
1311         rev32   v4.16b, v4.16b
1312         add     v12.4s, v11.4s, v11.4s      // compose 2<<96
1313         str     q4, [sp]                    // save adjusted round0 key
1314         add     v13.4s, v11.4s, v12.4s      // compose 3<<96
1315         add     v14.4s, v12.4s, v12.4s      // compose 4<<96
1316         b       .Lctr_enc_loop
1317
1318 .align  4
1319 .Lctr_enc_loop:
1320         // Intermix prologue from _bsaes_encrypt8 to use the opportunity
1321         // to flip byte order in 32-bit counter
1322
1323         add     v1.4s, v15.4s, v11.4s       // +1
1324         add     x9, sp, #0x10               // pass next round key
1325         add     v2.4s, v15.4s, v12.4s       // +2
1326         ldr     q9, [x13]                   // .LREVM0SR
1327         ldr     q8, [sp]                    // load round0 key
1328         add     v3.4s, v15.4s, v13.4s       // +3
1329         mov     x10, x15                    // pass rounds
1330         sub     x11, x13, #.LREVM0SR-.LSR   // pass constants
1331         add     v6.4s, v2.4s, v14.4s
1332         add     v4.4s, v15.4s, v14.4s       // +4
1333         add     v7.4s, v3.4s, v14.4s
1334         add     v15.4s, v4.4s, v14.4s       // next counter
1335         add     v5.4s, v1.4s, v14.4s
1336
1337         bl      _bsaes_encrypt8_alt
1338
1339         subs    x2, x2, #8
1340         blo     .Lctr_enc_loop_done
1341
1342         ldr     q16, [x0], #16
1343         ldr     q17, [x0], #16
1344         eor     v1.16b, v1.16b, v17.16b
1345         ldr     q17, [x0], #16
1346         eor     v0.16b, v0.16b, v16.16b
1347         eor     v4.16b, v4.16b, v17.16b
1348         str     q0, [x1], #16
1349         ldr     q16, [x0], #16
1350         str     q1, [x1], #16
1351         mov     v0.16b, v15.16b
1352         str     q4, [x1], #16
1353         ldr     q1, [x0], #16
1354         eor     v4.16b, v6.16b, v16.16b
1355         eor     v1.16b, v3.16b, v1.16b
1356         ldr     q3, [x0], #16
1357         eor     v3.16b, v7.16b, v3.16b
1358         ldr     q6, [x0], #16
1359         eor     v2.16b, v2.16b, v6.16b
1360         ldr     q6, [x0], #16
1361         eor     v5.16b, v5.16b, v6.16b
1362         str     q4, [x1], #16
1363         str     q1, [x1], #16
1364         str     q3, [x1], #16
1365         str     q2, [x1], #16
1366         str     q5, [x1], #16
1367
1368         bne     .Lctr_enc_loop
1369         b       .Lctr_enc_done
1370
1371 .align  4
1372 .Lctr_enc_loop_done:
1373         add     x2, x2, #8
1374         ldr     q16, [x0], #16              // load input
1375         eor     v0.16b, v0.16b, v16.16b
1376         str     q0, [x1], #16               // write output
1377         cmp     x2, #2
1378         blo     .Lctr_enc_done
1379         ldr     q17, [x0], #16
1380         eor     v1.16b, v1.16b, v17.16b
1381         str     q1, [x1], #16
1382         beq     .Lctr_enc_done
1383         ldr     q18, [x0], #16
1384         eor     v4.16b, v4.16b, v18.16b
1385         str     q4, [x1], #16
1386         cmp     x2, #4
1387         blo     .Lctr_enc_done
1388         ldr     q19, [x0], #16
1389         eor     v6.16b, v6.16b, v19.16b
1390         str     q6, [x1], #16
1391         beq     .Lctr_enc_done
1392         ldr     q20, [x0], #16
1393         eor     v3.16b, v3.16b, v20.16b
1394         str     q3, [x1], #16
1395         cmp     x2, #6
1396         blo     .Lctr_enc_done
1397         ldr     q21, [x0], #16
1398         eor     v7.16b, v7.16b, v21.16b
1399         str     q7, [x1], #16
1400         beq     .Lctr_enc_done
1401         ldr     q22, [x0]
1402         eor     v2.16b, v2.16b, v22.16b
1403         str     q2, [x1], #16
1404
1405 .Lctr_enc_done:
1406         movi    v0.16b, #0
1407         movi    v1.16b, #0
1408 .Lctr_enc_bzero: // wipe key schedule [if any]
1409         stp     q0, q1, [sp], #32
1410         cmp     sp, x14
1411         bne     .Lctr_enc_bzero
1412
1413         ldp     d8, d9, [sp, #16]
1414         ldp     d10, d11, [sp, #32]
1415         ldp     d12, d13, [sp, #48]
1416         ldp     d14, d15, [sp, #64]
1417         ldp     fp, lr, [sp], #80
1418         ret
1419
1420 .Lctr_enc_short:
1421         stp     fp, lr, [sp, #-96]!
1422         stp     x19, x20, [sp, #16]
1423         stp     x21, x22, [sp, #32]
1424         str     x23, [sp, #48]
1425
1426         mov     x19, x0                     // copy arguments
1427         mov     x20, x1
1428         mov     x21, x2
1429         mov     x22, x3
1430         ldr     w23, [x4, #12]              // load counter .LSW
1431         ldr     q1, [x4]                    // load whole counter value
1432 #ifdef __ARMEL__
1433         rev     w23, w23
1434 #endif
1435         str     q1, [sp, #80]               // copy counter value
1436
1437 .Lctr_enc_short_loop:
1438         add     x0, sp, #80                 // input counter value
1439         add     x1, sp, #64                 // output on the stack
1440         mov     x2, x22                     // key
1441
1442         bl      AES_encrypt
1443
1444         ldr     q0, [x19], #16              // load input
1445         ldr     q1, [sp, #64]               // load encrypted counter
1446         add     x23, x23, #1
1447 #ifdef __ARMEL__
1448         rev     w0, w23
1449         str     w0, [sp, #80+12]            // next counter value
1450 #else
1451         str     w23, [sp, #80+12]           // next counter value
1452 #endif
1453         eor     v0.16b, v0.16b, v1.16b
1454         str     q0, [x20], #16              // store output
1455         subs    x21, x21, #1
1456         bne     .Lctr_enc_short_loop
1457
1458         movi    v0.16b, #0
1459         movi    v1.16b, #0
1460         stp     q0, q1, [sp, #64]
1461
1462         ldr     x23, [sp, #48]
1463         ldp     x21, x22, [sp, #32]
1464         ldp     x19, x20, [sp, #16]
1465         ldp     fp, lr, [sp], #96
1466         ret
1467 .size   ossl_bsaes_ctr32_encrypt_blocks,.-ossl_bsaes_ctr32_encrypt_blocks
1468
1469 .globl  ossl_bsaes_xts_encrypt
1470 .type   ossl_bsaes_xts_encrypt,%function
1471 .align  4
1472 // On entry:
1473 //   x0 -> input plaintext
1474 //   x1 -> output ciphertext
1475 //   x2 -> length of text in bytes (must be at least 16)
1476 //   x3 -> key1 (used to encrypt the XORed plaintext blocks)
1477 //   x4 -> key2 (used to encrypt the initial vector to yield the initial tweak)
1478 //   x5 -> 16-byte initial vector (typically, sector number)
1479 // On exit:
1480 //   Output ciphertext filled in
1481 //   No output registers, usual AAPCS64 register preservation
1482 ossl_bsaes_xts_encrypt:
1483         // Stack layout:
1484         // sp ->
1485         //        nrounds*128-96 bytes: key schedule
1486         // x19 ->
1487         //        16 bytes: frame record
1488         //        4*16 bytes: tweak storage across _bsaes_encrypt8
1489         //        6*8 bytes: storage for 5 callee-saved general-purpose registers
1490         //        8*8 bytes: storage for 8 callee-saved SIMD registers
1491         stp     fp, lr, [sp, #-192]!
1492         stp     x19, x20, [sp, #80]
1493         stp     x21, x22, [sp, #96]
1494         str     x23, [sp, #112]
1495         stp     d8, d9, [sp, #128]
1496         stp     d10, d11, [sp, #144]
1497         stp     d12, d13, [sp, #160]
1498         stp     d14, d15, [sp, #176]
1499
1500         mov     x19, sp
1501         mov     x20, x0
1502         mov     x21, x1
1503         mov     x22, x2
1504         mov     x23, x3
1505
1506         // generate initial tweak
1507         sub     sp, sp, #16
1508         mov     x0, x5                      // iv[]
1509         mov     x1, sp
1510         mov     x2, x4                      // key2
1511         bl      AES_encrypt
1512         ldr     q11, [sp], #16
1513
1514         ldr     w1, [x23, #240]             // get # of rounds
1515         // allocate the key schedule on the stack
1516         add     x17, sp, #96
1517         sub     x17, x17, x1, lsl #7        // 128 bytes per inner round key, less 96 bytes
1518
1519         // populate the key schedule
1520         mov     x9, x23                     // pass key
1521         mov     x10, x1                     // pass # of rounds
1522         mov     sp, x17
1523         bl      _bsaes_key_convert
1524         eor     v15.16b, v15.16b, v7.16b    // fix up last round key
1525         str     q15, [x17]                  // save last round key
1526
1527         subs    x22, x22, #0x80
1528         blo     .Lxts_enc_short
1529         b       .Lxts_enc_loop
1530
1531 .align  4
1532 .Lxts_enc_loop:
1533         ldr     q8, .Lxts_magic
1534         mov     x10, x1                     // pass rounds
1535         add     x2, x19, #16
1536         ldr     q0, [x20], #16
1537         sshr    v1.2d, v11.2d, #63
1538         mov     x9, sp                      // pass key schedule
1539         ldr     q6, .Lxts_magic+16
1540         add     v2.2d, v11.2d, v11.2d
1541         cmtst   v3.2d, v11.2d, v6.2d
1542         and     v1.16b, v1.16b, v8.16b
1543         ext     v1.16b, v1.16b, v1.16b, #8
1544         and     v3.16b, v3.16b, v8.16b
1545         ldr     q4, [x20], #16
1546         eor     v12.16b, v2.16b, v1.16b
1547         eor     v1.16b, v4.16b, v12.16b
1548         eor     v0.16b, v0.16b, v11.16b
1549         cmtst   v2.2d, v12.2d, v6.2d
1550         add     v4.2d, v12.2d, v12.2d
1551         add     x0, x19, #16
1552         ext     v3.16b, v3.16b, v3.16b, #8
1553         and     v2.16b, v2.16b, v8.16b
1554         eor     v13.16b, v4.16b, v3.16b
1555         ldr     q3, [x20], #16
1556         ext     v4.16b, v2.16b, v2.16b, #8
1557         eor     v2.16b, v3.16b, v13.16b
1558         ldr     q3, [x20], #16
1559         add     v5.2d, v13.2d, v13.2d
1560         cmtst   v7.2d, v13.2d, v6.2d
1561         and     v7.16b, v7.16b, v8.16b
1562         ldr     q9, [x20], #16
1563         ext     v7.16b, v7.16b, v7.16b, #8
1564         ldr     q10, [x20], #16
1565         eor     v14.16b, v5.16b, v4.16b
1566         ldr     q16, [x20], #16
1567         add     v4.2d, v14.2d, v14.2d
1568         eor     v3.16b, v3.16b, v14.16b
1569         eor     v15.16b, v4.16b, v7.16b
1570         add     v5.2d, v15.2d, v15.2d
1571         ldr     q7, [x20], #16
1572         cmtst   v4.2d, v14.2d, v6.2d
1573         and     v17.16b, v4.16b, v8.16b
1574         cmtst   v18.2d, v15.2d, v6.2d
1575         eor     v4.16b, v9.16b, v15.16b
1576         ext     v9.16b, v17.16b, v17.16b, #8
1577         eor     v9.16b, v5.16b, v9.16b
1578         add     v17.2d, v9.2d, v9.2d
1579         and     v18.16b, v18.16b, v8.16b
1580         eor     v5.16b, v10.16b, v9.16b
1581         str     q9, [x2], #16
1582         ext     v10.16b, v18.16b, v18.16b, #8
1583         cmtst   v9.2d, v9.2d, v6.2d
1584         and     v9.16b, v9.16b, v8.16b
1585         eor     v10.16b, v17.16b, v10.16b
1586         cmtst   v17.2d, v10.2d, v6.2d
1587         eor     v6.16b, v16.16b, v10.16b
1588         str     q10, [x2], #16
1589         ext     v9.16b, v9.16b, v9.16b, #8
1590         add     v10.2d, v10.2d, v10.2d
1591         eor     v9.16b, v10.16b, v9.16b
1592         str     q9, [x2], #16
1593         eor     v7.16b, v7.16b, v9.16b
1594         add     v9.2d, v9.2d, v9.2d
1595         and     v8.16b, v17.16b, v8.16b
1596         ext     v8.16b, v8.16b, v8.16b, #8
1597         eor     v8.16b, v9.16b, v8.16b
1598         str     q8, [x2]                    // next round tweak
1599
1600         bl      _bsaes_encrypt8
1601
1602         ldr     q8, [x0], #16
1603         eor     v0.16b, v0.16b, v11.16b
1604         eor     v1.16b, v1.16b, v12.16b
1605         ldr     q9, [x0], #16
1606         eor     v4.16b, v4.16b, v13.16b
1607         eor     v6.16b, v6.16b, v14.16b
1608         ldr     q10, [x0], #16
1609         eor     v3.16b, v3.16b, v15.16b
1610         subs    x22, x22, #0x80
1611         str     q0, [x21], #16
1612         ldr     q11, [x0]                   // next round tweak
1613         str     q1, [x21], #16
1614         eor     v0.16b, v7.16b, v8.16b
1615         eor     v1.16b, v2.16b, v9.16b
1616         str     q4, [x21], #16
1617         eor     v2.16b, v5.16b, v10.16b
1618         str     q6, [x21], #16
1619         str     q3, [x21], #16
1620         str     q0, [x21], #16
1621         str     q1, [x21], #16
1622         str     q2, [x21], #16
1623         bpl     .Lxts_enc_loop
1624
1625 .Lxts_enc_short:
1626         adds    x22, x22, #0x70
1627         bmi     .Lxts_enc_done
1628
1629         ldr     q8, .Lxts_magic
1630         sshr    v1.2d, v11.2d, #63
1631         add     v2.2d, v11.2d, v11.2d
1632         ldr     q9, .Lxts_magic+16
1633         subs    x22, x22, #0x10
1634         ldr     q0, [x20], #16
1635         and     v1.16b, v1.16b, v8.16b
1636         cmtst   v3.2d, v11.2d, v9.2d
1637         ext     v1.16b, v1.16b, v1.16b, #8
1638         and     v3.16b, v3.16b, v8.16b
1639         eor     v12.16b, v2.16b, v1.16b
1640         ext     v1.16b, v3.16b, v3.16b, #8
1641         add     v2.2d, v12.2d, v12.2d
1642         cmtst   v3.2d, v12.2d, v9.2d
1643         eor     v13.16b, v2.16b, v1.16b
1644         and     v22.16b, v3.16b, v8.16b
1645         bmi     .Lxts_enc_1
1646
1647         ext     v2.16b, v22.16b, v22.16b, #8
1648         add     v3.2d, v13.2d, v13.2d
1649         ldr     q1, [x20], #16
1650         cmtst   v4.2d, v13.2d, v9.2d
1651         subs    x22, x22, #0x10
1652         eor     v14.16b, v3.16b, v2.16b
1653         and     v23.16b, v4.16b, v8.16b
1654         bmi     .Lxts_enc_2
1655
1656         ext     v3.16b, v23.16b, v23.16b, #8
1657         add     v4.2d, v14.2d, v14.2d
1658         ldr     q2, [x20], #16
1659         cmtst   v5.2d, v14.2d, v9.2d
1660         eor     v0.16b, v0.16b, v11.16b
1661         subs    x22, x22, #0x10
1662         eor     v15.16b, v4.16b, v3.16b
1663         and     v24.16b, v5.16b, v8.16b
1664         bmi     .Lxts_enc_3
1665
1666         ext     v4.16b, v24.16b, v24.16b, #8
1667         add     v5.2d, v15.2d, v15.2d
1668         ldr     q3, [x20], #16
1669         cmtst   v6.2d, v15.2d, v9.2d
1670         eor     v1.16b, v1.16b, v12.16b
1671         subs    x22, x22, #0x10
1672         eor     v16.16b, v5.16b, v4.16b
1673         and     v25.16b, v6.16b, v8.16b
1674         bmi     .Lxts_enc_4
1675
1676         ext     v5.16b, v25.16b, v25.16b, #8
1677         add     v6.2d, v16.2d, v16.2d
1678         add     x0, x19, #16
1679         cmtst   v7.2d, v16.2d, v9.2d
1680         ldr     q4, [x20], #16
1681         eor     v2.16b, v2.16b, v13.16b
1682         str     q16, [x0], #16
1683         subs    x22, x22, #0x10
1684         eor     v17.16b, v6.16b, v5.16b
1685         and     v26.16b, v7.16b, v8.16b
1686         bmi     .Lxts_enc_5
1687
1688         ext     v7.16b, v26.16b, v26.16b, #8
1689         add     v18.2d, v17.2d, v17.2d
1690         ldr     q5, [x20], #16
1691         eor     v3.16b, v3.16b, v14.16b
1692         str     q17, [x0], #16
1693         subs    x22, x22, #0x10
1694         eor     v18.16b, v18.16b, v7.16b
1695         bmi     .Lxts_enc_6
1696
1697         ldr     q6, [x20], #16
1698         eor     v4.16b, v4.16b, v15.16b
1699         eor     v5.16b, v5.16b, v16.16b
1700         str     q18, [x0]                   // next round tweak
1701         mov     x9, sp                      // pass key schedule
1702         mov     x10, x1
1703         add     x0, x19, #16
1704         sub     x22, x22, #0x10
1705         eor     v6.16b, v6.16b, v17.16b
1706
1707         bl      _bsaes_encrypt8
1708
1709         ldr     q16, [x0], #16
1710         eor     v0.16b, v0.16b, v11.16b
1711         eor     v1.16b, v1.16b, v12.16b
1712         ldr     q17, [x0], #16
1713         eor     v4.16b, v4.16b, v13.16b
1714         eor     v6.16b, v6.16b, v14.16b
1715         eor     v3.16b, v3.16b, v15.16b
1716         ldr     q11, [x0]                   // next round tweak
1717         str     q0, [x21], #16
1718         str     q1, [x21], #16
1719         eor     v0.16b, v7.16b, v16.16b
1720         eor     v1.16b, v2.16b, v17.16b
1721         str     q4, [x21], #16
1722         str     q6, [x21], #16
1723         str     q3, [x21], #16
1724         str     q0, [x21], #16
1725         str     q1, [x21], #16
1726         b       .Lxts_enc_done
1727
1728 .align  4
1729 .Lxts_enc_6:
1730         eor     v4.16b, v4.16b, v15.16b
1731         eor     v5.16b, v5.16b, v16.16b
1732         mov     x9, sp                      // pass key schedule
1733         mov     x10, x1                     // pass rounds
1734         add     x0, x19, #16
1735
1736         bl      _bsaes_encrypt8
1737
1738         ldr     q16, [x0], #16
1739         eor     v0.16b, v0.16b, v11.16b
1740         eor     v1.16b, v1.16b, v12.16b
1741         eor     v4.16b, v4.16b, v13.16b
1742         eor     v6.16b, v6.16b, v14.16b
1743         ldr     q11, [x0]                   // next round tweak
1744         eor     v3.16b, v3.16b, v15.16b
1745         str     q0, [x21], #16
1746         str     q1, [x21], #16
1747         eor     v0.16b, v7.16b, v16.16b
1748         str     q4, [x21], #16
1749         str     q6, [x21], #16
1750         str     q3, [x21], #16
1751         str     q0, [x21], #16
1752         b       .Lxts_enc_done
1753
1754 .align  4
1755 .Lxts_enc_5:
1756         eor     v3.16b, v3.16b, v14.16b
1757         eor     v4.16b, v4.16b, v15.16b
1758         mov     x9, sp                      // pass key schedule
1759         mov     x10, x1                     // pass rounds
1760         add     x0, x19, #16
1761
1762         bl      _bsaes_encrypt8
1763
1764         eor     v0.16b, v0.16b, v11.16b
1765         eor     v1.16b, v1.16b, v12.16b
1766         ldr     q11, [x0]                   // next round tweak
1767         eor     v4.16b, v4.16b, v13.16b
1768         eor     v6.16b, v6.16b, v14.16b
1769         eor     v3.16b, v3.16b, v15.16b
1770         str     q0, [x21], #16
1771         str     q1, [x21], #16
1772         str     q4, [x21], #16
1773         str     q6, [x21], #16
1774         str     q3, [x21], #16
1775         b       .Lxts_enc_done
1776
1777 .align  4
1778 .Lxts_enc_4:
1779         eor     v2.16b, v2.16b, v13.16b
1780         eor     v3.16b, v3.16b, v14.16b
1781         mov     x9, sp                      // pass key schedule
1782         mov     x10, x1                     // pass rounds
1783         add     x0, x19, #16
1784
1785         bl      _bsaes_encrypt8
1786
1787         eor     v0.16b, v0.16b, v11.16b
1788         eor     v1.16b, v1.16b, v12.16b
1789         eor     v4.16b, v4.16b, v13.16b
1790         eor     v6.16b, v6.16b, v14.16b
1791         mov     v11.16b, v15.16b            // next round tweak
1792         str     q0, [x21], #16
1793         str     q1, [x21], #16
1794         str     q4, [x21], #16
1795         str     q6, [x21], #16
1796         b       .Lxts_enc_done
1797
1798 .align  4
1799 .Lxts_enc_3:
1800         eor     v1.16b, v1.16b, v12.16b
1801         eor     v2.16b, v2.16b, v13.16b
1802         mov     x9, sp                      // pass key schedule
1803         mov     x10, x1                     // pass rounds
1804         add     x0, x19, #16
1805
1806         bl      _bsaes_encrypt8
1807
1808         eor     v0.16b, v0.16b, v11.16b
1809         eor     v1.16b, v1.16b, v12.16b
1810         eor     v4.16b, v4.16b, v13.16b
1811         mov     v11.16b, v14.16b            // next round tweak
1812         str     q0, [x21], #16
1813         str     q1, [x21], #16
1814         str     q4, [x21], #16
1815         b       .Lxts_enc_done
1816
1817 .align  4
1818 .Lxts_enc_2:
1819         eor     v0.16b, v0.16b, v11.16b
1820         eor     v1.16b, v1.16b, v12.16b
1821         mov     x9, sp                      // pass key schedule
1822         mov     x10, x1                     // pass rounds
1823         add     x0, x19, #16
1824
1825         bl      _bsaes_encrypt8
1826
1827         eor     v0.16b, v0.16b, v11.16b
1828         eor     v1.16b, v1.16b, v12.16b
1829         mov     v11.16b, v13.16b            // next round tweak
1830         str     q0, [x21], #16
1831         str     q1, [x21], #16
1832         b       .Lxts_enc_done
1833
1834 .align  4
1835 .Lxts_enc_1:
1836         eor     v0.16b, v0.16b, v11.16b
1837         sub     x0, sp, #16
1838         sub     x1, sp, #16
1839         mov     x2, x23
1840         mov     v13.d[0], v11.d[1]          // just in case AES_encrypt corrupts top half of callee-saved SIMD registers
1841         mov     v14.d[0], v12.d[1]
1842         str     q0, [sp, #-16]!
1843
1844         bl      AES_encrypt
1845
1846         ldr     q0, [sp], #16
1847         trn1    v13.2d, v11.2d, v13.2d
1848         trn1    v11.2d, v12.2d, v14.2d      // next round tweak
1849         eor     v0.16b, v0.16b, v13.16b
1850         str     q0, [x21], #16
1851
1852 .Lxts_enc_done:
1853         adds    x22, x22, #0x10
1854         beq     .Lxts_enc_ret
1855
1856         sub     x6, x21, #0x10
1857         // Penultimate plaintext block produces final ciphertext part-block
1858         // plus remaining part of final plaintext block. Move ciphertext part
1859         // to final position and re-use penultimate ciphertext block buffer to
1860         // construct final plaintext block
1861 .Lxts_enc_steal:
1862         ldrb    w0, [x20], #1
1863         ldrb    w1, [x21, #-0x10]
1864         strb    w0, [x21, #-0x10]
1865         strb    w1, [x21], #1
1866
1867         subs    x22, x22, #1
1868         bhi     .Lxts_enc_steal
1869
1870         // Finally encrypt the penultimate ciphertext block using the
1871         // last tweak
1872         ldr     q0, [x6]
1873         eor     v0.16b, v0.16b, v11.16b
1874         str     q0, [sp, #-16]!
1875         mov     x0, sp
1876         mov     x1, sp
1877         mov     x2, x23
1878         mov     x21, x6
1879         mov     v13.d[0], v11.d[1]          // just in case AES_encrypt corrupts top half of callee-saved SIMD registers
1880
1881         bl      AES_encrypt
1882
1883         trn1    v11.2d, v11.2d, v13.2d
1884         ldr     q0, [sp], #16
1885         eor     v0.16b, v0.16b, v11.16b
1886         str     q0, [x21]
1887
1888 .Lxts_enc_ret:
1889
1890         movi    v0.16b, #0
1891         movi    v1.16b, #0
1892 .Lxts_enc_bzero: // wipe key schedule
1893         stp     q0, q1, [sp], #32
1894         cmp     sp, x19
1895         bne     .Lxts_enc_bzero
1896
1897         ldp     x19, x20, [sp, #80]
1898         ldp     x21, x22, [sp, #96]
1899         ldr     x23, [sp, #112]
1900         ldp     d8, d9, [sp, #128]
1901         ldp     d10, d11, [sp, #144]
1902         ldp     d12, d13, [sp, #160]
1903         ldp     d14, d15, [sp, #176]
1904         ldp     fp, lr, [sp], #192
1905         ret
1906 .size   ossl_bsaes_xts_encrypt,.-ossl_bsaes_xts_encrypt
1907
1908 // The assembler doesn't seem capable of de-duplicating these when expressed
1909 // using `ldr qd,=` syntax, so assign a symbolic address
1910 .align  5
1911 .Lxts_magic:
1912 .quad   1, 0x87, 0x4000000000000000, 0x4000000000000000
1913
1914 .globl  ossl_bsaes_xts_decrypt
1915 .type   ossl_bsaes_xts_decrypt,%function
1916 .align  4
1917 // On entry:
1918 //   x0 -> input ciphertext
1919 //   x1 -> output plaintext
1920 //   x2 -> length of text in bytes (must be at least 16)
1921 //   x3 -> key1 (used to decrypt the XORed ciphertext blocks)
1922 //   x4 -> key2 (used to encrypt the initial vector to yield the initial tweak)
1923 //   x5 -> 16-byte initial vector (typically, sector number)
1924 // On exit:
1925 //   Output plaintext filled in
1926 //   No output registers, usual AAPCS64 register preservation
1927 ossl_bsaes_xts_decrypt:
1928         // Stack layout:
1929         // sp ->
1930         //        nrounds*128-96 bytes: key schedule
1931         // x19 ->
1932         //        16 bytes: frame record
1933         //        4*16 bytes: tweak storage across _bsaes_decrypt8
1934         //        6*8 bytes: storage for 5 callee-saved general-purpose registers
1935         //        8*8 bytes: storage for 8 callee-saved SIMD registers
1936         stp     fp, lr, [sp, #-192]!
1937         stp     x19, x20, [sp, #80]
1938         stp     x21, x22, [sp, #96]
1939         str     x23, [sp, #112]
1940         stp     d8, d9, [sp, #128]
1941         stp     d10, d11, [sp, #144]
1942         stp     d12, d13, [sp, #160]
1943         stp     d14, d15, [sp, #176]
1944
1945         mov     x19, sp
1946         mov     x20, x0
1947         mov     x21, x1
1948         mov     x22, x2
1949         mov     x23, x3
1950
1951         // generate initial tweak
1952         sub     sp, sp, #16
1953         mov     x0, x5                      // iv[]
1954         mov     x1, sp
1955         mov     x2, x4                      // key2
1956         bl      AES_encrypt
1957         ldr     q11, [sp], #16
1958
1959         ldr     w1, [x23, #240]             // get # of rounds
1960         // allocate the key schedule on the stack
1961         add     x17, sp, #96
1962         sub     x17, x17, x1, lsl #7        // 128 bytes per inner round key, less 96 bytes
1963
1964         // populate the key schedule
1965         mov     x9, x23                     // pass key
1966         mov     x10, x1                     // pass # of rounds
1967         mov     sp, x17
1968         bl      _bsaes_key_convert
1969         ldr     q6,  [sp]
1970         str     q15, [x17]                  // save last round key
1971         eor     v6.16b, v6.16b, v7.16b      // fix up round 0 key (by XORing with 0x63)
1972         str     q6, [sp]
1973
1974         sub     x30, x22, #0x10
1975         tst     x22, #0xf                   // if not multiple of 16
1976         csel    x22, x30, x22, ne           // subtract another 16 bytes
1977         subs    x22, x22, #0x80
1978
1979         blo     .Lxts_dec_short
1980         b       .Lxts_dec_loop
1981
1982 .align  4
1983 .Lxts_dec_loop:
1984         ldr     q8, .Lxts_magic
1985         mov     x10, x1                     // pass rounds
1986         add     x2, x19, #16
1987         ldr     q0, [x20], #16
1988         sshr    v1.2d, v11.2d, #63
1989         mov     x9, sp                      // pass key schedule
1990         ldr     q6, .Lxts_magic+16
1991         add     v2.2d, v11.2d, v11.2d
1992         cmtst   v3.2d, v11.2d, v6.2d
1993         and     v1.16b, v1.16b, v8.16b
1994         ext     v1.16b, v1.16b, v1.16b, #8
1995         and     v3.16b, v3.16b, v8.16b
1996         ldr     q4, [x20], #16
1997         eor     v12.16b, v2.16b, v1.16b
1998         eor     v1.16b, v4.16b, v12.16b
1999         eor     v0.16b, v0.16b, v11.16b
2000         cmtst   v2.2d, v12.2d, v6.2d
2001         add     v4.2d, v12.2d, v12.2d
2002         add     x0, x19, #16
2003         ext     v3.16b, v3.16b, v3.16b, #8
2004         and     v2.16b, v2.16b, v8.16b
2005         eor     v13.16b, v4.16b, v3.16b
2006         ldr     q3, [x20], #16
2007         ext     v4.16b, v2.16b, v2.16b, #8
2008         eor     v2.16b, v3.16b, v13.16b
2009         ldr     q3, [x20], #16
2010         add     v5.2d, v13.2d, v13.2d
2011         cmtst   v7.2d, v13.2d, v6.2d
2012         and     v7.16b, v7.16b, v8.16b
2013         ldr     q9, [x20], #16
2014         ext     v7.16b, v7.16b, v7.16b, #8
2015         ldr     q10, [x20], #16
2016         eor     v14.16b, v5.16b, v4.16b
2017         ldr     q16, [x20], #16
2018         add     v4.2d, v14.2d, v14.2d
2019         eor     v3.16b, v3.16b, v14.16b
2020         eor     v15.16b, v4.16b, v7.16b
2021         add     v5.2d, v15.2d, v15.2d
2022         ldr     q7, [x20], #16
2023         cmtst   v4.2d, v14.2d, v6.2d
2024         and     v17.16b, v4.16b, v8.16b
2025         cmtst   v18.2d, v15.2d, v6.2d
2026         eor     v4.16b, v9.16b, v15.16b
2027         ext     v9.16b, v17.16b, v17.16b, #8
2028         eor     v9.16b, v5.16b, v9.16b
2029         add     v17.2d, v9.2d, v9.2d
2030         and     v18.16b, v18.16b, v8.16b
2031         eor     v5.16b, v10.16b, v9.16b
2032         str     q9, [x2], #16
2033         ext     v10.16b, v18.16b, v18.16b, #8
2034         cmtst   v9.2d, v9.2d, v6.2d
2035         and     v9.16b, v9.16b, v8.16b
2036         eor     v10.16b, v17.16b, v10.16b
2037         cmtst   v17.2d, v10.2d, v6.2d
2038         eor     v6.16b, v16.16b, v10.16b
2039         str     q10, [x2], #16
2040         ext     v9.16b, v9.16b, v9.16b, #8
2041         add     v10.2d, v10.2d, v10.2d
2042         eor     v9.16b, v10.16b, v9.16b
2043         str     q9, [x2], #16
2044         eor     v7.16b, v7.16b, v9.16b
2045         add     v9.2d, v9.2d, v9.2d
2046         and     v8.16b, v17.16b, v8.16b
2047         ext     v8.16b, v8.16b, v8.16b, #8
2048         eor     v8.16b, v9.16b, v8.16b
2049         str     q8, [x2]                    // next round tweak
2050
2051         bl      _bsaes_decrypt8
2052
2053         eor     v6.16b, v6.16b, v13.16b
2054         eor     v0.16b, v0.16b, v11.16b
2055         ldr     q8, [x0], #16
2056         eor     v7.16b, v7.16b, v8.16b
2057         str     q0, [x21], #16
2058         eor     v0.16b, v1.16b, v12.16b
2059         ldr     q1, [x0], #16
2060         eor     v1.16b, v3.16b, v1.16b
2061         subs    x22, x22, #0x80
2062         eor     v2.16b, v2.16b, v15.16b
2063         eor     v3.16b, v4.16b, v14.16b
2064         ldr     q4, [x0], #16
2065         str     q0, [x21], #16
2066         ldr     q11, [x0]                   // next round tweak
2067         eor     v0.16b, v5.16b, v4.16b
2068         str     q6, [x21], #16
2069         str     q3, [x21], #16
2070         str     q2, [x21], #16
2071         str     q7, [x21], #16
2072         str     q1, [x21], #16
2073         str     q0, [x21], #16
2074         bpl     .Lxts_dec_loop
2075
2076 .Lxts_dec_short:
2077         adds    x22, x22, #0x70
2078         bmi     .Lxts_dec_done
2079
2080         ldr     q8, .Lxts_magic
2081         sshr    v1.2d, v11.2d, #63
2082         add     v2.2d, v11.2d, v11.2d
2083         ldr     q9, .Lxts_magic+16
2084         subs    x22, x22, #0x10
2085         ldr     q0, [x20], #16
2086         and     v1.16b, v1.16b, v8.16b
2087         cmtst   v3.2d, v11.2d, v9.2d
2088         ext     v1.16b, v1.16b, v1.16b, #8
2089         and     v3.16b, v3.16b, v8.16b
2090         eor     v12.16b, v2.16b, v1.16b
2091         ext     v1.16b, v3.16b, v3.16b, #8
2092         add     v2.2d, v12.2d, v12.2d
2093         cmtst   v3.2d, v12.2d, v9.2d
2094         eor     v13.16b, v2.16b, v1.16b
2095         and     v22.16b, v3.16b, v8.16b
2096         bmi     .Lxts_dec_1
2097
2098         ext     v2.16b, v22.16b, v22.16b, #8
2099         add     v3.2d, v13.2d, v13.2d
2100         ldr     q1, [x20], #16
2101         cmtst   v4.2d, v13.2d, v9.2d
2102         subs    x22, x22, #0x10
2103         eor     v14.16b, v3.16b, v2.16b
2104         and     v23.16b, v4.16b, v8.16b
2105         bmi     .Lxts_dec_2
2106
2107         ext     v3.16b, v23.16b, v23.16b, #8
2108         add     v4.2d, v14.2d, v14.2d
2109         ldr     q2, [x20], #16
2110         cmtst   v5.2d, v14.2d, v9.2d
2111         eor     v0.16b, v0.16b, v11.16b
2112         subs    x22, x22, #0x10
2113         eor     v15.16b, v4.16b, v3.16b
2114         and     v24.16b, v5.16b, v8.16b
2115         bmi     .Lxts_dec_3
2116
2117         ext     v4.16b, v24.16b, v24.16b, #8
2118         add     v5.2d, v15.2d, v15.2d
2119         ldr     q3, [x20], #16
2120         cmtst   v6.2d, v15.2d, v9.2d
2121         eor     v1.16b, v1.16b, v12.16b
2122         subs    x22, x22, #0x10
2123         eor     v16.16b, v5.16b, v4.16b
2124         and     v25.16b, v6.16b, v8.16b
2125         bmi     .Lxts_dec_4
2126
2127         ext     v5.16b, v25.16b, v25.16b, #8
2128         add     v6.2d, v16.2d, v16.2d
2129         add     x0, x19, #16
2130         cmtst   v7.2d, v16.2d, v9.2d
2131         ldr     q4, [x20], #16
2132         eor     v2.16b, v2.16b, v13.16b
2133         str     q16, [x0], #16
2134         subs    x22, x22, #0x10
2135         eor     v17.16b, v6.16b, v5.16b
2136         and     v26.16b, v7.16b, v8.16b
2137         bmi     .Lxts_dec_5
2138
2139         ext     v7.16b, v26.16b, v26.16b, #8
2140         add     v18.2d, v17.2d, v17.2d
2141         ldr     q5, [x20], #16
2142         eor     v3.16b, v3.16b, v14.16b
2143         str     q17, [x0], #16
2144         subs    x22, x22, #0x10
2145         eor     v18.16b, v18.16b, v7.16b
2146         bmi     .Lxts_dec_6
2147
2148         ldr     q6, [x20], #16
2149         eor     v4.16b, v4.16b, v15.16b
2150         eor     v5.16b, v5.16b, v16.16b
2151         str     q18, [x0]                   // next round tweak
2152         mov     x9, sp                      // pass key schedule
2153         mov     x10, x1
2154         add     x0, x19, #16
2155         sub     x22, x22, #0x10
2156         eor     v6.16b, v6.16b, v17.16b
2157
2158         bl      _bsaes_decrypt8
2159
2160         ldr     q16, [x0], #16
2161         eor     v0.16b, v0.16b, v11.16b
2162         eor     v1.16b, v1.16b, v12.16b
2163         ldr     q17, [x0], #16
2164         eor     v6.16b, v6.16b, v13.16b
2165         eor     v4.16b, v4.16b, v14.16b
2166         eor     v2.16b, v2.16b, v15.16b
2167         ldr     q11, [x0]                   // next round tweak
2168         str     q0, [x21], #16
2169         str     q1, [x21], #16
2170         eor     v0.16b, v7.16b, v16.16b
2171         eor     v1.16b, v3.16b, v17.16b
2172         str     q6, [x21], #16
2173         str     q4, [x21], #16
2174         str     q2, [x21], #16
2175         str     q0, [x21], #16
2176         str     q1, [x21], #16
2177         b       .Lxts_dec_done
2178
2179 .align  4
2180 .Lxts_dec_6:
2181         eor     v4.16b, v4.16b, v15.16b
2182         eor     v5.16b, v5.16b, v16.16b
2183         mov     x9, sp                      // pass key schedule
2184         mov     x10, x1                     // pass rounds
2185         add     x0, x19, #16
2186
2187         bl      _bsaes_decrypt8
2188
2189         ldr     q16, [x0], #16
2190         eor     v0.16b, v0.16b, v11.16b
2191         eor     v1.16b, v1.16b, v12.16b
2192         eor     v6.16b, v6.16b, v13.16b
2193         eor     v4.16b, v4.16b, v14.16b
2194         ldr     q11, [x0]                   // next round tweak
2195         eor     v2.16b, v2.16b, v15.16b
2196         str     q0, [x21], #16
2197         str     q1, [x21], #16
2198         eor     v0.16b, v7.16b, v16.16b
2199         str     q6, [x21], #16
2200         str     q4, [x21], #16
2201         str     q2, [x21], #16
2202         str     q0, [x21], #16
2203         b       .Lxts_dec_done
2204
2205 .align  4
2206 .Lxts_dec_5:
2207         eor     v3.16b, v3.16b, v14.16b
2208         eor     v4.16b, v4.16b, v15.16b
2209         mov     x9, sp                      // pass key schedule
2210         mov     x10, x1                     // pass rounds
2211         add     x0, x19, #16
2212
2213         bl      _bsaes_decrypt8
2214
2215         eor     v0.16b, v0.16b, v11.16b
2216         eor     v1.16b, v1.16b, v12.16b
2217         ldr     q11, [x0]                   // next round tweak
2218         eor     v6.16b, v6.16b, v13.16b
2219         eor     v4.16b, v4.16b, v14.16b
2220         eor     v2.16b, v2.16b, v15.16b
2221         str     q0, [x21], #16
2222         str     q1, [x21], #16
2223         str     q6, [x21], #16
2224         str     q4, [x21], #16
2225         str     q2, [x21], #16
2226         b       .Lxts_dec_done
2227
2228 .align  4
2229 .Lxts_dec_4:
2230         eor     v2.16b, v2.16b, v13.16b
2231         eor     v3.16b, v3.16b, v14.16b
2232         mov     x9, sp                      // pass key schedule
2233         mov     x10, x1                     // pass rounds
2234         add     x0, x19, #16
2235
2236         bl      _bsaes_decrypt8
2237
2238         eor     v0.16b, v0.16b, v11.16b
2239         eor     v1.16b, v1.16b, v12.16b
2240         eor     v6.16b, v6.16b, v13.16b
2241         eor     v4.16b, v4.16b, v14.16b
2242         mov     v11.16b, v15.16b            // next round tweak
2243         str     q0, [x21], #16
2244         str     q1, [x21], #16
2245         str     q6, [x21], #16
2246         str     q4, [x21], #16
2247         b       .Lxts_dec_done
2248
2249 .align  4
2250 .Lxts_dec_3:
2251         eor     v1.16b, v1.16b, v12.16b
2252         eor     v2.16b, v2.16b, v13.16b
2253         mov     x9, sp                      // pass key schedule
2254         mov     x10, x1                     // pass rounds
2255         add     x0, x19, #16
2256
2257         bl      _bsaes_decrypt8
2258
2259         eor     v0.16b, v0.16b, v11.16b
2260         eor     v1.16b, v1.16b, v12.16b
2261         eor     v6.16b, v6.16b, v13.16b
2262         mov     v11.16b, v14.16b            // next round tweak
2263         str     q0, [x21], #16
2264         str     q1, [x21], #16
2265         str     q6, [x21], #16
2266         b       .Lxts_dec_done
2267
2268 .align  4
2269 .Lxts_dec_2:
2270         eor     v0.16b, v0.16b, v11.16b
2271         eor     v1.16b, v1.16b, v12.16b
2272         mov     x9, sp                      // pass key schedule
2273         mov     x10, x1                     // pass rounds
2274         add     x0, x19, #16
2275
2276         bl      _bsaes_decrypt8
2277
2278         eor     v0.16b, v0.16b, v11.16b
2279         eor     v1.16b, v1.16b, v12.16b
2280         mov     v11.16b, v13.16b            // next round tweak
2281         str     q0, [x21], #16
2282         str     q1, [x21], #16
2283         b       .Lxts_dec_done
2284
2285 .align  4
2286 .Lxts_dec_1:
2287         eor     v0.16b, v0.16b, v11.16b
2288         sub     x0, sp, #16
2289         sub     x1, sp, #16
2290         mov     x2, x23
2291         mov     v13.d[0], v11.d[1]          // just in case AES_decrypt corrupts top half of callee-saved SIMD registers
2292         mov     v14.d[0], v12.d[1]
2293         str     q0, [sp, #-16]!
2294
2295         bl      AES_decrypt
2296
2297         ldr     q0, [sp], #16
2298         trn1    v13.2d, v11.2d, v13.2d
2299         trn1    v11.2d, v12.2d, v14.2d      // next round tweak
2300         eor     v0.16b, v0.16b, v13.16b
2301         str     q0, [x21], #16
2302
2303 .Lxts_dec_done:
2304         adds    x22, x22, #0x10
2305         beq     .Lxts_dec_ret
2306
2307         // calculate one round of extra tweak for the stolen ciphertext
2308         ldr     q8, .Lxts_magic
2309         sshr    v6.2d, v11.2d, #63
2310         and     v6.16b, v6.16b, v8.16b
2311         add     v12.2d, v11.2d, v11.2d
2312         ext     v6.16b, v6.16b, v6.16b, #8
2313         eor     v12.16b, v12.16b, v6.16b
2314
2315         // perform the final decryption with the last tweak value
2316         ldr     q0, [x20], #16
2317         eor     v0.16b, v0.16b, v12.16b
2318         str     q0, [sp, #-16]!
2319         mov     x0, sp
2320         mov     x1, sp
2321         mov     x2, x23
2322         mov     v13.d[0], v11.d[1]          // just in case AES_decrypt corrupts top half of callee-saved SIMD registers
2323         mov     v14.d[0], v12.d[1]
2324
2325         bl      AES_decrypt
2326
2327         trn1    v12.2d, v12.2d, v14.2d
2328         trn1    v11.2d, v11.2d, v13.2d
2329         ldr     q0, [sp], #16
2330         eor     v0.16b, v0.16b, v12.16b
2331         str     q0, [x21]
2332
2333         mov     x6, x21
2334         // Penultimate ciphertext block produces final plaintext part-block
2335         // plus remaining part of final ciphertext block. Move plaintext part
2336         // to final position and re-use penultimate plaintext block buffer to
2337         // construct final ciphertext block
2338 .Lxts_dec_steal:
2339         ldrb    w1, [x21]
2340         ldrb    w0, [x20], #1
2341         strb    w1, [x21, #0x10]
2342         strb    w0, [x21], #1
2343
2344         subs    x22, x22, #1
2345         bhi     .Lxts_dec_steal
2346
2347         // Finally decrypt the penultimate plaintext block using the
2348         // penultimate tweak
2349         ldr     q0, [x6]
2350         eor     v0.16b, v0.16b, v11.16b
2351         str     q0, [sp, #-16]!
2352         mov     x0, sp
2353         mov     x1, sp
2354         mov     x2, x23
2355         mov     x21, x6
2356
2357         bl      AES_decrypt
2358
2359         trn1    v11.2d, v11.2d, v13.2d
2360         ldr     q0, [sp], #16
2361         eor     v0.16b, v0.16b, v11.16b
2362         str     q0, [x21]
2363
2364 .Lxts_dec_ret:
2365
2366         movi    v0.16b, #0
2367         movi    v1.16b, #0
2368 .Lxts_dec_bzero: // wipe key schedule
2369         stp     q0, q1, [sp], #32
2370         cmp     sp, x19
2371         bne     .Lxts_dec_bzero
2372
2373         ldp     x19, x20, [sp, #80]
2374         ldp     x21, x22, [sp, #96]
2375         ldr     x23, [sp, #112]
2376         ldp     d8, d9, [sp, #128]
2377         ldp     d10, d11, [sp, #144]
2378         ldp     d12, d13, [sp, #160]
2379         ldp     d14, d15, [sp, #176]
2380         ldp     fp, lr, [sp], #192
2381         ret
2382 .size   ossl_bsaes_xts_decrypt,.-ossl_bsaes_xts_decrypt