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