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