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