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