• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1@ Copyright 2012-2023 The OpenSSL Project Authors. All Rights Reserved.
2@
3@ Licensed under the Apache License 2.0 (the "License").  You may not use
4@ this file except in compliance with the License.  You can obtain a copy
5@ in the file LICENSE in the source distribution or at
6@ https://www.openssl.org/source/license.html
7
8
9@ ====================================================================
10@ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
11@ project. The module is, however, dual licensed under OpenSSL and
12@ CRYPTOGAMS licenses depending on where you obtain it. For further
13@ details see http://www.openssl.org/~appro/cryptogams/.
14@
15@ Specific modes and adaptation for Linux kernel by Ard Biesheuvel
16@ of Linaro.
17@ ====================================================================
18
19@ Bit-sliced AES for ARM NEON
20@
21@ February 2012.
22@
23@ This implementation is direct adaptation of bsaes-x86_64 module for
24@ ARM NEON. Except that this module is endian-neutral [in sense that
25@ it can be compiled for either endianness] by courtesy of vld1.8's
26@ neutrality. Initial version doesn't implement interface to OpenSSL,
27@ only low-level primitives and unsupported entry points, just enough
28@ to collect performance results, which for Cortex-A8 core are:
29@
30@ encrypt	19.5 cycles per byte processed with 128-bit key
31@ decrypt	22.1 cycles per byte processed with 128-bit key
32@ key conv.	440  cycles per 128-bit key/0.18 of 8x block
33@
34@ Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7,
35@ which is [much] worse than anticipated (for further details see
36@ http://www.openssl.org/~appro/Snapdragon-S4.html).
37@
38@ Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code
39@ manages in 20.0 cycles].
40@
41@ When comparing to x86_64 results keep in mind that NEON unit is
42@ [mostly] single-issue and thus can't [fully] benefit from
43@ instruction-level parallelism. And when comparing to aes-armv4
44@ results keep in mind key schedule conversion overhead (see
45@ bsaes-x86_64.pl for further details)...
46@
47@						<appro@openssl.org>
48
49@ April-August 2013
50@ Add CBC, CTR and XTS subroutines and adapt for kernel use; courtesy of Ard.
51
52@ $output is the last argument if it looks like a file (it has an extension)
53@ $flavour is the first argument if it doesn't look like a file
54#ifndef __KERNEL__
55# include "arm_arch.h"
56
57# define VFP_ABI_PUSH	vstmdb	sp!,{d8-d15}
58# define VFP_ABI_POP	vldmia	sp!,{d8-d15}
59# define VFP_ABI_FRAME	0x40
60#else
61# define VFP_ABI_PUSH
62# define VFP_ABI_POP
63# define VFP_ABI_FRAME	0
64# define BSAES_ASM_EXTENDED_KEY
65# define XTS_CHAIN_TWEAK
66# define __ARM_ARCH__ __LINUX_ARM_ARCH__
67# define __ARM_MAX_ARCH__ 7
68#endif
69
70#ifdef __thumb__
71# define adrl adr
72#endif
73
74#if __ARM_MAX_ARCH__>=7
75.arch	armv7-a
76.fpu	neon
77
78.syntax	unified 	@ ARMv7-capable assembler is expected to handle this
79#if defined(__thumb2__) && !defined(__APPLE__)
80.thumb
81#else
82.code	32
83# undef __thumb2__
84#endif
85
86.text
87
88.type	_bsaes_decrypt8,%function
89.align	4
90_bsaes_decrypt8:
91	adr	r6,.
92	vldmia	r4!, {q9}		@ round 0 key
93#if defined(__thumb2__) || defined(__APPLE__)
94	adr	r6,.LM0ISR
95#else
96	add	r6,r6,#.LM0ISR-_bsaes_decrypt8
97#endif
98
99	vldmia	r6!, {q8}		@ .LM0ISR
100	veor	q10, q0, q9	@ xor with round0 key
101	veor	q11, q1, q9
102	vtbl.8	d0, {q10}, d16
103	vtbl.8	d1, {q10}, d17
104	veor	q12, q2, q9
105	vtbl.8	d2, {q11}, d16
106	vtbl.8	d3, {q11}, d17
107	veor	q13, q3, q9
108	vtbl.8	d4, {q12}, d16
109	vtbl.8	d5, {q12}, d17
110	veor	q14, q4, q9
111	vtbl.8	d6, {q13}, d16
112	vtbl.8	d7, {q13}, d17
113	veor	q15, q5, q9
114	vtbl.8	d8, {q14}, d16
115	vtbl.8	d9, {q14}, d17
116	veor	q10, q6, q9
117	vtbl.8	d10, {q15}, d16
118	vtbl.8	d11, {q15}, d17
119	veor	q11, q7, q9
120	vtbl.8	d12, {q10}, d16
121	vtbl.8	d13, {q10}, d17
122	vtbl.8	d14, {q11}, d16
123	vtbl.8	d15, {q11}, d17
124	vmov.i8	q8,#0x55			@ compose .LBS0
125	vmov.i8	q9,#0x33			@ compose .LBS1
126	vshr.u64	q10, q6, #1
127	vshr.u64	q11, q4, #1
128	veor	q10, q10, q7
129	veor	q11, q11, q5
130	vand	q10, q10, q8
131	vand	q11, q11, q8
132	veor	q7, q7, q10
133	vshl.u64	q10, q10, #1
134	veor	q5, q5, q11
135	vshl.u64	q11, q11, #1
136	veor	q6, q6, q10
137	veor	q4, q4, q11
138	vshr.u64	q10, q2, #1
139	vshr.u64	q11, q0, #1
140	veor	q10, q10, q3
141	veor	q11, q11, q1
142	vand	q10, q10, q8
143	vand	q11, q11, q8
144	veor	q3, q3, q10
145	vshl.u64	q10, q10, #1
146	veor	q1, q1, q11
147	vshl.u64	q11, q11, #1
148	veor	q2, q2, q10
149	veor	q0, q0, q11
150	vmov.i8	q8,#0x0f			@ compose .LBS2
151	vshr.u64	q10, q5, #2
152	vshr.u64	q11, q4, #2
153	veor	q10, q10, q7
154	veor	q11, q11, q6
155	vand	q10, q10, q9
156	vand	q11, q11, q9
157	veor	q7, q7, q10
158	vshl.u64	q10, q10, #2
159	veor	q6, q6, q11
160	vshl.u64	q11, q11, #2
161	veor	q5, q5, q10
162	veor	q4, q4, q11
163	vshr.u64	q10, q1, #2
164	vshr.u64	q11, q0, #2
165	veor	q10, q10, q3
166	veor	q11, q11, q2
167	vand	q10, q10, q9
168	vand	q11, q11, q9
169	veor	q3, q3, q10
170	vshl.u64	q10, q10, #2
171	veor	q2, q2, q11
172	vshl.u64	q11, q11, #2
173	veor	q1, q1, q10
174	veor	q0, q0, q11
175	vshr.u64	q10, q3, #4
176	vshr.u64	q11, q2, #4
177	veor	q10, q10, q7
178	veor	q11, q11, q6
179	vand	q10, q10, q8
180	vand	q11, q11, q8
181	veor	q7, q7, q10
182	vshl.u64	q10, q10, #4
183	veor	q6, q6, q11
184	vshl.u64	q11, q11, #4
185	veor	q3, q3, q10
186	veor	q2, q2, q11
187	vshr.u64	q10, q1, #4
188	vshr.u64	q11, q0, #4
189	veor	q10, q10, q5
190	veor	q11, q11, q4
191	vand	q10, q10, q8
192	vand	q11, q11, q8
193	veor	q5, q5, q10
194	vshl.u64	q10, q10, #4
195	veor	q4, q4, q11
196	vshl.u64	q11, q11, #4
197	veor	q1, q1, q10
198	veor	q0, q0, q11
199	sub	r5,r5,#1
200	b	.Ldec_sbox
201.align	4
202.Ldec_loop:
203	vldmia	r4!, {q8,q9,q10,q11}
204	veor	q8, q8, q0
205	veor	q9, q9, q1
206	vtbl.8	d0, {q8}, d24
207	vtbl.8	d1, {q8}, d25
208	vldmia	r4!, {q8}
209	veor	q10, q10, q2
210	vtbl.8	d2, {q9}, d24
211	vtbl.8	d3, {q9}, d25
212	vldmia	r4!, {q9}
213	veor	q11, q11, q3
214	vtbl.8	d4, {q10}, d24
215	vtbl.8	d5, {q10}, d25
216	vldmia	r4!, {q10}
217	vtbl.8	d6, {q11}, d24
218	vtbl.8	d7, {q11}, d25
219	vldmia	r4!, {q11}
220	veor	q8, q8, q4
221	veor	q9, q9, q5
222	vtbl.8	d8, {q8}, d24
223	vtbl.8	d9, {q8}, d25
224	veor	q10, q10, q6
225	vtbl.8	d10, {q9}, d24
226	vtbl.8	d11, {q9}, d25
227	veor	q11, q11, q7
228	vtbl.8	d12, {q10}, d24
229	vtbl.8	d13, {q10}, d25
230	vtbl.8	d14, {q11}, d24
231	vtbl.8	d15, {q11}, d25
232.Ldec_sbox:
233	veor	q1, q1, q4
234	veor	q3, q3, q4
235
236	veor	q4, q4, q7
237	veor	q1, q1, q6
238	veor	q2, q2, q7
239	veor	q6, q6, q4
240
241	veor	q0, q0, q1
242	veor	q2, q2, q5
243	veor	q7, q7, q6
244	veor	q3, q3, q0
245	veor	q5, q5, q0
246	veor	q1, q1, q3
247	veor	q11, q3, q0
248	veor	q10, q7, q4
249	veor	q9, q1, q6
250	veor	q13, q4, q0
251	vmov	q8, q10
252	veor	q12, q5, q2
253
254	vorr	q10, q10, q9
255	veor	q15, q11, q8
256	vand	q14, q11, q12
257	vorr	q11, q11, q12
258	veor	q12, q12, q9
259	vand	q8, q8, q9
260	veor	q9, q6, q2
261	vand	q15, q15, q12
262	vand	q13, q13, q9
263	veor	q9, q3, q7
264	veor	q12, q1, q5
265	veor	q11, q11, q13
266	veor	q10, q10, q13
267	vand	q13, q9, q12
268	vorr	q9, q9, q12
269	veor	q11, q11, q15
270	veor	q8, q8, q13
271	veor	q10, q10, q14
272	veor	q9, q9, q15
273	veor	q8, q8, q14
274	vand	q12, q4, q6
275	veor	q9, q9, q14
276	vand	q13, q0, q2
277	vand	q14, q7, q1
278	vorr	q15, q3, q5
279	veor	q11, q11, q12
280	veor	q9, q9, q14
281	veor	q8, q8, q15
282	veor	q10, q10, q13
283
284	@ Inv_GF16 	0, 	1, 	2, 	3, s0, s1, s2, s3
285
286	@ new smaller inversion
287
288	vand	q14, q11, q9
289	vmov	q12, q8
290
291	veor	q13, q10, q14
292	veor	q15, q8, q14
293	veor	q14, q8, q14	@ q14=q15
294
295	vbsl	q13, q9, q8
296	vbsl	q15, q11, q10
297	veor	q11, q11, q10
298
299	vbsl	q12, q13, q14
300	vbsl	q8, q14, q13
301
302	vand	q14, q12, q15
303	veor	q9, q9, q8
304
305	veor	q14, q14, q11
306	veor	q12, q5, q2
307	veor	q8, q1, q6
308	veor	q10, q15, q14
309	vand	q10, q10, q5
310	veor	q5, q5, q1
311	vand	q11, q1, q15
312	vand	q5, q5, q14
313	veor	q1, q11, q10
314	veor	q5, q5, q11
315	veor	q15, q15, q13
316	veor	q14, q14, q9
317	veor	q11, q15, q14
318	veor	q10, q13, q9
319	vand	q11, q11, q12
320	vand	q10, q10, q2
321	veor	q12, q12, q8
322	veor	q2, q2, q6
323	vand	q8, q8, q15
324	vand	q6, q6, q13
325	vand	q12, q12, q14
326	vand	q2, q2, q9
327	veor	q8, q8, q12
328	veor	q2, q2, q6
329	veor	q12, q12, q11
330	veor	q6, q6, q10
331	veor	q5, q5, q12
332	veor	q2, q2, q12
333	veor	q1, q1, q8
334	veor	q6, q6, q8
335
336	veor	q12, q3, q0
337	veor	q8, q7, q4
338	veor	q11, q15, q14
339	veor	q10, q13, q9
340	vand	q11, q11, q12
341	vand	q10, q10, q0
342	veor	q12, q12, q8
343	veor	q0, q0, q4
344	vand	q8, q8, q15
345	vand	q4, q4, q13
346	vand	q12, q12, q14
347	vand	q0, q0, q9
348	veor	q8, q8, q12
349	veor	q0, q0, q4
350	veor	q12, q12, q11
351	veor	q4, q4, q10
352	veor	q15, q15, q13
353	veor	q14, q14, q9
354	veor	q10, q15, q14
355	vand	q10, q10, q3
356	veor	q3, q3, q7
357	vand	q11, q7, q15
358	vand	q3, q3, q14
359	veor	q7, q11, q10
360	veor	q3, q3, q11
361	veor	q3, q3, q12
362	veor	q0, q0, q12
363	veor	q7, q7, q8
364	veor	q4, q4, q8
365	veor	q1, q1, q7
366	veor	q6, q6, q5
367
368	veor	q4, q4, q1
369	veor	q2, q2, q7
370	veor	q5, q5, q7
371	veor	q4, q4, q2
372	veor	q7, q7, q0
373	veor	q4, q4, q5
374	veor	q3, q3, q6
375	veor	q6, q6, q1
376	veor	q3, q3, q4
377
378	veor	q4, q4, q0
379	veor	q7, q7, q3
380	subs	r5,r5,#1
381	bcc	.Ldec_done
382	@ multiplication by 0x05-0x00-0x04-0x00
383	vext.8	q8, q0, q0, #8
384	vext.8	q14, q3, q3, #8
385	vext.8	q15, q5, q5, #8
386	veor	q8, q8, q0
387	vext.8	q9, q1, q1, #8
388	veor	q14, q14, q3
389	vext.8	q10, q6, q6, #8
390	veor	q15, q15, q5
391	vext.8	q11, q4, q4, #8
392	veor	q9, q9, q1
393	vext.8	q12, q2, q2, #8
394	veor	q10, q10, q6
395	vext.8	q13, q7, q7, #8
396	veor	q11, q11, q4
397	veor	q12, q12, q2
398	veor	q13, q13, q7
399
400	veor	q0, q0, q14
401	veor	q1, q1, q14
402	veor	q6, q6, q8
403	veor	q2, q2, q10
404	veor	q4, q4, q9
405	veor	q1, q1, q15
406	veor	q6, q6, q15
407	veor	q2, q2, q14
408	veor	q7, q7, q11
409	veor	q4, q4, q14
410	veor	q3, q3, q12
411	veor	q2, q2, q15
412	veor	q7, q7, q15
413	veor	q5, q5, q13
414	vext.8	q8, q0, q0, #12	@ x0 <<< 32
415	vext.8	q9, q1, q1, #12
416	veor	q0, q0, q8		@ x0 ^ (x0 <<< 32)
417	vext.8	q10, q6, q6, #12
418	veor	q1, q1, q9
419	vext.8	q11, q4, q4, #12
420	veor	q6, q6, q10
421	vext.8	q12, q2, q2, #12
422	veor	q4, q4, q11
423	vext.8	q13, q7, q7, #12
424	veor	q2, q2, q12
425	vext.8	q14, q3, q3, #12
426	veor	q7, q7, q13
427	vext.8	q15, q5, q5, #12
428	veor	q3, q3, q14
429
430	veor	q9, q9, q0
431	veor	q5, q5, q15
432	vext.8	q0, q0, q0, #8		@ (x0 ^ (x0 <<< 32)) <<< 64)
433	veor	q10, q10, q1
434	veor	q8, q8, q5
435	veor	q9, q9, q5
436	vext.8	q1, q1, q1, #8
437	veor	q13, q13, q2
438	veor	q0, q0, q8
439	veor	q14, q14, q7
440	veor	q1, q1, q9
441	vext.8	q8, q2, q2, #8
442	veor	q12, q12, q4
443	vext.8	q9, q7, q7, #8
444	veor	q15, q15, q3
445	vext.8	q2, q4, q4, #8
446	veor	q11, q11, q6
447	vext.8	q7, q5, q5, #8
448	veor	q12, q12, q5
449	vext.8	q4, q3, q3, #8
450	veor	q11, q11, q5
451	vext.8	q3, q6, q6, #8
452	veor	q5, q9, q13
453	veor	q11, q11, q2
454	veor	q7, q7, q15
455	veor	q6, q4, q14
456	veor	q4, q8, q12
457	veor	q2, q3, q10
458	vmov	q3, q11
459	 @ vmov	q5, q9
460	vldmia	r6, {q12}		@ .LISR
461	ite	eq				@ Thumb2 thing, sanity check in ARM
462	addeq	r6,r6,#0x10
463	bne	.Ldec_loop
464	vldmia	r6, {q12}		@ .LISRM0
465	b	.Ldec_loop
466.align	4
467.Ldec_done:
468	vmov.i8	q8,#0x55			@ compose .LBS0
469	vmov.i8	q9,#0x33			@ compose .LBS1
470	vshr.u64	q10, q3, #1
471	vshr.u64	q11, q2, #1
472	veor	q10, q10, q5
473	veor	q11, q11, q7
474	vand	q10, q10, q8
475	vand	q11, q11, q8
476	veor	q5, q5, q10
477	vshl.u64	q10, q10, #1
478	veor	q7, q7, q11
479	vshl.u64	q11, q11, #1
480	veor	q3, q3, q10
481	veor	q2, q2, q11
482	vshr.u64	q10, q6, #1
483	vshr.u64	q11, q0, #1
484	veor	q10, q10, q4
485	veor	q11, q11, q1
486	vand	q10, q10, q8
487	vand	q11, q11, q8
488	veor	q4, q4, q10
489	vshl.u64	q10, q10, #1
490	veor	q1, q1, q11
491	vshl.u64	q11, q11, #1
492	veor	q6, q6, q10
493	veor	q0, q0, q11
494	vmov.i8	q8,#0x0f			@ compose .LBS2
495	vshr.u64	q10, q7, #2
496	vshr.u64	q11, q2, #2
497	veor	q10, q10, q5
498	veor	q11, q11, q3
499	vand	q10, q10, q9
500	vand	q11, q11, q9
501	veor	q5, q5, q10
502	vshl.u64	q10, q10, #2
503	veor	q3, q3, q11
504	vshl.u64	q11, q11, #2
505	veor	q7, q7, q10
506	veor	q2, q2, q11
507	vshr.u64	q10, q1, #2
508	vshr.u64	q11, q0, #2
509	veor	q10, q10, q4
510	veor	q11, q11, q6
511	vand	q10, q10, q9
512	vand	q11, q11, q9
513	veor	q4, q4, q10
514	vshl.u64	q10, q10, #2
515	veor	q6, q6, q11
516	vshl.u64	q11, q11, #2
517	veor	q1, q1, q10
518	veor	q0, q0, q11
519	vshr.u64	q10, q4, #4
520	vshr.u64	q11, q6, #4
521	veor	q10, q10, q5
522	veor	q11, q11, q3
523	vand	q10, q10, q8
524	vand	q11, q11, q8
525	veor	q5, q5, q10
526	vshl.u64	q10, q10, #4
527	veor	q3, q3, q11
528	vshl.u64	q11, q11, #4
529	veor	q4, q4, q10
530	veor	q6, q6, q11
531	vshr.u64	q10, q1, #4
532	vshr.u64	q11, q0, #4
533	veor	q10, q10, q7
534	veor	q11, q11, q2
535	vand	q10, q10, q8
536	vand	q11, q11, q8
537	veor	q7, q7, q10
538	vshl.u64	q10, q10, #4
539	veor	q2, q2, q11
540	vshl.u64	q11, q11, #4
541	veor	q1, q1, q10
542	veor	q0, q0, q11
543	vldmia	r4, {q8}			@ last round key
544	veor	q6, q6, q8
545	veor	q4, q4, q8
546	veor	q2, q2, q8
547	veor	q7, q7, q8
548	veor	q3, q3, q8
549	veor	q5, q5, q8
550	veor	q0, q0, q8
551	veor	q1, q1, q8
552	bx	lr
553.size	_bsaes_decrypt8,.-_bsaes_decrypt8
554
555.type	_bsaes_const,%object
556.align	6
557_bsaes_const:
558.LM0ISR:@ InvShiftRows constants
559.quad	0x0a0e0206070b0f03, 0x0004080c0d010509
560.LISR:
561.quad	0x0504070602010003, 0x0f0e0d0c080b0a09
562.LISRM0:
563.quad	0x01040b0e0205080f, 0x0306090c00070a0d
564.LM0SR:@ ShiftRows constants
565.quad	0x0a0e02060f03070b, 0x0004080c05090d01
566.LSR:
567.quad	0x0504070600030201, 0x0f0e0d0c0a09080b
568.LSRM0:
569.quad	0x0304090e00050a0f, 0x01060b0c0207080d
570.LM0:
571.quad	0x02060a0e03070b0f, 0x0004080c0105090d
572.LREVM0SR:
573.quad	0x090d01050c000408, 0x03070b0f060a0e02
574.byte	66,105,116,45,115,108,105,99,101,100,32,65,69,83,32,102,111,114,32,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
575.align	2
576.align	6
577.size	_bsaes_const,.-_bsaes_const
578
579.type	_bsaes_encrypt8,%function
580.align	4
581_bsaes_encrypt8:
582	adr	r6,.
583	vldmia	r4!, {q9}		@ round 0 key
584#if defined(__thumb2__) || defined(__APPLE__)
585	adr	r6,.LM0SR
586#else
587	sub	r6,r6,#_bsaes_encrypt8-.LM0SR
588#endif
589
590	vldmia	r6!, {q8}		@ .LM0SR
591_bsaes_encrypt8_alt:
592	veor	q10, q0, q9	@ xor with round0 key
593	veor	q11, q1, q9
594	vtbl.8	d0, {q10}, d16
595	vtbl.8	d1, {q10}, d17
596	veor	q12, q2, q9
597	vtbl.8	d2, {q11}, d16
598	vtbl.8	d3, {q11}, d17
599	veor	q13, q3, q9
600	vtbl.8	d4, {q12}, d16
601	vtbl.8	d5, {q12}, d17
602	veor	q14, q4, q9
603	vtbl.8	d6, {q13}, d16
604	vtbl.8	d7, {q13}, d17
605	veor	q15, q5, q9
606	vtbl.8	d8, {q14}, d16
607	vtbl.8	d9, {q14}, d17
608	veor	q10, q6, q9
609	vtbl.8	d10, {q15}, d16
610	vtbl.8	d11, {q15}, d17
611	veor	q11, q7, q9
612	vtbl.8	d12, {q10}, d16
613	vtbl.8	d13, {q10}, d17
614	vtbl.8	d14, {q11}, d16
615	vtbl.8	d15, {q11}, d17
616_bsaes_encrypt8_bitslice:
617	vmov.i8	q8,#0x55			@ compose .LBS0
618	vmov.i8	q9,#0x33			@ compose .LBS1
619	vshr.u64	q10, q6, #1
620	vshr.u64	q11, q4, #1
621	veor	q10, q10, q7
622	veor	q11, q11, q5
623	vand	q10, q10, q8
624	vand	q11, q11, q8
625	veor	q7, q7, q10
626	vshl.u64	q10, q10, #1
627	veor	q5, q5, q11
628	vshl.u64	q11, q11, #1
629	veor	q6, q6, q10
630	veor	q4, q4, q11
631	vshr.u64	q10, q2, #1
632	vshr.u64	q11, q0, #1
633	veor	q10, q10, q3
634	veor	q11, q11, q1
635	vand	q10, q10, q8
636	vand	q11, q11, q8
637	veor	q3, q3, q10
638	vshl.u64	q10, q10, #1
639	veor	q1, q1, q11
640	vshl.u64	q11, q11, #1
641	veor	q2, q2, q10
642	veor	q0, q0, q11
643	vmov.i8	q8,#0x0f			@ compose .LBS2
644	vshr.u64	q10, q5, #2
645	vshr.u64	q11, q4, #2
646	veor	q10, q10, q7
647	veor	q11, q11, q6
648	vand	q10, q10, q9
649	vand	q11, q11, q9
650	veor	q7, q7, q10
651	vshl.u64	q10, q10, #2
652	veor	q6, q6, q11
653	vshl.u64	q11, q11, #2
654	veor	q5, q5, q10
655	veor	q4, q4, q11
656	vshr.u64	q10, q1, #2
657	vshr.u64	q11, q0, #2
658	veor	q10, q10, q3
659	veor	q11, q11, q2
660	vand	q10, q10, q9
661	vand	q11, q11, q9
662	veor	q3, q3, q10
663	vshl.u64	q10, q10, #2
664	veor	q2, q2, q11
665	vshl.u64	q11, q11, #2
666	veor	q1, q1, q10
667	veor	q0, q0, q11
668	vshr.u64	q10, q3, #4
669	vshr.u64	q11, q2, #4
670	veor	q10, q10, q7
671	veor	q11, q11, q6
672	vand	q10, q10, q8
673	vand	q11, q11, q8
674	veor	q7, q7, q10
675	vshl.u64	q10, q10, #4
676	veor	q6, q6, q11
677	vshl.u64	q11, q11, #4
678	veor	q3, q3, q10
679	veor	q2, q2, q11
680	vshr.u64	q10, q1, #4
681	vshr.u64	q11, q0, #4
682	veor	q10, q10, q5
683	veor	q11, q11, q4
684	vand	q10, q10, q8
685	vand	q11, q11, q8
686	veor	q5, q5, q10
687	vshl.u64	q10, q10, #4
688	veor	q4, q4, q11
689	vshl.u64	q11, q11, #4
690	veor	q1, q1, q10
691	veor	q0, q0, q11
692	sub	r5,r5,#1
693	b	.Lenc_sbox
694.align	4
695.Lenc_loop:
696	vldmia	r4!, {q8,q9,q10,q11}
697	veor	q8, q8, q0
698	veor	q9, q9, q1
699	vtbl.8	d0, {q8}, d24
700	vtbl.8	d1, {q8}, d25
701	vldmia	r4!, {q8}
702	veor	q10, q10, q2
703	vtbl.8	d2, {q9}, d24
704	vtbl.8	d3, {q9}, d25
705	vldmia	r4!, {q9}
706	veor	q11, q11, q3
707	vtbl.8	d4, {q10}, d24
708	vtbl.8	d5, {q10}, d25
709	vldmia	r4!, {q10}
710	vtbl.8	d6, {q11}, d24
711	vtbl.8	d7, {q11}, d25
712	vldmia	r4!, {q11}
713	veor	q8, q8, q4
714	veor	q9, q9, q5
715	vtbl.8	d8, {q8}, d24
716	vtbl.8	d9, {q8}, d25
717	veor	q10, q10, q6
718	vtbl.8	d10, {q9}, d24
719	vtbl.8	d11, {q9}, d25
720	veor	q11, q11, q7
721	vtbl.8	d12, {q10}, d24
722	vtbl.8	d13, {q10}, d25
723	vtbl.8	d14, {q11}, d24
724	vtbl.8	d15, {q11}, d25
725.Lenc_sbox:
726	veor	q2, q2, q1
727	veor	q5, q5, q6
728	veor	q3, q3, q0
729	veor	q6, q6, q2
730	veor	q5, q5, q0
731
732	veor	q6, q6, q3
733	veor	q3, q3, q7
734	veor	q7, q7, q5
735	veor	q3, q3, q4
736	veor	q4, q4, q5
737
738	veor	q2, q2, q7
739	veor	q3, q3, q1
740	veor	q1, q1, q5
741	veor	q11, q7, q4
742	veor	q10, q1, q2
743	veor	q9, q5, q3
744	veor	q13, q2, q4
745	vmov	q8, q10
746	veor	q12, q6, q0
747
748	vorr	q10, q10, q9
749	veor	q15, q11, q8
750	vand	q14, q11, q12
751	vorr	q11, q11, q12
752	veor	q12, q12, q9
753	vand	q8, q8, q9
754	veor	q9, q3, q0
755	vand	q15, q15, q12
756	vand	q13, q13, q9
757	veor	q9, q7, q1
758	veor	q12, q5, q6
759	veor	q11, q11, q13
760	veor	q10, q10, q13
761	vand	q13, q9, q12
762	vorr	q9, q9, q12
763	veor	q11, q11, q15
764	veor	q8, q8, q13
765	veor	q10, q10, q14
766	veor	q9, q9, q15
767	veor	q8, q8, q14
768	vand	q12, q2, q3
769	veor	q9, q9, q14
770	vand	q13, q4, q0
771	vand	q14, q1, q5
772	vorr	q15, q7, q6
773	veor	q11, q11, q12
774	veor	q9, q9, q14
775	veor	q8, q8, q15
776	veor	q10, q10, q13
777
778	@ Inv_GF16 	0, 	1, 	2, 	3, s0, s1, s2, s3
779
780	@ new smaller inversion
781
782	vand	q14, q11, q9
783	vmov	q12, q8
784
785	veor	q13, q10, q14
786	veor	q15, q8, q14
787	veor	q14, q8, q14	@ q14=q15
788
789	vbsl	q13, q9, q8
790	vbsl	q15, q11, q10
791	veor	q11, q11, q10
792
793	vbsl	q12, q13, q14
794	vbsl	q8, q14, q13
795
796	vand	q14, q12, q15
797	veor	q9, q9, q8
798
799	veor	q14, q14, q11
800	veor	q12, q6, q0
801	veor	q8, q5, q3
802	veor	q10, q15, q14
803	vand	q10, q10, q6
804	veor	q6, q6, q5
805	vand	q11, q5, q15
806	vand	q6, q6, q14
807	veor	q5, q11, q10
808	veor	q6, q6, q11
809	veor	q15, q15, q13
810	veor	q14, q14, q9
811	veor	q11, q15, q14
812	veor	q10, q13, q9
813	vand	q11, q11, q12
814	vand	q10, q10, q0
815	veor	q12, q12, q8
816	veor	q0, q0, q3
817	vand	q8, q8, q15
818	vand	q3, q3, q13
819	vand	q12, q12, q14
820	vand	q0, q0, q9
821	veor	q8, q8, q12
822	veor	q0, q0, q3
823	veor	q12, q12, q11
824	veor	q3, q3, q10
825	veor	q6, q6, q12
826	veor	q0, q0, q12
827	veor	q5, q5, q8
828	veor	q3, q3, q8
829
830	veor	q12, q7, q4
831	veor	q8, q1, q2
832	veor	q11, q15, q14
833	veor	q10, q13, q9
834	vand	q11, q11, q12
835	vand	q10, q10, q4
836	veor	q12, q12, q8
837	veor	q4, q4, q2
838	vand	q8, q8, q15
839	vand	q2, q2, q13
840	vand	q12, q12, q14
841	vand	q4, q4, q9
842	veor	q8, q8, q12
843	veor	q4, q4, q2
844	veor	q12, q12, q11
845	veor	q2, q2, q10
846	veor	q15, q15, q13
847	veor	q14, q14, q9
848	veor	q10, q15, q14
849	vand	q10, q10, q7
850	veor	q7, q7, q1
851	vand	q11, q1, q15
852	vand	q7, q7, q14
853	veor	q1, q11, q10
854	veor	q7, q7, q11
855	veor	q7, q7, q12
856	veor	q4, q4, q12
857	veor	q1, q1, q8
858	veor	q2, q2, q8
859	veor	q7, q7, q0
860	veor	q1, q1, q6
861	veor	q6, q6, q0
862	veor	q4, q4, q7
863	veor	q0, q0, q1
864
865	veor	q1, q1, q5
866	veor	q5, q5, q2
867	veor	q2, q2, q3
868	veor	q3, q3, q5
869	veor	q4, q4, q5
870
871	veor	q6, q6, q3
872	subs	r5,r5,#1
873	bcc	.Lenc_done
874	vext.8	q8, q0, q0, #12	@ x0 <<< 32
875	vext.8	q9, q1, q1, #12
876	veor	q0, q0, q8		@ x0 ^ (x0 <<< 32)
877	vext.8	q10, q4, q4, #12
878	veor	q1, q1, q9
879	vext.8	q11, q6, q6, #12
880	veor	q4, q4, q10
881	vext.8	q12, q3, q3, #12
882	veor	q6, q6, q11
883	vext.8	q13, q7, q7, #12
884	veor	q3, q3, q12
885	vext.8	q14, q2, q2, #12
886	veor	q7, q7, q13
887	vext.8	q15, q5, q5, #12
888	veor	q2, q2, q14
889
890	veor	q9, q9, q0
891	veor	q5, q5, q15
892	vext.8	q0, q0, q0, #8		@ (x0 ^ (x0 <<< 32)) <<< 64)
893	veor	q10, q10, q1
894	veor	q8, q8, q5
895	veor	q9, q9, q5
896	vext.8	q1, q1, q1, #8
897	veor	q13, q13, q3
898	veor	q0, q0, q8
899	veor	q14, q14, q7
900	veor	q1, q1, q9
901	vext.8	q8, q3, q3, #8
902	veor	q12, q12, q6
903	vext.8	q9, q7, q7, #8
904	veor	q15, q15, q2
905	vext.8	q3, q6, q6, #8
906	veor	q11, q11, q4
907	vext.8	q7, q5, q5, #8
908	veor	q12, q12, q5
909	vext.8	q6, q2, q2, #8
910	veor	q11, q11, q5
911	vext.8	q2, q4, q4, #8
912	veor	q5, q9, q13
913	veor	q4, q8, q12
914	veor	q3, q3, q11
915	veor	q7, q7, q15
916	veor	q6, q6, q14
917	 @ vmov	q4, q8
918	veor	q2, q2, q10
919	 @ vmov	q5, q9
920	vldmia	r6, {q12}		@ .LSR
921	ite	eq				@ Thumb2 thing, samity check in ARM
922	addeq	r6,r6,#0x10
923	bne	.Lenc_loop
924	vldmia	r6, {q12}		@ .LSRM0
925	b	.Lenc_loop
926.align	4
927.Lenc_done:
928	vmov.i8	q8,#0x55			@ compose .LBS0
929	vmov.i8	q9,#0x33			@ compose .LBS1
930	vshr.u64	q10, q2, #1
931	vshr.u64	q11, q3, #1
932	veor	q10, q10, q5
933	veor	q11, q11, q7
934	vand	q10, q10, q8
935	vand	q11, q11, q8
936	veor	q5, q5, q10
937	vshl.u64	q10, q10, #1
938	veor	q7, q7, q11
939	vshl.u64	q11, q11, #1
940	veor	q2, q2, q10
941	veor	q3, q3, q11
942	vshr.u64	q10, q4, #1
943	vshr.u64	q11, q0, #1
944	veor	q10, q10, q6
945	veor	q11, q11, q1
946	vand	q10, q10, q8
947	vand	q11, q11, q8
948	veor	q6, q6, q10
949	vshl.u64	q10, q10, #1
950	veor	q1, q1, q11
951	vshl.u64	q11, q11, #1
952	veor	q4, q4, q10
953	veor	q0, q0, q11
954	vmov.i8	q8,#0x0f			@ compose .LBS2
955	vshr.u64	q10, q7, #2
956	vshr.u64	q11, q3, #2
957	veor	q10, q10, q5
958	veor	q11, q11, q2
959	vand	q10, q10, q9
960	vand	q11, q11, q9
961	veor	q5, q5, q10
962	vshl.u64	q10, q10, #2
963	veor	q2, q2, q11
964	vshl.u64	q11, q11, #2
965	veor	q7, q7, q10
966	veor	q3, q3, q11
967	vshr.u64	q10, q1, #2
968	vshr.u64	q11, q0, #2
969	veor	q10, q10, q6
970	veor	q11, q11, q4
971	vand	q10, q10, q9
972	vand	q11, q11, q9
973	veor	q6, q6, q10
974	vshl.u64	q10, q10, #2
975	veor	q4, q4, q11
976	vshl.u64	q11, q11, #2
977	veor	q1, q1, q10
978	veor	q0, q0, q11
979	vshr.u64	q10, q6, #4
980	vshr.u64	q11, q4, #4
981	veor	q10, q10, q5
982	veor	q11, q11, q2
983	vand	q10, q10, q8
984	vand	q11, q11, q8
985	veor	q5, q5, q10
986	vshl.u64	q10, q10, #4
987	veor	q2, q2, q11
988	vshl.u64	q11, q11, #4
989	veor	q6, q6, q10
990	veor	q4, q4, q11
991	vshr.u64	q10, q1, #4
992	vshr.u64	q11, q0, #4
993	veor	q10, q10, q7
994	veor	q11, q11, q3
995	vand	q10, q10, q8
996	vand	q11, q11, q8
997	veor	q7, q7, q10
998	vshl.u64	q10, q10, #4
999	veor	q3, q3, q11
1000	vshl.u64	q11, q11, #4
1001	veor	q1, q1, q10
1002	veor	q0, q0, q11
1003	vldmia	r4, {q8}			@ last round key
1004	veor	q4, q4, q8
1005	veor	q6, q6, q8
1006	veor	q3, q3, q8
1007	veor	q7, q7, q8
1008	veor	q2, q2, q8
1009	veor	q5, q5, q8
1010	veor	q0, q0, q8
1011	veor	q1, q1, q8
1012	bx	lr
1013.size	_bsaes_encrypt8,.-_bsaes_encrypt8
1014.type	_bsaes_key_convert,%function
1015.align	4
1016_bsaes_key_convert:
1017	adr	r6,.
1018	vld1.8	{q7},  [r4]!		@ load round 0 key
1019#if defined(__thumb2__) || defined(__APPLE__)
1020	adr	r6,.LM0
1021#else
1022	sub	r6,r6,#_bsaes_key_convert-.LM0
1023#endif
1024	vld1.8	{q15}, [r4]!		@ load round 1 key
1025
1026	vmov.i8	q8,  #0x01			@ bit masks
1027	vmov.i8	q9,  #0x02
1028	vmov.i8	q10, #0x04
1029	vmov.i8	q11, #0x08
1030	vmov.i8	q12, #0x10
1031	vmov.i8	q13, #0x20
1032	vldmia	r6, {q14}		@ .LM0
1033
1034#ifdef __ARMEL__
1035	vrev32.8	q7,  q7
1036	vrev32.8	q15, q15
1037#endif
1038	sub	r5,r5,#1
1039	vstmia	r12!, {q7}		@ save round 0 key
1040	b	.Lkey_loop
1041
1042.align	4
1043.Lkey_loop:
1044	vtbl.8	d14,{q15},d28
1045	vtbl.8	d15,{q15},d29
1046	vmov.i8	q6,  #0x40
1047	vmov.i8	q15, #0x80
1048
1049	vtst.8	q0, q7, q8
1050	vtst.8	q1, q7, q9
1051	vtst.8	q2, q7, q10
1052	vtst.8	q3, q7, q11
1053	vtst.8	q4, q7, q12
1054	vtst.8	q5, q7, q13
1055	vtst.8	q6, q7, q6
1056	vtst.8	q7, q7, q15
1057	vld1.8	{q15}, [r4]!		@ load next round key
1058	vmvn	q0, q0		@ "pnot"
1059	vmvn	q1, q1
1060	vmvn	q5, q5
1061	vmvn	q6, q6
1062#ifdef __ARMEL__
1063	vrev32.8	q15, q15
1064#endif
1065	subs	r5,r5,#1
1066	vstmia	r12!,{q0,q1,q2,q3,q4,q5,q6,q7}		@ write bit-sliced round key
1067	bne	.Lkey_loop
1068
1069	vmov.i8	q7,#0x63			@ compose .L63
1070	@ don't save last round key
1071	bx	lr
1072.size	_bsaes_key_convert,.-_bsaes_key_convert
1073
1074
1075
1076.globl	ossl_bsaes_cbc_encrypt
1077.type	ossl_bsaes_cbc_encrypt,%function
1078.align	5
1079ossl_bsaes_cbc_encrypt:
1080#ifndef	__KERNEL__
1081	cmp	r2, #128
1082#ifndef	__thumb__
1083	blo	AES_cbc_encrypt
1084#else
1085	bhs	.Lcbc_do_bsaes
1086	b	AES_cbc_encrypt
1087.Lcbc_do_bsaes:
1088#endif
1089#endif
1090
1091	@ it is up to the caller to make sure we are called with enc == 0
1092
1093	mov	ip, sp
1094	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}
1095	VFP_ABI_PUSH
1096	ldr	r8, [ip]			@ IV is 1st arg on the stack
1097	mov	r2, r2, lsr#4		@ len in 16 byte blocks
1098	sub	sp, #0x10			@ scratch space to carry over the IV
1099	mov	r9, sp				@ save sp
1100
1101	ldr	r10, [r3, #240]		@ get # of rounds
1102#ifndef	BSAES_ASM_EXTENDED_KEY
1103	@ allocate the key schedule on the stack
1104	sub	r12, sp, r10, lsl#7		@ 128 bytes per inner round key
1105	add	r12, #96			@ sifze of bit-slices key schedule
1106
1107	@ populate the key schedule
1108	mov	r4, r3			@ pass key
1109	mov	r5, r10			@ pass # of rounds
1110	mov	sp, r12				@ sp is sp
1111	bl	_bsaes_key_convert
1112	vldmia	sp, {q6}
1113	vstmia	r12,  {q15}		@ save last round key
1114	veor	q7, q7, q6	@ fix up round 0 key
1115	vstmia	sp, {q7}
1116#else
1117	ldr	r12, [r3, #244]
1118	eors	r12, #1
1119	beq	0f
1120
1121	@ populate the key schedule
1122	str	r12, [r3, #244]
1123	mov	r4, r3			@ pass key
1124	mov	r5, r10			@ pass # of rounds
1125	add	r12, r3, #248			@ pass key schedule
1126	bl	_bsaes_key_convert
1127	add	r4, r3, #248
1128	vldmia	r4, {q6}
1129	vstmia	r12, {q15}			@ save last round key
1130	veor	q7, q7, q6	@ fix up round 0 key
1131	vstmia	r4, {q7}
1132
1133.align	2
11340:
1135#endif
1136
1137	vld1.8	{q15}, [r8]		@ load IV
1138	b	.Lcbc_dec_loop
1139
1140.align	4
1141.Lcbc_dec_loop:
1142	subs	r2, r2, #0x8
1143	bmi	.Lcbc_dec_loop_finish
1144
1145	vld1.8	{q0,q1}, [r0]!	@ load input
1146	vld1.8	{q2,q3}, [r0]!
1147#ifndef	BSAES_ASM_EXTENDED_KEY
1148	mov	r4, sp			@ pass the key
1149#else
1150	add	r4, r3, #248
1151#endif
1152	vld1.8	{q4,q5}, [r0]!
1153	mov	r5, r10
1154	vld1.8	{q6,q7}, [r0]
1155	sub	r0, r0, #0x60
1156	vstmia	r9, {q15}			@ put aside IV
1157
1158	bl	_bsaes_decrypt8
1159
1160	vldmia	r9, {q14}			@ reload IV
1161	vld1.8	{q8,q9}, [r0]!	@ reload input
1162	veor	q0, q0, q14	@ ^= IV
1163	vld1.8	{q10,q11}, [r0]!
1164	veor	q1, q1, q8
1165	veor	q6, q6, q9
1166	vld1.8	{q12,q13}, [r0]!
1167	veor	q4, q4, q10
1168	veor	q2, q2, q11
1169	vld1.8	{q14,q15}, [r0]!
1170	veor	q7, q7, q12
1171	vst1.8	{q0,q1}, [r1]!	@ write output
1172	veor	q3, q3, q13
1173	vst1.8	{q6}, [r1]!
1174	veor	q5, q5, q14
1175	vst1.8	{q4}, [r1]!
1176	vst1.8	{q2}, [r1]!
1177	vst1.8	{q7}, [r1]!
1178	vst1.8	{q3}, [r1]!
1179	vst1.8	{q5}, [r1]!
1180
1181	b	.Lcbc_dec_loop
1182
1183.Lcbc_dec_loop_finish:
1184	adds	r2, r2, #8
1185	beq	.Lcbc_dec_done
1186
1187	vld1.8	{q0}, [r0]!		@ load input
1188	cmp	r2, #2
1189	blo	.Lcbc_dec_one
1190	vld1.8	{q1}, [r0]!
1191#ifndef	BSAES_ASM_EXTENDED_KEY
1192	mov	r4, sp			@ pass the key
1193#else
1194	add	r4, r3, #248
1195#endif
1196	mov	r5, r10
1197	vstmia	r9, {q15}			@ put aside IV
1198	beq	.Lcbc_dec_two
1199	vld1.8	{q2}, [r0]!
1200	cmp	r2, #4
1201	blo	.Lcbc_dec_three
1202	vld1.8	{q3}, [r0]!
1203	beq	.Lcbc_dec_four
1204	vld1.8	{q4}, [r0]!
1205	cmp	r2, #6
1206	blo	.Lcbc_dec_five
1207	vld1.8	{q5}, [r0]!
1208	beq	.Lcbc_dec_six
1209	vld1.8	{q6}, [r0]!
1210	sub	r0, r0, #0x70
1211
1212	bl	_bsaes_decrypt8
1213
1214	vldmia	r9, {q14}			@ reload IV
1215	vld1.8	{q8,q9}, [r0]!	@ reload input
1216	veor	q0, q0, q14	@ ^= IV
1217	vld1.8	{q10,q11}, [r0]!
1218	veor	q1, q1, q8
1219	veor	q6, q6, q9
1220	vld1.8	{q12,q13}, [r0]!
1221	veor	q4, q4, q10
1222	veor	q2, q2, q11
1223	vld1.8	{q15}, [r0]!
1224	veor	q7, q7, q12
1225	vst1.8	{q0,q1}, [r1]!	@ write output
1226	veor	q3, q3, q13
1227	vst1.8	{q6}, [r1]!
1228	vst1.8	{q4}, [r1]!
1229	vst1.8	{q2}, [r1]!
1230	vst1.8	{q7}, [r1]!
1231	vst1.8	{q3}, [r1]!
1232	b	.Lcbc_dec_done
1233.align	4
1234.Lcbc_dec_six:
1235	sub	r0, r0, #0x60
1236	bl	_bsaes_decrypt8
1237	vldmia	r9,{q14}			@ reload IV
1238	vld1.8	{q8,q9}, [r0]!	@ reload input
1239	veor	q0, q0, q14	@ ^= IV
1240	vld1.8	{q10,q11}, [r0]!
1241	veor	q1, q1, q8
1242	veor	q6, q6, q9
1243	vld1.8	{q12}, [r0]!
1244	veor	q4, q4, q10
1245	veor	q2, q2, q11
1246	vld1.8	{q15}, [r0]!
1247	veor	q7, q7, q12
1248	vst1.8	{q0,q1}, [r1]!	@ write output
1249	vst1.8	{q6}, [r1]!
1250	vst1.8	{q4}, [r1]!
1251	vst1.8	{q2}, [r1]!
1252	vst1.8	{q7}, [r1]!
1253	b	.Lcbc_dec_done
1254.align	4
1255.Lcbc_dec_five:
1256	sub	r0, r0, #0x50
1257	bl	_bsaes_decrypt8
1258	vldmia	r9, {q14}			@ reload IV
1259	vld1.8	{q8,q9}, [r0]!	@ reload input
1260	veor	q0, q0, q14	@ ^= IV
1261	vld1.8	{q10,q11}, [r0]!
1262	veor	q1, q1, q8
1263	veor	q6, q6, q9
1264	vld1.8	{q15}, [r0]!
1265	veor	q4, q4, q10
1266	vst1.8	{q0,q1}, [r1]!	@ write output
1267	veor	q2, q2, q11
1268	vst1.8	{q6}, [r1]!
1269	vst1.8	{q4}, [r1]!
1270	vst1.8	{q2}, [r1]!
1271	b	.Lcbc_dec_done
1272.align	4
1273.Lcbc_dec_four:
1274	sub	r0, r0, #0x40
1275	bl	_bsaes_decrypt8
1276	vldmia	r9, {q14}			@ reload IV
1277	vld1.8	{q8,q9}, [r0]!	@ reload input
1278	veor	q0, q0, q14	@ ^= IV
1279	vld1.8	{q10}, [r0]!
1280	veor	q1, q1, q8
1281	veor	q6, q6, q9
1282	vld1.8	{q15}, [r0]!
1283	veor	q4, q4, q10
1284	vst1.8	{q0,q1}, [r1]!	@ write output
1285	vst1.8	{q6}, [r1]!
1286	vst1.8	{q4}, [r1]!
1287	b	.Lcbc_dec_done
1288.align	4
1289.Lcbc_dec_three:
1290	sub	r0, r0, #0x30
1291	bl	_bsaes_decrypt8
1292	vldmia	r9, {q14}			@ reload IV
1293	vld1.8	{q8,q9}, [r0]!	@ reload input
1294	veor	q0, q0, q14	@ ^= IV
1295	vld1.8	{q15}, [r0]!
1296	veor	q1, q1, q8
1297	veor	q6, q6, q9
1298	vst1.8	{q0,q1}, [r1]!	@ write output
1299	vst1.8	{q6}, [r1]!
1300	b	.Lcbc_dec_done
1301.align	4
1302.Lcbc_dec_two:
1303	sub	r0, r0, #0x20
1304	bl	_bsaes_decrypt8
1305	vldmia	r9, {q14}			@ reload IV
1306	vld1.8	{q8}, [r0]!		@ reload input
1307	veor	q0, q0, q14	@ ^= IV
1308	vld1.8	{q15}, [r0]!		@ reload input
1309	veor	q1, q1, q8
1310	vst1.8	{q0,q1}, [r1]!	@ write output
1311	b	.Lcbc_dec_done
1312.align	4
1313.Lcbc_dec_one:
1314	sub	r0, r0, #0x10
1315	mov	r10, r1			@ save original out pointer
1316	mov	r1, r9			@ use the iv scratch space as out buffer
1317	mov	r2, r3
1318	vmov	q4,q15		@ just in case ensure that IV
1319	vmov	q5,q0			@ and input are preserved
1320	bl	AES_decrypt
1321	vld1.8	{q0}, [r9]		@ load result
1322	veor	q0, q0, q4	@ ^= IV
1323	vmov	q15, q5		@ q5 holds input
1324	vst1.8	{q0}, [r10]		@ write output
1325
1326.Lcbc_dec_done:
1327#ifndef	BSAES_ASM_EXTENDED_KEY
1328	vmov.i32	q0, #0
1329	vmov.i32	q1, #0
1330.Lcbc_dec_bzero:@ wipe key schedule [if any]
1331	vstmia	sp!, {q0,q1}
1332	cmp	sp, r9
1333	bne	.Lcbc_dec_bzero
1334#endif
1335
1336	mov	sp, r9
1337	add	sp, #0x10			@ add sp,r9,#0x10 is no good for thumb
1338	vst1.8	{q15}, [r8]		@ return IV
1339	VFP_ABI_POP
1340	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}
1341.size	ossl_bsaes_cbc_encrypt,.-ossl_bsaes_cbc_encrypt
1342
1343.globl	ossl_bsaes_ctr32_encrypt_blocks
1344.type	ossl_bsaes_ctr32_encrypt_blocks,%function
1345.align	5
1346ossl_bsaes_ctr32_encrypt_blocks:
1347	cmp	r2, #8			@ use plain AES for
1348	blo	.Lctr_enc_short			@ small sizes
1349
1350	mov	ip, sp
1351	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}
1352	VFP_ABI_PUSH
1353	ldr	r8, [ip]			@ ctr is 1st arg on the stack
1354	sub	sp, sp, #0x10			@ scratch space to carry over the ctr
1355	mov	r9, sp				@ save sp
1356
1357	ldr	r10, [r3, #240]		@ get # of rounds
1358#ifndef	BSAES_ASM_EXTENDED_KEY
1359	@ allocate the key schedule on the stack
1360	sub	r12, sp, r10, lsl#7		@ 128 bytes per inner round key
1361	add	r12, #96			@ size of bit-sliced key schedule
1362
1363	@ populate the key schedule
1364	mov	r4, r3			@ pass key
1365	mov	r5, r10			@ pass # of rounds
1366	mov	sp, r12				@ sp is sp
1367	bl	_bsaes_key_convert
1368	veor	q7,q7,q15	@ fix up last round key
1369	vstmia	r12, {q7}			@ save last round key
1370
1371	vld1.8	{q0}, [r8]		@ load counter
1372#ifdef	__APPLE__
1373	mov	r8, #:lower16:(.LREVM0SR-.LM0)
1374	add	r8, r6, r8
1375#else
1376	add	r8, r6, #.LREVM0SR-.LM0	@ borrow r8
1377#endif
1378	vldmia	sp, {q4}		@ load round0 key
1379#else
1380	ldr	r12, [r3, #244]
1381	eors	r12, #1
1382	beq	0f
1383
1384	@ populate the key schedule
1385	str	r12, [r3, #244]
1386	mov	r4, r3			@ pass key
1387	mov	r5, r10			@ pass # of rounds
1388	add	r12, r3, #248			@ pass key schedule
1389	bl	_bsaes_key_convert
1390	veor	q7,q7,q15	@ fix up last round key
1391	vstmia	r12, {q7}			@ save last round key
1392
1393.align	2
13940:	add	r12, r3, #248
1395	vld1.8	{q0}, [r8]		@ load counter
1396	add	r8, r6, #.LREVM0SR-.LM0	@ borrow r8
1397	vldmia	r12, {q4}			@ load round0 key
1398	sub	sp, #0x10			@ place for adjusted round0 key
1399#endif
1400
1401	vmov.i32	q8,#1		@ compose 1<<96
1402	veor	q9,q9,q9
1403	vrev32.8	q0,q0
1404	vext.8	q8,q9,q8,#4
1405	vrev32.8	q4,q4
1406	vadd.u32	q9,q8,q8	@ compose 2<<96
1407	vstmia	sp, {q4}		@ save adjusted round0 key
1408	b	.Lctr_enc_loop
1409
1410.align	4
1411.Lctr_enc_loop:
1412	vadd.u32	q10, q8, q9	@ compose 3<<96
1413	vadd.u32	q1, q0, q8	@ +1
1414	vadd.u32	q2, q0, q9	@ +2
1415	vadd.u32	q3, q0, q10	@ +3
1416	vadd.u32	q4, q1, q10
1417	vadd.u32	q5, q2, q10
1418	vadd.u32	q6, q3, q10
1419	vadd.u32	q7, q4, q10
1420	vadd.u32	q10, q5, q10	@ next counter
1421
1422	@ Borrow prologue from _bsaes_encrypt8 to use the opportunity
1423	@ to flip byte order in 32-bit counter
1424
1425	vldmia	sp, {q9}		@ load round0 key
1426#ifndef	BSAES_ASM_EXTENDED_KEY
1427	add	r4, sp, #0x10		@ pass next round key
1428#else
1429	add	r4, r3, #264
1430#endif
1431	vldmia	r8, {q8}			@ .LREVM0SR
1432	mov	r5, r10			@ pass rounds
1433	vstmia	r9, {q10}			@ save next counter
1434#ifdef	__APPLE__
1435	mov	r6, #:lower16:(.LREVM0SR-.LSR)
1436	sub	r6, r8, r6
1437#else
1438	sub	r6, r8, #.LREVM0SR-.LSR	@ pass constants
1439#endif
1440
1441	bl	_bsaes_encrypt8_alt
1442
1443	subs	r2, r2, #8
1444	blo	.Lctr_enc_loop_done
1445
1446	vld1.8	{q8,q9}, [r0]!	@ load input
1447	vld1.8	{q10,q11}, [r0]!
1448	veor	q0, q8
1449	veor	q1, q9
1450	vld1.8	{q12,q13}, [r0]!
1451	veor	q4, q10
1452	veor	q6, q11
1453	vld1.8	{q14,q15}, [r0]!
1454	veor	q3, q12
1455	vst1.8	{q0,q1}, [r1]!	@ write output
1456	veor	q7, q13
1457	veor	q2, q14
1458	vst1.8	{q4}, [r1]!
1459	veor	q5, q15
1460	vst1.8	{q6}, [r1]!
1461	vmov.i32	q8, #1			@ compose 1<<96
1462	vst1.8	{q3}, [r1]!
1463	veor	q9, q9, q9
1464	vst1.8	{q7}, [r1]!
1465	vext.8	q8, q9, q8, #4
1466	vst1.8	{q2}, [r1]!
1467	vadd.u32	q9,q8,q8		@ compose 2<<96
1468	vst1.8	{q5}, [r1]!
1469	vldmia	r9, {q0}			@ load counter
1470
1471	bne	.Lctr_enc_loop
1472	b	.Lctr_enc_done
1473
1474.align	4
1475.Lctr_enc_loop_done:
1476	add	r2, r2, #8
1477	vld1.8	{q8}, [r0]!	@ load input
1478	veor	q0, q8
1479	vst1.8	{q0}, [r1]!	@ write output
1480	cmp	r2, #2
1481	blo	.Lctr_enc_done
1482	vld1.8	{q9}, [r0]!
1483	veor	q1, q9
1484	vst1.8	{q1}, [r1]!
1485	beq	.Lctr_enc_done
1486	vld1.8	{q10}, [r0]!
1487	veor	q4, q10
1488	vst1.8	{q4}, [r1]!
1489	cmp	r2, #4
1490	blo	.Lctr_enc_done
1491	vld1.8	{q11}, [r0]!
1492	veor	q6, q11
1493	vst1.8	{q6}, [r1]!
1494	beq	.Lctr_enc_done
1495	vld1.8	{q12}, [r0]!
1496	veor	q3, q12
1497	vst1.8	{q3}, [r1]!
1498	cmp	r2, #6
1499	blo	.Lctr_enc_done
1500	vld1.8	{q13}, [r0]!
1501	veor	q7, q13
1502	vst1.8	{q7}, [r1]!
1503	beq	.Lctr_enc_done
1504	vld1.8	{q14}, [r0]
1505	veor	q2, q14
1506	vst1.8	{q2}, [r1]!
1507
1508.Lctr_enc_done:
1509	vmov.i32	q0, #0
1510	vmov.i32	q1, #0
1511#ifndef	BSAES_ASM_EXTENDED_KEY
1512.Lctr_enc_bzero:@ wipe key schedule [if any]
1513	vstmia	sp!, {q0,q1}
1514	cmp	sp, r9
1515	bne	.Lctr_enc_bzero
1516#else
1517	vstmia	sp, {q0,q1}
1518#endif
1519
1520	mov	sp, r9
1521	add	sp, #0x10		@ add sp,r9,#0x10 is no good for thumb
1522	VFP_ABI_POP
1523	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}	@ return
1524
1525.align	4
1526.Lctr_enc_short:
1527	ldr	ip, [sp]		@ ctr pointer is passed on stack
1528	stmdb	sp!, {r4,r5,r6,r7,r8, lr}
1529
1530	mov	r4, r0		@ copy arguments
1531	mov	r5, r1
1532	mov	r6, r2
1533	mov	r7, r3
1534	ldr	r8, [ip, #12]		@ load counter .LSW
1535	vld1.8	{q1}, [ip]		@ load whole counter value
1536#ifdef __ARMEL__
1537	rev	r8, r8
1538#endif
1539	sub	sp, sp, #0x10
1540	vst1.8	{q1}, [sp]		@ copy counter value
1541	sub	sp, sp, #0x10
1542
1543.Lctr_enc_short_loop:
1544	add	r0, sp, #0x10		@ input counter value
1545	mov	r1, sp			@ output on the stack
1546	mov	r2, r7			@ key
1547
1548	bl	AES_encrypt
1549
1550	vld1.8	{q0}, [r4]!	@ load input
1551	vld1.8	{q1}, [sp]		@ load encrypted counter
1552	add	r8, r8, #1
1553#ifdef __ARMEL__
1554	rev	r0, r8
1555	str	r0, [sp, #0x1c]		@ next counter value
1556#else
1557	str	r8, [sp, #0x1c]		@ next counter value
1558#endif
1559	veor	q0,q0,q1
1560	vst1.8	{q0}, [r5]!	@ store output
1561	subs	r6, r6, #1
1562	bne	.Lctr_enc_short_loop
1563
1564	vmov.i32	q0, #0
1565	vmov.i32	q1, #0
1566	vstmia	sp!, {q0,q1}
1567
1568	ldmia	sp!, {r4,r5,r6,r7,r8, pc}
1569.size	ossl_bsaes_ctr32_encrypt_blocks,.-ossl_bsaes_ctr32_encrypt_blocks
1570.globl	ossl_bsaes_xts_encrypt
1571.type	ossl_bsaes_xts_encrypt,%function
1572.align	4
1573ossl_bsaes_xts_encrypt:
1574	mov	ip, sp
1575	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}		@ 0x20
1576	VFP_ABI_PUSH
1577	mov	r6, sp				@ future r3
1578
1579	mov	r7, r0
1580	mov	r8, r1
1581	mov	r9, r2
1582	mov	r10, r3
1583
1584	sub	r0, sp, #0x10			@ 0x10
1585	bic	r0, #0xf			@ align at 16 bytes
1586	mov	sp, r0
1587
1588#ifdef	XTS_CHAIN_TWEAK
1589	ldr	r0, [ip]			@ pointer to input tweak
1590#else
1591	@ generate initial tweak
1592	ldr	r0, [ip, #4]			@ iv[]
1593	mov	r1, sp
1594	ldr	r2, [ip, #0]			@ key2
1595	bl	AES_encrypt
1596	mov	r0,sp				@ pointer to initial tweak
1597#endif
1598
1599	ldr	r1, [r10, #240]		@ get # of rounds
1600	mov	r3, r6
1601#ifndef	BSAES_ASM_EXTENDED_KEY
1602	@ allocate the key schedule on the stack
1603	sub	r12, sp, r1, lsl#7		@ 128 bytes per inner round key
1604	@ add	r12, #96			@ size of bit-sliced key schedule
1605	sub	r12, #48			@ place for tweak[9]
1606
1607	@ populate the key schedule
1608	mov	r4, r10			@ pass key
1609	mov	r5, r1			@ pass # of rounds
1610	mov	sp, r12
1611	add	r12, #0x90			@ pass key schedule
1612	bl	_bsaes_key_convert
1613	veor	q7, q7, q15	@ fix up last round key
1614	vstmia	r12, {q7}			@ save last round key
1615#else
1616	ldr	r12, [r10, #244]
1617	eors	r12, #1
1618	beq	0f
1619
1620	str	r12, [r10, #244]
1621	mov	r4, r10			@ pass key
1622	mov	r5, r1			@ pass # of rounds
1623	add	r12, r10, #248			@ pass key schedule
1624	bl	_bsaes_key_convert
1625	veor	q7, q7, q15	@ fix up last round key
1626	vstmia	r12, {q7}
1627
1628.align	2
16290:	sub	sp, #0x90			@ place for tweak[9]
1630#endif
1631
1632	vld1.8	{q8}, [r0]			@ initial tweak
1633	adr	r2, .Lxts_magic
1634
1635	subs	r9, #0x80
1636	blo	.Lxts_enc_short
1637	b	.Lxts_enc_loop
1638
1639.align	4
1640.Lxts_enc_loop:
1641	vldmia	r2, {q5}	@ load XTS magic
1642	vshr.s64	q6, q8, #63
1643	mov	r0, sp
1644	vand	q6, q6, q5
1645	vadd.u64	q9, q8, q8
1646	vst1.64	{q8}, [r0,:128]!
1647	vswp	d13,d12
1648	vshr.s64	q7, q9, #63
1649	veor	q9, q9, q6
1650	vand	q7, q7, q5
1651	vadd.u64	q10, q9, q9
1652	vst1.64	{q9}, [r0,:128]!
1653	vswp	d15,d14
1654	vshr.s64	q6, q10, #63
1655	veor	q10, q10, q7
1656	vand	q6, q6, q5
1657	vld1.8	{q0}, [r7]!
1658	vadd.u64	q11, q10, q10
1659	vst1.64	{q10}, [r0,:128]!
1660	vswp	d13,d12
1661	vshr.s64	q7, q11, #63
1662	veor	q11, q11, q6
1663	vand	q7, q7, q5
1664	vld1.8	{q1}, [r7]!
1665	veor	q0, q0, q8
1666	vadd.u64	q12, q11, q11
1667	vst1.64	{q11}, [r0,:128]!
1668	vswp	d15,d14
1669	vshr.s64	q6, q12, #63
1670	veor	q12, q12, q7
1671	vand	q6, q6, q5
1672	vld1.8	{q2}, [r7]!
1673	veor	q1, q1, q9
1674	vadd.u64	q13, q12, q12
1675	vst1.64	{q12}, [r0,:128]!
1676	vswp	d13,d12
1677	vshr.s64	q7, q13, #63
1678	veor	q13, q13, q6
1679	vand	q7, q7, q5
1680	vld1.8	{q3}, [r7]!
1681	veor	q2, q2, q10
1682	vadd.u64	q14, q13, q13
1683	vst1.64	{q13}, [r0,:128]!
1684	vswp	d15,d14
1685	vshr.s64	q6, q14, #63
1686	veor	q14, q14, q7
1687	vand	q6, q6, q5
1688	vld1.8	{q4}, [r7]!
1689	veor	q3, q3, q11
1690	vadd.u64	q15, q14, q14
1691	vst1.64	{q14}, [r0,:128]!
1692	vswp	d13,d12
1693	vshr.s64	q7, q15, #63
1694	veor	q15, q15, q6
1695	vand	q7, q7, q5
1696	vld1.8	{q5}, [r7]!
1697	veor	q4, q4, q12
1698	vadd.u64	q8, q15, q15
1699	vst1.64	{q15}, [r0,:128]!
1700	vswp	d15,d14
1701	veor	q8, q8, q7
1702	vst1.64	{q8}, [r0,:128]		@ next round tweak
1703
1704	vld1.8	{q6,q7}, [r7]!
1705	veor	q5, q5, q13
1706#ifndef	BSAES_ASM_EXTENDED_KEY
1707	add	r4, sp, #0x90			@ pass key schedule
1708#else
1709	add	r4, r10, #248			@ pass key schedule
1710#endif
1711	veor	q6, q6, q14
1712	mov	r5, r1			@ pass rounds
1713	veor	q7, q7, q15
1714	mov	r0, sp
1715
1716	bl	_bsaes_encrypt8
1717
1718	vld1.64	{q8,q9}, [r0,:128]!
1719	vld1.64	{q10,q11}, [r0,:128]!
1720	veor	q0, q0, q8
1721	vld1.64	{q12,q13}, [r0,:128]!
1722	veor	q1, q1, q9
1723	veor	q8, q4, q10
1724	vst1.8	{q0,q1}, [r8]!
1725	veor	q9, q6, q11
1726	vld1.64	{q14,q15}, [r0,:128]!
1727	veor	q10, q3, q12
1728	vst1.8	{q8,q9}, [r8]!
1729	veor	q11, q7, q13
1730	veor	q12, q2, q14
1731	vst1.8	{q10,q11}, [r8]!
1732	veor	q13, q5, q15
1733	vst1.8	{q12,q13}, [r8]!
1734
1735	vld1.64	{q8}, [r0,:128]		@ next round tweak
1736
1737	subs	r9, #0x80
1738	bpl	.Lxts_enc_loop
1739
1740.Lxts_enc_short:
1741	adds	r9, #0x70
1742	bmi	.Lxts_enc_done
1743
1744	vldmia	r2, {q5}	@ load XTS magic
1745	vshr.s64	q7, q8, #63
1746	mov	r0, sp
1747	vand	q7, q7, q5
1748	vadd.u64	q9, q8, q8
1749	vst1.64	{q8}, [r0,:128]!
1750	vswp	d15,d14
1751	vshr.s64	q6, q9, #63
1752	veor	q9, q9, q7
1753	vand	q6, q6, q5
1754	vadd.u64	q10, q9, q9
1755	vst1.64	{q9}, [r0,:128]!
1756	vswp	d13,d12
1757	vshr.s64	q7, q10, #63
1758	veor	q10, q10, q6
1759	vand	q7, q7, q5
1760	vld1.8	{q0}, [r7]!
1761	subs	r9, #0x10
1762	bmi	.Lxts_enc_1
1763	vadd.u64	q11, q10, q10
1764	vst1.64	{q10}, [r0,:128]!
1765	vswp	d15,d14
1766	vshr.s64	q6, q11, #63
1767	veor	q11, q11, q7
1768	vand	q6, q6, q5
1769	vld1.8	{q1}, [r7]!
1770	subs	r9, #0x10
1771	bmi	.Lxts_enc_2
1772	veor	q0, q0, q8
1773	vadd.u64	q12, q11, q11
1774	vst1.64	{q11}, [r0,:128]!
1775	vswp	d13,d12
1776	vshr.s64	q7, q12, #63
1777	veor	q12, q12, q6
1778	vand	q7, q7, q5
1779	vld1.8	{q2}, [r7]!
1780	subs	r9, #0x10
1781	bmi	.Lxts_enc_3
1782	veor	q1, q1, q9
1783	vadd.u64	q13, q12, q12
1784	vst1.64	{q12}, [r0,:128]!
1785	vswp	d15,d14
1786	vshr.s64	q6, q13, #63
1787	veor	q13, q13, q7
1788	vand	q6, q6, q5
1789	vld1.8	{q3}, [r7]!
1790	subs	r9, #0x10
1791	bmi	.Lxts_enc_4
1792	veor	q2, q2, q10
1793	vadd.u64	q14, q13, q13
1794	vst1.64	{q13}, [r0,:128]!
1795	vswp	d13,d12
1796	vshr.s64	q7, q14, #63
1797	veor	q14, q14, q6
1798	vand	q7, q7, q5
1799	vld1.8	{q4}, [r7]!
1800	subs	r9, #0x10
1801	bmi	.Lxts_enc_5
1802	veor	q3, q3, q11
1803	vadd.u64	q15, q14, q14
1804	vst1.64	{q14}, [r0,:128]!
1805	vswp	d15,d14
1806	vshr.s64	q6, q15, #63
1807	veor	q15, q15, q7
1808	vand	q6, q6, q5
1809	vld1.8	{q5}, [r7]!
1810	subs	r9, #0x10
1811	bmi	.Lxts_enc_6
1812	veor	q4, q4, q12
1813	sub	r9, #0x10
1814	vst1.64	{q15}, [r0,:128]		@ next round tweak
1815
1816	vld1.8	{q6}, [r7]!
1817	veor	q5, q5, q13
1818#ifndef	BSAES_ASM_EXTENDED_KEY
1819	add	r4, sp, #0x90			@ pass key schedule
1820#else
1821	add	r4, r10, #248			@ pass key schedule
1822#endif
1823	veor	q6, q6, q14
1824	mov	r5, r1			@ pass rounds
1825	mov	r0, sp
1826
1827	bl	_bsaes_encrypt8
1828
1829	vld1.64	{q8,q9}, [r0,:128]!
1830	vld1.64	{q10,q11}, [r0,:128]!
1831	veor	q0, q0, q8
1832	vld1.64	{q12,q13}, [r0,:128]!
1833	veor	q1, q1, q9
1834	veor	q8, q4, q10
1835	vst1.8	{q0,q1}, [r8]!
1836	veor	q9, q6, q11
1837	vld1.64	{q14}, [r0,:128]!
1838	veor	q10, q3, q12
1839	vst1.8	{q8,q9}, [r8]!
1840	veor	q11, q7, q13
1841	veor	q12, q2, q14
1842	vst1.8	{q10,q11}, [r8]!
1843	vst1.8	{q12}, [r8]!
1844
1845	vld1.64	{q8}, [r0,:128]		@ next round tweak
1846	b	.Lxts_enc_done
1847.align	4
1848.Lxts_enc_6:
1849	veor	q4, q4, q12
1850#ifndef	BSAES_ASM_EXTENDED_KEY
1851	add	r4, sp, #0x90			@ pass key schedule
1852#else
1853	add	r4, r10, #248			@ pass key schedule
1854#endif
1855	veor	q5, q5, q13
1856	mov	r5, r1			@ pass rounds
1857	mov	r0, sp
1858
1859	bl	_bsaes_encrypt8
1860
1861	vld1.64	{q8,q9}, [r0,:128]!
1862	vld1.64	{q10,q11}, [r0,:128]!
1863	veor	q0, q0, q8
1864	vld1.64	{q12,q13}, [r0,:128]!
1865	veor	q1, q1, q9
1866	veor	q8, q4, q10
1867	vst1.8	{q0,q1}, [r8]!
1868	veor	q9, q6, q11
1869	veor	q10, q3, q12
1870	vst1.8	{q8,q9}, [r8]!
1871	veor	q11, q7, q13
1872	vst1.8	{q10,q11}, [r8]!
1873
1874	vld1.64	{q8}, [r0,:128]		@ next round tweak
1875	b	.Lxts_enc_done
1876
1877@ put this in range for both ARM and Thumb mode adr instructions
1878.align	5
1879.Lxts_magic:
1880.quad	1, 0x87
1881
1882.align	5
1883.Lxts_enc_5:
1884	veor	q3, q3, q11
1885#ifndef	BSAES_ASM_EXTENDED_KEY
1886	add	r4, sp, #0x90			@ pass key schedule
1887#else
1888	add	r4, r10, #248			@ pass key schedule
1889#endif
1890	veor	q4, q4, q12
1891	mov	r5, r1			@ pass rounds
1892	mov	r0, sp
1893
1894	bl	_bsaes_encrypt8
1895
1896	vld1.64	{q8,q9}, [r0,:128]!
1897	vld1.64	{q10,q11}, [r0,:128]!
1898	veor	q0, q0, q8
1899	vld1.64	{q12}, [r0,:128]!
1900	veor	q1, q1, q9
1901	veor	q8, q4, q10
1902	vst1.8	{q0,q1}, [r8]!
1903	veor	q9, q6, q11
1904	veor	q10, q3, q12
1905	vst1.8	{q8,q9}, [r8]!
1906	vst1.8	{q10}, [r8]!
1907
1908	vld1.64	{q8}, [r0,:128]		@ next round tweak
1909	b	.Lxts_enc_done
1910.align	4
1911.Lxts_enc_4:
1912	veor	q2, q2, q10
1913#ifndef	BSAES_ASM_EXTENDED_KEY
1914	add	r4, sp, #0x90			@ pass key schedule
1915#else
1916	add	r4, r10, #248			@ pass key schedule
1917#endif
1918	veor	q3, q3, q11
1919	mov	r5, r1			@ pass rounds
1920	mov	r0, sp
1921
1922	bl	_bsaes_encrypt8
1923
1924	vld1.64	{q8,q9}, [r0,:128]!
1925	vld1.64	{q10,q11}, [r0,:128]!
1926	veor	q0, q0, q8
1927	veor	q1, q1, q9
1928	veor	q8, q4, q10
1929	vst1.8	{q0,q1}, [r8]!
1930	veor	q9, q6, q11
1931	vst1.8	{q8,q9}, [r8]!
1932
1933	vld1.64	{q8}, [r0,:128]		@ next round tweak
1934	b	.Lxts_enc_done
1935.align	4
1936.Lxts_enc_3:
1937	veor	q1, q1, q9
1938#ifndef	BSAES_ASM_EXTENDED_KEY
1939	add	r4, sp, #0x90			@ pass key schedule
1940#else
1941	add	r4, r10, #248			@ pass key schedule
1942#endif
1943	veor	q2, q2, q10
1944	mov	r5, r1			@ pass rounds
1945	mov	r0, sp
1946
1947	bl	_bsaes_encrypt8
1948
1949	vld1.64	{q8,q9}, [r0,:128]!
1950	vld1.64	{q10}, [r0,:128]!
1951	veor	q0, q0, q8
1952	veor	q1, q1, q9
1953	veor	q8, q4, q10
1954	vst1.8	{q0,q1}, [r8]!
1955	vst1.8	{q8}, [r8]!
1956
1957	vld1.64	{q8}, [r0,:128]		@ next round tweak
1958	b	.Lxts_enc_done
1959.align	4
1960.Lxts_enc_2:
1961	veor	q0, q0, q8
1962#ifndef	BSAES_ASM_EXTENDED_KEY
1963	add	r4, sp, #0x90			@ pass key schedule
1964#else
1965	add	r4, r10, #248			@ pass key schedule
1966#endif
1967	veor	q1, q1, q9
1968	mov	r5, r1			@ pass rounds
1969	mov	r0, sp
1970
1971	bl	_bsaes_encrypt8
1972
1973	vld1.64	{q8,q9}, [r0,:128]!
1974	veor	q0, q0, q8
1975	veor	q1, q1, q9
1976	vst1.8	{q0,q1}, [r8]!
1977
1978	vld1.64	{q8}, [r0,:128]		@ next round tweak
1979	b	.Lxts_enc_done
1980.align	4
1981.Lxts_enc_1:
1982	mov	r0, sp
1983	veor	q0, q0, q8
1984	mov	r1, sp
1985	vst1.8	{q0}, [sp,:128]
1986	mov	r2, r10
1987	mov	r4, r3				@ preserve fp
1988
1989	bl	AES_encrypt
1990
1991	vld1.8	{q0}, [sp,:128]
1992	veor	q0, q0, q8
1993	vst1.8	{q0}, [r8]!
1994	mov	r3, r4
1995
1996	vmov	q8, q9		@ next round tweak
1997
1998.Lxts_enc_done:
1999#ifndef	XTS_CHAIN_TWEAK
2000	adds	r9, #0x10
2001	beq	.Lxts_enc_ret
2002	sub	r6, r8, #0x10
2003
2004.Lxts_enc_steal:
2005	ldrb	r0, [r7], #1
2006	ldrb	r1, [r8, #-0x10]
2007	strb	r0, [r8, #-0x10]
2008	strb	r1, [r8], #1
2009
2010	subs	r9, #1
2011	bhi	.Lxts_enc_steal
2012
2013	vld1.8	{q0}, [r6]
2014	mov	r0, sp
2015	veor	q0, q0, q8
2016	mov	r1, sp
2017	vst1.8	{q0}, [sp,:128]
2018	mov	r2, r10
2019	mov	r4, r3			@ preserve fp
2020
2021	bl	AES_encrypt
2022
2023	vld1.8	{q0}, [sp,:128]
2024	veor	q0, q0, q8
2025	vst1.8	{q0}, [r6]
2026	mov	r3, r4
2027#endif
2028
2029.Lxts_enc_ret:
2030	bic	r0, r3, #0xf
2031	vmov.i32	q0, #0
2032	vmov.i32	q1, #0
2033#ifdef	XTS_CHAIN_TWEAK
2034	ldr	r1, [r3, #0x20+VFP_ABI_FRAME]	@ chain tweak
2035#endif
2036.Lxts_enc_bzero:@ wipe key schedule [if any]
2037	vstmia	sp!, {q0,q1}
2038	cmp	sp, r0
2039	bne	.Lxts_enc_bzero
2040
2041	mov	sp, r3
2042#ifdef	XTS_CHAIN_TWEAK
2043	vst1.8	{q8}, [r1]
2044#endif
2045	VFP_ABI_POP
2046	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}	@ return
2047
2048.size	ossl_bsaes_xts_encrypt,.-ossl_bsaes_xts_encrypt
2049
2050.globl	ossl_bsaes_xts_decrypt
2051.type	ossl_bsaes_xts_decrypt,%function
2052.align	4
2053ossl_bsaes_xts_decrypt:
2054	mov	ip, sp
2055	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}		@ 0x20
2056	VFP_ABI_PUSH
2057	mov	r6, sp				@ future r3
2058
2059	mov	r7, r0
2060	mov	r8, r1
2061	mov	r9, r2
2062	mov	r10, r3
2063
2064	sub	r0, sp, #0x10			@ 0x10
2065	bic	r0, #0xf			@ align at 16 bytes
2066	mov	sp, r0
2067
2068#ifdef	XTS_CHAIN_TWEAK
2069	ldr	r0, [ip]			@ pointer to input tweak
2070#else
2071	@ generate initial tweak
2072	ldr	r0, [ip, #4]			@ iv[]
2073	mov	r1, sp
2074	ldr	r2, [ip, #0]			@ key2
2075	bl	AES_encrypt
2076	mov	r0, sp				@ pointer to initial tweak
2077#endif
2078
2079	ldr	r1, [r10, #240]		@ get # of rounds
2080	mov	r3, r6
2081#ifndef	BSAES_ASM_EXTENDED_KEY
2082	@ allocate the key schedule on the stack
2083	sub	r12, sp, r1, lsl#7		@ 128 bytes per inner round key
2084	@ add	r12, #96			@ size of bit-sliced key schedule
2085	sub	r12, #48			@ place for tweak[9]
2086
2087	@ populate the key schedule
2088	mov	r4, r10			@ pass key
2089	mov	r5, r1			@ pass # of rounds
2090	mov	sp, r12
2091	add	r12, #0x90			@ pass key schedule
2092	bl	_bsaes_key_convert
2093	add	r4, sp, #0x90
2094	vldmia	r4, {q6}
2095	vstmia	r12,  {q15}		@ save last round key
2096	veor	q7, q7, q6	@ fix up round 0 key
2097	vstmia	r4, {q7}
2098#else
2099	ldr	r12, [r10, #244]
2100	eors	r12, #1
2101	beq	0f
2102
2103	str	r12, [r10, #244]
2104	mov	r4, r10			@ pass key
2105	mov	r5, r1			@ pass # of rounds
2106	add	r12, r10, #248			@ pass key schedule
2107	bl	_bsaes_key_convert
2108	add	r4, r10, #248
2109	vldmia	r4, {q6}
2110	vstmia	r12,  {q15}		@ save last round key
2111	veor	q7, q7, q6	@ fix up round 0 key
2112	vstmia	r4, {q7}
2113
2114.align	2
21150:	sub	sp, #0x90			@ place for tweak[9]
2116#endif
2117	vld1.8	{q8}, [r0]			@ initial tweak
2118	adr	r2, .Lxts_magic
2119
2120#ifndef	XTS_CHAIN_TWEAK
2121	tst	r9, #0xf			@ if not multiple of 16
2122	it	ne				@ Thumb2 thing, sanity check in ARM
2123	subne	r9, #0x10			@ subtract another 16 bytes
2124#endif
2125	subs	r9, #0x80
2126
2127	blo	.Lxts_dec_short
2128	b	.Lxts_dec_loop
2129
2130.align	4
2131.Lxts_dec_loop:
2132	vldmia	r2, {q5}	@ load XTS magic
2133	vshr.s64	q6, q8, #63
2134	mov	r0, sp
2135	vand	q6, q6, q5
2136	vadd.u64	q9, q8, q8
2137	vst1.64	{q8}, [r0,:128]!
2138	vswp	d13,d12
2139	vshr.s64	q7, q9, #63
2140	veor	q9, q9, q6
2141	vand	q7, q7, q5
2142	vadd.u64	q10, q9, q9
2143	vst1.64	{q9}, [r0,:128]!
2144	vswp	d15,d14
2145	vshr.s64	q6, q10, #63
2146	veor	q10, q10, q7
2147	vand	q6, q6, q5
2148	vld1.8	{q0}, [r7]!
2149	vadd.u64	q11, q10, q10
2150	vst1.64	{q10}, [r0,:128]!
2151	vswp	d13,d12
2152	vshr.s64	q7, q11, #63
2153	veor	q11, q11, q6
2154	vand	q7, q7, q5
2155	vld1.8	{q1}, [r7]!
2156	veor	q0, q0, q8
2157	vadd.u64	q12, q11, q11
2158	vst1.64	{q11}, [r0,:128]!
2159	vswp	d15,d14
2160	vshr.s64	q6, q12, #63
2161	veor	q12, q12, q7
2162	vand	q6, q6, q5
2163	vld1.8	{q2}, [r7]!
2164	veor	q1, q1, q9
2165	vadd.u64	q13, q12, q12
2166	vst1.64	{q12}, [r0,:128]!
2167	vswp	d13,d12
2168	vshr.s64	q7, q13, #63
2169	veor	q13, q13, q6
2170	vand	q7, q7, q5
2171	vld1.8	{q3}, [r7]!
2172	veor	q2, q2, q10
2173	vadd.u64	q14, q13, q13
2174	vst1.64	{q13}, [r0,:128]!
2175	vswp	d15,d14
2176	vshr.s64	q6, q14, #63
2177	veor	q14, q14, q7
2178	vand	q6, q6, q5
2179	vld1.8	{q4}, [r7]!
2180	veor	q3, q3, q11
2181	vadd.u64	q15, q14, q14
2182	vst1.64	{q14}, [r0,:128]!
2183	vswp	d13,d12
2184	vshr.s64	q7, q15, #63
2185	veor	q15, q15, q6
2186	vand	q7, q7, q5
2187	vld1.8	{q5}, [r7]!
2188	veor	q4, q4, q12
2189	vadd.u64	q8, q15, q15
2190	vst1.64	{q15}, [r0,:128]!
2191	vswp	d15,d14
2192	veor	q8, q8, q7
2193	vst1.64	{q8}, [r0,:128]		@ next round tweak
2194
2195	vld1.8	{q6,q7}, [r7]!
2196	veor	q5, q5, q13
2197#ifndef	BSAES_ASM_EXTENDED_KEY
2198	add	r4, sp, #0x90			@ pass key schedule
2199#else
2200	add	r4, r10, #248			@ pass key schedule
2201#endif
2202	veor	q6, q6, q14
2203	mov	r5, r1			@ pass rounds
2204	veor	q7, q7, q15
2205	mov	r0, sp
2206
2207	bl	_bsaes_decrypt8
2208
2209	vld1.64	{q8,q9}, [r0,:128]!
2210	vld1.64	{q10,q11}, [r0,:128]!
2211	veor	q0, q0, q8
2212	vld1.64	{q12,q13}, [r0,:128]!
2213	veor	q1, q1, q9
2214	veor	q8, q6, q10
2215	vst1.8	{q0,q1}, [r8]!
2216	veor	q9, q4, q11
2217	vld1.64	{q14,q15}, [r0,:128]!
2218	veor	q10, q2, q12
2219	vst1.8	{q8,q9}, [r8]!
2220	veor	q11, q7, q13
2221	veor	q12, q3, q14
2222	vst1.8	{q10,q11}, [r8]!
2223	veor	q13, q5, q15
2224	vst1.8	{q12,q13}, [r8]!
2225
2226	vld1.64	{q8}, [r0,:128]		@ next round tweak
2227
2228	subs	r9, #0x80
2229	bpl	.Lxts_dec_loop
2230
2231.Lxts_dec_short:
2232	adds	r9, #0x70
2233	bmi	.Lxts_dec_done
2234
2235	vldmia	r2, {q5}	@ load XTS magic
2236	vshr.s64	q7, q8, #63
2237	mov	r0, sp
2238	vand	q7, q7, q5
2239	vadd.u64	q9, q8, q8
2240	vst1.64	{q8}, [r0,:128]!
2241	vswp	d15,d14
2242	vshr.s64	q6, q9, #63
2243	veor	q9, q9, q7
2244	vand	q6, q6, q5
2245	vadd.u64	q10, q9, q9
2246	vst1.64	{q9}, [r0,:128]!
2247	vswp	d13,d12
2248	vshr.s64	q7, q10, #63
2249	veor	q10, q10, q6
2250	vand	q7, q7, q5
2251	vld1.8	{q0}, [r7]!
2252	subs	r9, #0x10
2253	bmi	.Lxts_dec_1
2254	vadd.u64	q11, q10, q10
2255	vst1.64	{q10}, [r0,:128]!
2256	vswp	d15,d14
2257	vshr.s64	q6, q11, #63
2258	veor	q11, q11, q7
2259	vand	q6, q6, q5
2260	vld1.8	{q1}, [r7]!
2261	subs	r9, #0x10
2262	bmi	.Lxts_dec_2
2263	veor	q0, q0, q8
2264	vadd.u64	q12, q11, q11
2265	vst1.64	{q11}, [r0,:128]!
2266	vswp	d13,d12
2267	vshr.s64	q7, q12, #63
2268	veor	q12, q12, q6
2269	vand	q7, q7, q5
2270	vld1.8	{q2}, [r7]!
2271	subs	r9, #0x10
2272	bmi	.Lxts_dec_3
2273	veor	q1, q1, q9
2274	vadd.u64	q13, q12, q12
2275	vst1.64	{q12}, [r0,:128]!
2276	vswp	d15,d14
2277	vshr.s64	q6, q13, #63
2278	veor	q13, q13, q7
2279	vand	q6, q6, q5
2280	vld1.8	{q3}, [r7]!
2281	subs	r9, #0x10
2282	bmi	.Lxts_dec_4
2283	veor	q2, q2, q10
2284	vadd.u64	q14, q13, q13
2285	vst1.64	{q13}, [r0,:128]!
2286	vswp	d13,d12
2287	vshr.s64	q7, q14, #63
2288	veor	q14, q14, q6
2289	vand	q7, q7, q5
2290	vld1.8	{q4}, [r7]!
2291	subs	r9, #0x10
2292	bmi	.Lxts_dec_5
2293	veor	q3, q3, q11
2294	vadd.u64	q15, q14, q14
2295	vst1.64	{q14}, [r0,:128]!
2296	vswp	d15,d14
2297	vshr.s64	q6, q15, #63
2298	veor	q15, q15, q7
2299	vand	q6, q6, q5
2300	vld1.8	{q5}, [r7]!
2301	subs	r9, #0x10
2302	bmi	.Lxts_dec_6
2303	veor	q4, q4, q12
2304	sub	r9, #0x10
2305	vst1.64	{q15}, [r0,:128]		@ next round tweak
2306
2307	vld1.8	{q6}, [r7]!
2308	veor	q5, q5, q13
2309#ifndef	BSAES_ASM_EXTENDED_KEY
2310	add	r4, sp, #0x90			@ pass key schedule
2311#else
2312	add	r4, r10, #248			@ pass key schedule
2313#endif
2314	veor	q6, q6, q14
2315	mov	r5, r1			@ pass rounds
2316	mov	r0, sp
2317
2318	bl	_bsaes_decrypt8
2319
2320	vld1.64	{q8,q9}, [r0,:128]!
2321	vld1.64	{q10,q11}, [r0,:128]!
2322	veor	q0, q0, q8
2323	vld1.64	{q12,q13}, [r0,:128]!
2324	veor	q1, q1, q9
2325	veor	q8, q6, q10
2326	vst1.8	{q0,q1}, [r8]!
2327	veor	q9, q4, q11
2328	vld1.64	{q14}, [r0,:128]!
2329	veor	q10, q2, q12
2330	vst1.8	{q8,q9}, [r8]!
2331	veor	q11, q7, q13
2332	veor	q12, q3, q14
2333	vst1.8	{q10,q11}, [r8]!
2334	vst1.8	{q12}, [r8]!
2335
2336	vld1.64	{q8}, [r0,:128]		@ next round tweak
2337	b	.Lxts_dec_done
2338.align	4
2339.Lxts_dec_6:
2340	vst1.64	{q14}, [r0,:128]		@ next round tweak
2341
2342	veor	q4, q4, q12
2343#ifndef	BSAES_ASM_EXTENDED_KEY
2344	add	r4, sp, #0x90			@ pass key schedule
2345#else
2346	add	r4, r10, #248			@ pass key schedule
2347#endif
2348	veor	q5, q5, q13
2349	mov	r5, r1			@ pass rounds
2350	mov	r0, sp
2351
2352	bl	_bsaes_decrypt8
2353
2354	vld1.64	{q8,q9}, [r0,:128]!
2355	vld1.64	{q10,q11}, [r0,:128]!
2356	veor	q0, q0, q8
2357	vld1.64	{q12,q13}, [r0,:128]!
2358	veor	q1, q1, q9
2359	veor	q8, q6, q10
2360	vst1.8	{q0,q1}, [r8]!
2361	veor	q9, q4, q11
2362	veor	q10, q2, q12
2363	vst1.8	{q8,q9}, [r8]!
2364	veor	q11, q7, q13
2365	vst1.8	{q10,q11}, [r8]!
2366
2367	vld1.64	{q8}, [r0,:128]		@ next round tweak
2368	b	.Lxts_dec_done
2369.align	4
2370.Lxts_dec_5:
2371	veor	q3, q3, q11
2372#ifndef	BSAES_ASM_EXTENDED_KEY
2373	add	r4, sp, #0x90			@ pass key schedule
2374#else
2375	add	r4, r10, #248			@ pass key schedule
2376#endif
2377	veor	q4, q4, q12
2378	mov	r5, r1			@ pass rounds
2379	mov	r0, sp
2380
2381	bl	_bsaes_decrypt8
2382
2383	vld1.64	{q8,q9}, [r0,:128]!
2384	vld1.64	{q10,q11}, [r0,:128]!
2385	veor	q0, q0, q8
2386	vld1.64	{q12}, [r0,:128]!
2387	veor	q1, q1, q9
2388	veor	q8, q6, q10
2389	vst1.8	{q0,q1}, [r8]!
2390	veor	q9, q4, q11
2391	veor	q10, q2, q12
2392	vst1.8	{q8,q9}, [r8]!
2393	vst1.8	{q10}, [r8]!
2394
2395	vld1.64	{q8}, [r0,:128]		@ next round tweak
2396	b	.Lxts_dec_done
2397.align	4
2398.Lxts_dec_4:
2399	veor	q2, q2, q10
2400#ifndef	BSAES_ASM_EXTENDED_KEY
2401	add	r4, sp, #0x90			@ pass key schedule
2402#else
2403	add	r4, r10, #248			@ pass key schedule
2404#endif
2405	veor	q3, q3, q11
2406	mov	r5, r1			@ pass rounds
2407	mov	r0, sp
2408
2409	bl	_bsaes_decrypt8
2410
2411	vld1.64	{q8,q9}, [r0,:128]!
2412	vld1.64	{q10,q11}, [r0,:128]!
2413	veor	q0, q0, q8
2414	veor	q1, q1, q9
2415	veor	q8, q6, q10
2416	vst1.8	{q0,q1}, [r8]!
2417	veor	q9, q4, q11
2418	vst1.8	{q8,q9}, [r8]!
2419
2420	vld1.64	{q8}, [r0,:128]		@ next round tweak
2421	b	.Lxts_dec_done
2422.align	4
2423.Lxts_dec_3:
2424	veor	q1, q1, q9
2425#ifndef	BSAES_ASM_EXTENDED_KEY
2426	add	r4, sp, #0x90			@ pass key schedule
2427#else
2428	add	r4, r10, #248			@ pass key schedule
2429#endif
2430	veor	q2, q2, q10
2431	mov	r5, r1			@ pass rounds
2432	mov	r0, sp
2433
2434	bl	_bsaes_decrypt8
2435
2436	vld1.64	{q8,q9}, [r0,:128]!
2437	vld1.64	{q10}, [r0,:128]!
2438	veor	q0, q0, q8
2439	veor	q1, q1, q9
2440	veor	q8, q6, q10
2441	vst1.8	{q0,q1}, [r8]!
2442	vst1.8	{q8}, [r8]!
2443
2444	vld1.64	{q8}, [r0,:128]		@ next round tweak
2445	b	.Lxts_dec_done
2446.align	4
2447.Lxts_dec_2:
2448	veor	q0, q0, q8
2449#ifndef	BSAES_ASM_EXTENDED_KEY
2450	add	r4, sp, #0x90			@ pass key schedule
2451#else
2452	add	r4, r10, #248			@ pass key schedule
2453#endif
2454	veor	q1, q1, q9
2455	mov	r5, r1			@ pass rounds
2456	mov	r0, sp
2457
2458	bl	_bsaes_decrypt8
2459
2460	vld1.64	{q8,q9}, [r0,:128]!
2461	veor	q0, q0, q8
2462	veor	q1, q1, q9
2463	vst1.8	{q0,q1}, [r8]!
2464
2465	vld1.64	{q8}, [r0,:128]		@ next round tweak
2466	b	.Lxts_dec_done
2467.align	4
2468.Lxts_dec_1:
2469	mov	r0, sp
2470	veor	q0, q0, q8
2471	mov	r1, sp
2472	vst1.8	{q0}, [sp,:128]
2473	mov	r5, r2			@ preserve magic
2474	mov	r2, r10
2475	mov	r4, r3				@ preserve fp
2476
2477	bl	AES_decrypt
2478
2479	vld1.8	{q0}, [sp,:128]
2480	veor	q0, q0, q8
2481	vst1.8	{q0}, [r8]!
2482	mov	r3, r4
2483	mov	r2, r5
2484
2485	vmov	q8, q9		@ next round tweak
2486
2487.Lxts_dec_done:
2488#ifndef	XTS_CHAIN_TWEAK
2489	adds	r9, #0x10
2490	beq	.Lxts_dec_ret
2491
2492	@ calculate one round of extra tweak for the stolen ciphertext
2493	vldmia	r2, {q5}
2494	vshr.s64	q6, q8, #63
2495	vand	q6, q6, q5
2496	vadd.u64	q9, q8, q8
2497	vswp	d13,d12
2498	veor	q9, q9, q6
2499
2500	@ perform the final decryption with the last tweak value
2501	vld1.8	{q0}, [r7]!
2502	mov	r0, sp
2503	veor	q0, q0, q9
2504	mov	r1, sp
2505	vst1.8	{q0}, [sp,:128]
2506	mov	r2, r10
2507	mov	r4, r3			@ preserve fp
2508
2509	bl	AES_decrypt
2510
2511	vld1.8	{q0}, [sp,:128]
2512	veor	q0, q0, q9
2513	vst1.8	{q0}, [r8]
2514
2515	mov	r6, r8
2516.Lxts_dec_steal:
2517	ldrb	r1, [r8]
2518	ldrb	r0, [r7], #1
2519	strb	r1, [r8, #0x10]
2520	strb	r0, [r8], #1
2521
2522	subs	r9, #1
2523	bhi	.Lxts_dec_steal
2524
2525	vld1.8	{q0}, [r6]
2526	mov	r0, sp
2527	veor	q0, q8
2528	mov	r1, sp
2529	vst1.8	{q0}, [sp,:128]
2530	mov	r2, r10
2531
2532	bl	AES_decrypt
2533
2534	vld1.8	{q0}, [sp,:128]
2535	veor	q0, q0, q8
2536	vst1.8	{q0}, [r6]
2537	mov	r3, r4
2538#endif
2539
2540.Lxts_dec_ret:
2541	bic	r0, r3, #0xf
2542	vmov.i32	q0, #0
2543	vmov.i32	q1, #0
2544#ifdef	XTS_CHAIN_TWEAK
2545	ldr	r1, [r3, #0x20+VFP_ABI_FRAME]	@ chain tweak
2546#endif
2547.Lxts_dec_bzero:@ wipe key schedule [if any]
2548	vstmia	sp!, {q0,q1}
2549	cmp	sp, r0
2550	bne	.Lxts_dec_bzero
2551
2552	mov	sp, r3
2553#ifdef	XTS_CHAIN_TWEAK
2554	vst1.8	{q8}, [r1]
2555#endif
2556	VFP_ABI_POP
2557	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}	@ return
2558
2559.size	ossl_bsaes_xts_decrypt,.-ossl_bsaes_xts_decrypt
2560#endif
2561