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