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