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