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