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