xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/gen/bcm/bsaes-armv7-linux.S (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1// This file is generated from a similarly-named Perl script in the BoringSSL
2// source tree. Do not edit by hand.
3
4#include <openssl/asm_base.h>
5
6#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_ARM) && defined(__ELF__)
7@ Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
8@
9@ Licensed under the OpenSSL license (the "License").  You may not use
10@ this file except in compliance with the License.  You can obtain a copy
11@ in the file LICENSE in the source distribution or at
12@ https://www.openssl.org/source/license.html
13
14
15@ ====================================================================
16@ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
17@ project. The module is, however, dual licensed under OpenSSL and
18@ CRYPTOGAMS licenses depending on where you obtain it. For further
19@ details see http://www.openssl.org/~appro/cryptogams/.
20@
21@ Specific modes and adaptation for Linux kernel by Ard Biesheuvel
22@ of Linaro. Permission to use under GPL terms is granted.
23@ ====================================================================
24
25@ Bit-sliced AES for ARM NEON
26@
27@ February 2012.
28@
29@ This implementation is direct adaptation of bsaes-x86_64 module for
30@ ARM NEON. Except that this module is endian-neutral [in sense that
31@ it can be compiled for either endianness] by courtesy of vld1.8's
32@ neutrality. Initial version doesn't implement interface to OpenSSL,
33@ only low-level primitives and unsupported entry points, just enough
34@ to collect performance results, which for Cortex-A8 core are:
35@
36@ encrypt	19.5 cycles per byte processed with 128-bit key
37@ decrypt	22.1 cycles per byte processed with 128-bit key
38@ key conv.	440  cycles per 128-bit key/0.18 of 8x block
39@
40@ Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7,
41@ which is [much] worse than anticipated (for further details see
42@ http://www.openssl.org/~appro/Snapdragon-S4.html).
43@
44@ Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code
45@ manages in 20.0 cycles].
46@
47@ When comparing to x86_64 results keep in mind that NEON unit is
48@ [mostly] single-issue and thus can't [fully] benefit from
49@ instruction-level parallelism. And when comparing to aes-armv4
50@ results keep in mind key schedule conversion overhead (see
51@ bsaes-x86_64.pl for further details)...
52@
53@						<[email protected]>
54
55@ April-August 2013
56@ Add CBC, CTR and XTS subroutines and adapt for kernel use; courtesy of Ard.
57
58#ifndef __KERNEL__
59# include <openssl/arm_arch.h>
60
61# define VFP_ABI_PUSH	vstmdb	sp!,{d8-d15}
62# define VFP_ABI_POP	vldmia	sp!,{d8-d15}
63# define VFP_ABI_FRAME	0x40
64#else
65# define VFP_ABI_PUSH
66# define VFP_ABI_POP
67# define VFP_ABI_FRAME	0
68# define BSAES_ASM_EXTENDED_KEY
69# define XTS_CHAIN_TWEAK
70# define __ARM_MAX_ARCH__ 7
71#endif
72
73#ifdef __thumb__
74# define adrl adr
75#endif
76
77#if __ARM_MAX_ARCH__>=7
78.arch	armv7-a
79.fpu	neon
80
81.text
82.syntax	unified 	@ ARMv7-capable assembler is expected to handle this
83#if defined(__thumb2__) && !defined(__APPLE__)
84.thumb
85#else
86.code	32
87# undef __thumb2__
88#endif
89
90.type	_bsaes_decrypt8,%function
91.align	4
92_bsaes_decrypt8:
93	adr	r6,.
94	vldmia	r4!, {q9}		@ round 0 key
95#if defined(__thumb2__) || defined(__APPLE__)
96	adr	r6,.LM0ISR
97#else
98	add	r6,r6,#.LM0ISR-_bsaes_decrypt8
99#endif
100
101	vldmia	r6!, {q8}		@ .LM0ISR
102	veor	q10, q0, q9	@ xor with round0 key
103	veor	q11, q1, q9
104	vtbl.8	d0, {q10}, d16
105	vtbl.8	d1, {q10}, d17
106	veor	q12, q2, q9
107	vtbl.8	d2, {q11}, d16
108	vtbl.8	d3, {q11}, d17
109	veor	q13, q3, q9
110	vtbl.8	d4, {q12}, d16
111	vtbl.8	d5, {q12}, d17
112	veor	q14, q4, q9
113	vtbl.8	d6, {q13}, d16
114	vtbl.8	d7, {q13}, d17
115	veor	q15, q5, q9
116	vtbl.8	d8, {q14}, d16
117	vtbl.8	d9, {q14}, d17
118	veor	q10, q6, q9
119	vtbl.8	d10, {q15}, d16
120	vtbl.8	d11, {q15}, d17
121	veor	q11, q7, q9
122	vtbl.8	d12, {q10}, d16
123	vtbl.8	d13, {q10}, d17
124	vtbl.8	d14, {q11}, d16
125	vtbl.8	d15, {q11}, d17
126	vmov.i8	q8,#0x55			@ compose .LBS0
127	vmov.i8	q9,#0x33			@ compose .LBS1
128	vshr.u64	q10, q6, #1
129	vshr.u64	q11, q4, #1
130	veor	q10, q10, q7
131	veor	q11, q11, q5
132	vand	q10, q10, q8
133	vand	q11, q11, q8
134	veor	q7, q7, q10
135	vshl.u64	q10, q10, #1
136	veor	q5, q5, q11
137	vshl.u64	q11, q11, #1
138	veor	q6, q6, q10
139	veor	q4, q4, q11
140	vshr.u64	q10, q2, #1
141	vshr.u64	q11, q0, #1
142	veor	q10, q10, q3
143	veor	q11, q11, q1
144	vand	q10, q10, q8
145	vand	q11, q11, q8
146	veor	q3, q3, q10
147	vshl.u64	q10, q10, #1
148	veor	q1, q1, q11
149	vshl.u64	q11, q11, #1
150	veor	q2, q2, q10
151	veor	q0, q0, q11
152	vmov.i8	q8,#0x0f			@ compose .LBS2
153	vshr.u64	q10, q5, #2
154	vshr.u64	q11, q4, #2
155	veor	q10, q10, q7
156	veor	q11, q11, q6
157	vand	q10, q10, q9
158	vand	q11, q11, q9
159	veor	q7, q7, q10
160	vshl.u64	q10, q10, #2
161	veor	q6, q6, q11
162	vshl.u64	q11, q11, #2
163	veor	q5, q5, q10
164	veor	q4, q4, q11
165	vshr.u64	q10, q1, #2
166	vshr.u64	q11, q0, #2
167	veor	q10, q10, q3
168	veor	q11, q11, q2
169	vand	q10, q10, q9
170	vand	q11, q11, q9
171	veor	q3, q3, q10
172	vshl.u64	q10, q10, #2
173	veor	q2, q2, q11
174	vshl.u64	q11, q11, #2
175	veor	q1, q1, q10
176	veor	q0, q0, q11
177	vshr.u64	q10, q3, #4
178	vshr.u64	q11, q2, #4
179	veor	q10, q10, q7
180	veor	q11, q11, q6
181	vand	q10, q10, q8
182	vand	q11, q11, q8
183	veor	q7, q7, q10
184	vshl.u64	q10, q10, #4
185	veor	q6, q6, q11
186	vshl.u64	q11, q11, #4
187	veor	q3, q3, q10
188	veor	q2, q2, q11
189	vshr.u64	q10, q1, #4
190	vshr.u64	q11, q0, #4
191	veor	q10, q10, q5
192	veor	q11, q11, q4
193	vand	q10, q10, q8
194	vand	q11, q11, q8
195	veor	q5, q5, q10
196	vshl.u64	q10, q10, #4
197	veor	q4, q4, q11
198	vshl.u64	q11, q11, #4
199	veor	q1, q1, q10
200	veor	q0, q0, q11
201	sub	r5,r5,#1
202	b	.Ldec_sbox
203.align	4
204.Ldec_loop:
205	vldmia	r4!, {q8,q9,q10,q11}
206	veor	q8, q8, q0
207	veor	q9, q9, q1
208	vtbl.8	d0, {q8}, d24
209	vtbl.8	d1, {q8}, d25
210	vldmia	r4!, {q8}
211	veor	q10, q10, q2
212	vtbl.8	d2, {q9}, d24
213	vtbl.8	d3, {q9}, d25
214	vldmia	r4!, {q9}
215	veor	q11, q11, q3
216	vtbl.8	d4, {q10}, d24
217	vtbl.8	d5, {q10}, d25
218	vldmia	r4!, {q10}
219	vtbl.8	d6, {q11}, d24
220	vtbl.8	d7, {q11}, d25
221	vldmia	r4!, {q11}
222	veor	q8, q8, q4
223	veor	q9, q9, q5
224	vtbl.8	d8, {q8}, d24
225	vtbl.8	d9, {q8}, d25
226	veor	q10, q10, q6
227	vtbl.8	d10, {q9}, d24
228	vtbl.8	d11, {q9}, d25
229	veor	q11, q11, q7
230	vtbl.8	d12, {q10}, d24
231	vtbl.8	d13, {q10}, d25
232	vtbl.8	d14, {q11}, d24
233	vtbl.8	d15, {q11}, d25
234.Ldec_sbox:
235	veor	q1, q1, q4
236	veor	q3, q3, q4
237
238	veor	q4, q4, q7
239	veor	q1, q1, q6
240	veor	q2, q2, q7
241	veor	q6, q6, q4
242
243	veor	q0, q0, q1
244	veor	q2, q2, q5
245	veor	q7, q7, q6
246	veor	q3, q3, q0
247	veor	q5, q5, q0
248	veor	q1, q1, q3
249	veor	q11, q3, q0
250	veor	q10, q7, q4
251	veor	q9, q1, q6
252	veor	q13, q4, q0
253	vmov	q8, q10
254	veor	q12, q5, q2
255
256	vorr	q10, q10, q9
257	veor	q15, q11, q8
258	vand	q14, q11, q12
259	vorr	q11, q11, q12
260	veor	q12, q12, q9
261	vand	q8, q8, q9
262	veor	q9, q6, q2
263	vand	q15, q15, q12
264	vand	q13, q13, q9
265	veor	q9, q3, q7
266	veor	q12, q1, q5
267	veor	q11, q11, q13
268	veor	q10, q10, q13
269	vand	q13, q9, q12
270	vorr	q9, q9, q12
271	veor	q11, q11, q15
272	veor	q8, q8, q13
273	veor	q10, q10, q14
274	veor	q9, q9, q15
275	veor	q8, q8, q14
276	vand	q12, q4, q6
277	veor	q9, q9, q14
278	vand	q13, q0, q2
279	vand	q14, q7, q1
280	vorr	q15, q3, q5
281	veor	q11, q11, q12
282	veor	q9, q9, q14
283	veor	q8, q8, q15
284	veor	q10, q10, q13
285
286	@ Inv_GF16 	0, 	1, 	2, 	3, s0, s1, s2, s3
287
288	@ new smaller inversion
289
290	vand	q14, q11, q9
291	vmov	q12, q8
292
293	veor	q13, q10, q14
294	veor	q15, q8, q14
295	veor	q14, q8, q14	@ q14=q15
296
297	vbsl	q13, q9, q8
298	vbsl	q15, q11, q10
299	veor	q11, q11, q10
300
301	vbsl	q12, q13, q14
302	vbsl	q8, q14, q13
303
304	vand	q14, q12, q15
305	veor	q9, q9, q8
306
307	veor	q14, q14, q11
308	veor	q12, q5, q2
309	veor	q8, q1, q6
310	veor	q10, q15, q14
311	vand	q10, q10, q5
312	veor	q5, q5, q1
313	vand	q11, q1, q15
314	vand	q5, q5, q14
315	veor	q1, q11, q10
316	veor	q5, q5, q11
317	veor	q15, q15, q13
318	veor	q14, q14, q9
319	veor	q11, q15, q14
320	veor	q10, q13, q9
321	vand	q11, q11, q12
322	vand	q10, q10, q2
323	veor	q12, q12, q8
324	veor	q2, q2, q6
325	vand	q8, q8, q15
326	vand	q6, q6, q13
327	vand	q12, q12, q14
328	vand	q2, q2, q9
329	veor	q8, q8, q12
330	veor	q2, q2, q6
331	veor	q12, q12, q11
332	veor	q6, q6, q10
333	veor	q5, q5, q12
334	veor	q2, q2, q12
335	veor	q1, q1, q8
336	veor	q6, q6, q8
337
338	veor	q12, q3, q0
339	veor	q8, q7, q4
340	veor	q11, q15, q14
341	veor	q10, q13, q9
342	vand	q11, q11, q12
343	vand	q10, q10, q0
344	veor	q12, q12, q8
345	veor	q0, q0, q4
346	vand	q8, q8, q15
347	vand	q4, q4, q13
348	vand	q12, q12, q14
349	vand	q0, q0, q9
350	veor	q8, q8, q12
351	veor	q0, q0, q4
352	veor	q12, q12, q11
353	veor	q4, q4, q10
354	veor	q15, q15, q13
355	veor	q14, q14, q9
356	veor	q10, q15, q14
357	vand	q10, q10, q3
358	veor	q3, q3, q7
359	vand	q11, q7, q15
360	vand	q3, q3, q14
361	veor	q7, q11, q10
362	veor	q3, q3, q11
363	veor	q3, q3, q12
364	veor	q0, q0, q12
365	veor	q7, q7, q8
366	veor	q4, q4, q8
367	veor	q1, q1, q7
368	veor	q6, q6, q5
369
370	veor	q4, q4, q1
371	veor	q2, q2, q7
372	veor	q5, q5, q7
373	veor	q4, q4, q2
374	veor	q7, q7, q0
375	veor	q4, q4, q5
376	veor	q3, q3, q6
377	veor	q6, q6, q1
378	veor	q3, q3, q4
379
380	veor	q4, q4, q0
381	veor	q7, q7, q3
382	subs	r5,r5,#1
383	bcc	.Ldec_done
384	@ multiplication by 0x05-0x00-0x04-0x00
385	vext.8	q8, q0, q0, #8
386	vext.8	q14, q3, q3, #8
387	vext.8	q15, q5, q5, #8
388	veor	q8, q8, q0
389	vext.8	q9, q1, q1, #8
390	veor	q14, q14, q3
391	vext.8	q10, q6, q6, #8
392	veor	q15, q15, q5
393	vext.8	q11, q4, q4, #8
394	veor	q9, q9, q1
395	vext.8	q12, q2, q2, #8
396	veor	q10, q10, q6
397	vext.8	q13, q7, q7, #8
398	veor	q11, q11, q4
399	veor	q12, q12, q2
400	veor	q13, q13, q7
401
402	veor	q0, q0, q14
403	veor	q1, q1, q14
404	veor	q6, q6, q8
405	veor	q2, q2, q10
406	veor	q4, q4, q9
407	veor	q1, q1, q15
408	veor	q6, q6, q15
409	veor	q2, q2, q14
410	veor	q7, q7, q11
411	veor	q4, q4, q14
412	veor	q3, q3, q12
413	veor	q2, q2, q15
414	veor	q7, q7, q15
415	veor	q5, q5, q13
416	vext.8	q8, q0, q0, #12	@ x0 <<< 32
417	vext.8	q9, q1, q1, #12
418	veor	q0, q0, q8		@ x0 ^ (x0 <<< 32)
419	vext.8	q10, q6, q6, #12
420	veor	q1, q1, q9
421	vext.8	q11, q4, q4, #12
422	veor	q6, q6, q10
423	vext.8	q12, q2, q2, #12
424	veor	q4, q4, q11
425	vext.8	q13, q7, q7, #12
426	veor	q2, q2, q12
427	vext.8	q14, q3, q3, #12
428	veor	q7, q7, q13
429	vext.8	q15, q5, q5, #12
430	veor	q3, q3, q14
431
432	veor	q9, q9, q0
433	veor	q5, q5, q15
434	vext.8	q0, q0, q0, #8		@ (x0 ^ (x0 <<< 32)) <<< 64)
435	veor	q10, q10, q1
436	veor	q8, q8, q5
437	veor	q9, q9, q5
438	vext.8	q1, q1, q1, #8
439	veor	q13, q13, q2
440	veor	q0, q0, q8
441	veor	q14, q14, q7
442	veor	q1, q1, q9
443	vext.8	q8, q2, q2, #8
444	veor	q12, q12, q4
445	vext.8	q9, q7, q7, #8
446	veor	q15, q15, q3
447	vext.8	q2, q4, q4, #8
448	veor	q11, q11, q6
449	vext.8	q7, q5, q5, #8
450	veor	q12, q12, q5
451	vext.8	q4, q3, q3, #8
452	veor	q11, q11, q5
453	vext.8	q3, q6, q6, #8
454	veor	q5, q9, q13
455	veor	q11, q11, q2
456	veor	q7, q7, q15
457	veor	q6, q4, q14
458	veor	q4, q8, q12
459	veor	q2, q3, q10
460	vmov	q3, q11
461	 @ vmov	q5, q9
462	vldmia	r6, {q12}		@ .LISR
463	ite	eq				@ Thumb2 thing, sanity check in ARM
464	addeq	r6,r6,#0x10
465	bne	.Ldec_loop
466	vldmia	r6, {q12}		@ .LISRM0
467	b	.Ldec_loop
468.align	4
469.Ldec_done:
470	vmov.i8	q8,#0x55			@ compose .LBS0
471	vmov.i8	q9,#0x33			@ compose .LBS1
472	vshr.u64	q10, q3, #1
473	vshr.u64	q11, q2, #1
474	veor	q10, q10, q5
475	veor	q11, q11, q7
476	vand	q10, q10, q8
477	vand	q11, q11, q8
478	veor	q5, q5, q10
479	vshl.u64	q10, q10, #1
480	veor	q7, q7, q11
481	vshl.u64	q11, q11, #1
482	veor	q3, q3, q10
483	veor	q2, q2, q11
484	vshr.u64	q10, q6, #1
485	vshr.u64	q11, q0, #1
486	veor	q10, q10, q4
487	veor	q11, q11, q1
488	vand	q10, q10, q8
489	vand	q11, q11, q8
490	veor	q4, q4, q10
491	vshl.u64	q10, q10, #1
492	veor	q1, q1, q11
493	vshl.u64	q11, q11, #1
494	veor	q6, q6, q10
495	veor	q0, q0, q11
496	vmov.i8	q8,#0x0f			@ compose .LBS2
497	vshr.u64	q10, q7, #2
498	vshr.u64	q11, q2, #2
499	veor	q10, q10, q5
500	veor	q11, q11, q3
501	vand	q10, q10, q9
502	vand	q11, q11, q9
503	veor	q5, q5, q10
504	vshl.u64	q10, q10, #2
505	veor	q3, q3, q11
506	vshl.u64	q11, q11, #2
507	veor	q7, q7, q10
508	veor	q2, q2, q11
509	vshr.u64	q10, q1, #2
510	vshr.u64	q11, q0, #2
511	veor	q10, q10, q4
512	veor	q11, q11, q6
513	vand	q10, q10, q9
514	vand	q11, q11, q9
515	veor	q4, q4, q10
516	vshl.u64	q10, q10, #2
517	veor	q6, q6, q11
518	vshl.u64	q11, q11, #2
519	veor	q1, q1, q10
520	veor	q0, q0, q11
521	vshr.u64	q10, q4, #4
522	vshr.u64	q11, q6, #4
523	veor	q10, q10, q5
524	veor	q11, q11, q3
525	vand	q10, q10, q8
526	vand	q11, q11, q8
527	veor	q5, q5, q10
528	vshl.u64	q10, q10, #4
529	veor	q3, q3, q11
530	vshl.u64	q11, q11, #4
531	veor	q4, q4, q10
532	veor	q6, q6, q11
533	vshr.u64	q10, q1, #4
534	vshr.u64	q11, q0, #4
535	veor	q10, q10, q7
536	veor	q11, q11, q2
537	vand	q10, q10, q8
538	vand	q11, q11, q8
539	veor	q7, q7, q10
540	vshl.u64	q10, q10, #4
541	veor	q2, q2, q11
542	vshl.u64	q11, q11, #4
543	veor	q1, q1, q10
544	veor	q0, q0, q11
545	vldmia	r4, {q8}			@ last round key
546	veor	q6, q6, q8
547	veor	q4, q4, q8
548	veor	q2, q2, q8
549	veor	q7, q7, q8
550	veor	q3, q3, q8
551	veor	q5, q5, q8
552	veor	q0, q0, q8
553	veor	q1, q1, q8
554	bx	lr
555.size	_bsaes_decrypt8,.-_bsaes_decrypt8
556
557.type	_bsaes_const,%object
558.align	6
559_bsaes_const:
560.LM0ISR:@ InvShiftRows constants
561.quad	0x0a0e0206070b0f03, 0x0004080c0d010509
562.LISR:
563.quad	0x0504070602010003, 0x0f0e0d0c080b0a09
564.LISRM0:
565.quad	0x01040b0e0205080f, 0x0306090c00070a0d
566.LM0SR:@ ShiftRows constants
567.quad	0x0a0e02060f03070b, 0x0004080c05090d01
568.LSR:
569.quad	0x0504070600030201, 0x0f0e0d0c0a09080b
570.LSRM0:
571.quad	0x0304090e00050a0f, 0x01060b0c0207080d
572.LM0:
573.quad	0x02060a0e03070b0f, 0x0004080c0105090d
574.LREVM0SR:
575.quad	0x090d01050c000408, 0x03070b0f060a0e02
576.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
577.align	2
578.align	6
579.size	_bsaes_const,.-_bsaes_const
580
581.type	_bsaes_encrypt8,%function
582.align	4
583_bsaes_encrypt8:
584	adr	r6,.
585	vldmia	r4!, {q9}		@ round 0 key
586#if defined(__thumb2__) || defined(__APPLE__)
587	adr	r6,.LM0SR
588#else
589	sub	r6,r6,#_bsaes_encrypt8-.LM0SR
590#endif
591
592	vldmia	r6!, {q8}		@ .LM0SR
593_bsaes_encrypt8_alt:
594	veor	q10, q0, q9	@ xor with round0 key
595	veor	q11, q1, q9
596	vtbl.8	d0, {q10}, d16
597	vtbl.8	d1, {q10}, d17
598	veor	q12, q2, q9
599	vtbl.8	d2, {q11}, d16
600	vtbl.8	d3, {q11}, d17
601	veor	q13, q3, q9
602	vtbl.8	d4, {q12}, d16
603	vtbl.8	d5, {q12}, d17
604	veor	q14, q4, q9
605	vtbl.8	d6, {q13}, d16
606	vtbl.8	d7, {q13}, d17
607	veor	q15, q5, q9
608	vtbl.8	d8, {q14}, d16
609	vtbl.8	d9, {q14}, d17
610	veor	q10, q6, q9
611	vtbl.8	d10, {q15}, d16
612	vtbl.8	d11, {q15}, d17
613	veor	q11, q7, q9
614	vtbl.8	d12, {q10}, d16
615	vtbl.8	d13, {q10}, d17
616	vtbl.8	d14, {q11}, d16
617	vtbl.8	d15, {q11}, d17
618_bsaes_encrypt8_bitslice:
619	vmov.i8	q8,#0x55			@ compose .LBS0
620	vmov.i8	q9,#0x33			@ compose .LBS1
621	vshr.u64	q10, q6, #1
622	vshr.u64	q11, q4, #1
623	veor	q10, q10, q7
624	veor	q11, q11, q5
625	vand	q10, q10, q8
626	vand	q11, q11, q8
627	veor	q7, q7, q10
628	vshl.u64	q10, q10, #1
629	veor	q5, q5, q11
630	vshl.u64	q11, q11, #1
631	veor	q6, q6, q10
632	veor	q4, q4, q11
633	vshr.u64	q10, q2, #1
634	vshr.u64	q11, q0, #1
635	veor	q10, q10, q3
636	veor	q11, q11, q1
637	vand	q10, q10, q8
638	vand	q11, q11, q8
639	veor	q3, q3, q10
640	vshl.u64	q10, q10, #1
641	veor	q1, q1, q11
642	vshl.u64	q11, q11, #1
643	veor	q2, q2, q10
644	veor	q0, q0, q11
645	vmov.i8	q8,#0x0f			@ compose .LBS2
646	vshr.u64	q10, q5, #2
647	vshr.u64	q11, q4, #2
648	veor	q10, q10, q7
649	veor	q11, q11, q6
650	vand	q10, q10, q9
651	vand	q11, q11, q9
652	veor	q7, q7, q10
653	vshl.u64	q10, q10, #2
654	veor	q6, q6, q11
655	vshl.u64	q11, q11, #2
656	veor	q5, q5, q10
657	veor	q4, q4, q11
658	vshr.u64	q10, q1, #2
659	vshr.u64	q11, q0, #2
660	veor	q10, q10, q3
661	veor	q11, q11, q2
662	vand	q10, q10, q9
663	vand	q11, q11, q9
664	veor	q3, q3, q10
665	vshl.u64	q10, q10, #2
666	veor	q2, q2, q11
667	vshl.u64	q11, q11, #2
668	veor	q1, q1, q10
669	veor	q0, q0, q11
670	vshr.u64	q10, q3, #4
671	vshr.u64	q11, q2, #4
672	veor	q10, q10, q7
673	veor	q11, q11, q6
674	vand	q10, q10, q8
675	vand	q11, q11, q8
676	veor	q7, q7, q10
677	vshl.u64	q10, q10, #4
678	veor	q6, q6, q11
679	vshl.u64	q11, q11, #4
680	veor	q3, q3, q10
681	veor	q2, q2, q11
682	vshr.u64	q10, q1, #4
683	vshr.u64	q11, q0, #4
684	veor	q10, q10, q5
685	veor	q11, q11, q4
686	vand	q10, q10, q8
687	vand	q11, q11, q8
688	veor	q5, q5, q10
689	vshl.u64	q10, q10, #4
690	veor	q4, q4, q11
691	vshl.u64	q11, q11, #4
692	veor	q1, q1, q10
693	veor	q0, q0, q11
694	sub	r5,r5,#1
695	b	.Lenc_sbox
696.align	4
697.Lenc_loop:
698	vldmia	r4!, {q8,q9,q10,q11}
699	veor	q8, q8, q0
700	veor	q9, q9, q1
701	vtbl.8	d0, {q8}, d24
702	vtbl.8	d1, {q8}, d25
703	vldmia	r4!, {q8}
704	veor	q10, q10, q2
705	vtbl.8	d2, {q9}, d24
706	vtbl.8	d3, {q9}, d25
707	vldmia	r4!, {q9}
708	veor	q11, q11, q3
709	vtbl.8	d4, {q10}, d24
710	vtbl.8	d5, {q10}, d25
711	vldmia	r4!, {q10}
712	vtbl.8	d6, {q11}, d24
713	vtbl.8	d7, {q11}, d25
714	vldmia	r4!, {q11}
715	veor	q8, q8, q4
716	veor	q9, q9, q5
717	vtbl.8	d8, {q8}, d24
718	vtbl.8	d9, {q8}, d25
719	veor	q10, q10, q6
720	vtbl.8	d10, {q9}, d24
721	vtbl.8	d11, {q9}, d25
722	veor	q11, q11, q7
723	vtbl.8	d12, {q10}, d24
724	vtbl.8	d13, {q10}, d25
725	vtbl.8	d14, {q11}, d24
726	vtbl.8	d15, {q11}, d25
727.Lenc_sbox:
728	veor	q2, q2, q1
729	veor	q5, q5, q6
730	veor	q3, q3, q0
731	veor	q6, q6, q2
732	veor	q5, q5, q0
733
734	veor	q6, q6, q3
735	veor	q3, q3, q7
736	veor	q7, q7, q5
737	veor	q3, q3, q4
738	veor	q4, q4, q5
739
740	veor	q2, q2, q7
741	veor	q3, q3, q1
742	veor	q1, q1, q5
743	veor	q11, q7, q4
744	veor	q10, q1, q2
745	veor	q9, q5, q3
746	veor	q13, q2, q4
747	vmov	q8, q10
748	veor	q12, q6, q0
749
750	vorr	q10, q10, q9
751	veor	q15, q11, q8
752	vand	q14, q11, q12
753	vorr	q11, q11, q12
754	veor	q12, q12, q9
755	vand	q8, q8, q9
756	veor	q9, q3, q0
757	vand	q15, q15, q12
758	vand	q13, q13, q9
759	veor	q9, q7, q1
760	veor	q12, q5, q6
761	veor	q11, q11, q13
762	veor	q10, q10, q13
763	vand	q13, q9, q12
764	vorr	q9, q9, q12
765	veor	q11, q11, q15
766	veor	q8, q8, q13
767	veor	q10, q10, q14
768	veor	q9, q9, q15
769	veor	q8, q8, q14
770	vand	q12, q2, q3
771	veor	q9, q9, q14
772	vand	q13, q4, q0
773	vand	q14, q1, q5
774	vorr	q15, q7, q6
775	veor	q11, q11, q12
776	veor	q9, q9, q14
777	veor	q8, q8, q15
778	veor	q10, q10, q13
779
780	@ Inv_GF16 	0, 	1, 	2, 	3, s0, s1, s2, s3
781
782	@ new smaller inversion
783
784	vand	q14, q11, q9
785	vmov	q12, q8
786
787	veor	q13, q10, q14
788	veor	q15, q8, q14
789	veor	q14, q8, q14	@ q14=q15
790
791	vbsl	q13, q9, q8
792	vbsl	q15, q11, q10
793	veor	q11, q11, q10
794
795	vbsl	q12, q13, q14
796	vbsl	q8, q14, q13
797
798	vand	q14, q12, q15
799	veor	q9, q9, q8
800
801	veor	q14, q14, q11
802	veor	q12, q6, q0
803	veor	q8, q5, q3
804	veor	q10, q15, q14
805	vand	q10, q10, q6
806	veor	q6, q6, q5
807	vand	q11, q5, q15
808	vand	q6, q6, q14
809	veor	q5, q11, q10
810	veor	q6, q6, q11
811	veor	q15, q15, q13
812	veor	q14, q14, q9
813	veor	q11, q15, q14
814	veor	q10, q13, q9
815	vand	q11, q11, q12
816	vand	q10, q10, q0
817	veor	q12, q12, q8
818	veor	q0, q0, q3
819	vand	q8, q8, q15
820	vand	q3, q3, q13
821	vand	q12, q12, q14
822	vand	q0, q0, q9
823	veor	q8, q8, q12
824	veor	q0, q0, q3
825	veor	q12, q12, q11
826	veor	q3, q3, q10
827	veor	q6, q6, q12
828	veor	q0, q0, q12
829	veor	q5, q5, q8
830	veor	q3, q3, q8
831
832	veor	q12, q7, q4
833	veor	q8, q1, q2
834	veor	q11, q15, q14
835	veor	q10, q13, q9
836	vand	q11, q11, q12
837	vand	q10, q10, q4
838	veor	q12, q12, q8
839	veor	q4, q4, q2
840	vand	q8, q8, q15
841	vand	q2, q2, q13
842	vand	q12, q12, q14
843	vand	q4, q4, q9
844	veor	q8, q8, q12
845	veor	q4, q4, q2
846	veor	q12, q12, q11
847	veor	q2, q2, q10
848	veor	q15, q15, q13
849	veor	q14, q14, q9
850	veor	q10, q15, q14
851	vand	q10, q10, q7
852	veor	q7, q7, q1
853	vand	q11, q1, q15
854	vand	q7, q7, q14
855	veor	q1, q11, q10
856	veor	q7, q7, q11
857	veor	q7, q7, q12
858	veor	q4, q4, q12
859	veor	q1, q1, q8
860	veor	q2, q2, q8
861	veor	q7, q7, q0
862	veor	q1, q1, q6
863	veor	q6, q6, q0
864	veor	q4, q4, q7
865	veor	q0, q0, q1
866
867	veor	q1, q1, q5
868	veor	q5, q5, q2
869	veor	q2, q2, q3
870	veor	q3, q3, q5
871	veor	q4, q4, q5
872
873	veor	q6, q6, q3
874	subs	r5,r5,#1
875	bcc	.Lenc_done
876	vext.8	q8, q0, q0, #12	@ x0 <<< 32
877	vext.8	q9, q1, q1, #12
878	veor	q0, q0, q8		@ x0 ^ (x0 <<< 32)
879	vext.8	q10, q4, q4, #12
880	veor	q1, q1, q9
881	vext.8	q11, q6, q6, #12
882	veor	q4, q4, q10
883	vext.8	q12, q3, q3, #12
884	veor	q6, q6, q11
885	vext.8	q13, q7, q7, #12
886	veor	q3, q3, q12
887	vext.8	q14, q2, q2, #12
888	veor	q7, q7, q13
889	vext.8	q15, q5, q5, #12
890	veor	q2, q2, q14
891
892	veor	q9, q9, q0
893	veor	q5, q5, q15
894	vext.8	q0, q0, q0, #8		@ (x0 ^ (x0 <<< 32)) <<< 64)
895	veor	q10, q10, q1
896	veor	q8, q8, q5
897	veor	q9, q9, q5
898	vext.8	q1, q1, q1, #8
899	veor	q13, q13, q3
900	veor	q0, q0, q8
901	veor	q14, q14, q7
902	veor	q1, q1, q9
903	vext.8	q8, q3, q3, #8
904	veor	q12, q12, q6
905	vext.8	q9, q7, q7, #8
906	veor	q15, q15, q2
907	vext.8	q3, q6, q6, #8
908	veor	q11, q11, q4
909	vext.8	q7, q5, q5, #8
910	veor	q12, q12, q5
911	vext.8	q6, q2, q2, #8
912	veor	q11, q11, q5
913	vext.8	q2, q4, q4, #8
914	veor	q5, q9, q13
915	veor	q4, q8, q12
916	veor	q3, q3, q11
917	veor	q7, q7, q15
918	veor	q6, q6, q14
919	 @ vmov	q4, q8
920	veor	q2, q2, q10
921	 @ vmov	q5, q9
922	vldmia	r6, {q12}		@ .LSR
923	ite	eq				@ Thumb2 thing, samity check in ARM
924	addeq	r6,r6,#0x10
925	bne	.Lenc_loop
926	vldmia	r6, {q12}		@ .LSRM0
927	b	.Lenc_loop
928.align	4
929.Lenc_done:
930	vmov.i8	q8,#0x55			@ compose .LBS0
931	vmov.i8	q9,#0x33			@ compose .LBS1
932	vshr.u64	q10, q2, #1
933	vshr.u64	q11, q3, #1
934	veor	q10, q10, q5
935	veor	q11, q11, q7
936	vand	q10, q10, q8
937	vand	q11, q11, q8
938	veor	q5, q5, q10
939	vshl.u64	q10, q10, #1
940	veor	q7, q7, q11
941	vshl.u64	q11, q11, #1
942	veor	q2, q2, q10
943	veor	q3, q3, q11
944	vshr.u64	q10, q4, #1
945	vshr.u64	q11, q0, #1
946	veor	q10, q10, q6
947	veor	q11, q11, q1
948	vand	q10, q10, q8
949	vand	q11, q11, q8
950	veor	q6, q6, q10
951	vshl.u64	q10, q10, #1
952	veor	q1, q1, q11
953	vshl.u64	q11, q11, #1
954	veor	q4, q4, q10
955	veor	q0, q0, q11
956	vmov.i8	q8,#0x0f			@ compose .LBS2
957	vshr.u64	q10, q7, #2
958	vshr.u64	q11, q3, #2
959	veor	q10, q10, q5
960	veor	q11, q11, q2
961	vand	q10, q10, q9
962	vand	q11, q11, q9
963	veor	q5, q5, q10
964	vshl.u64	q10, q10, #2
965	veor	q2, q2, q11
966	vshl.u64	q11, q11, #2
967	veor	q7, q7, q10
968	veor	q3, q3, q11
969	vshr.u64	q10, q1, #2
970	vshr.u64	q11, q0, #2
971	veor	q10, q10, q6
972	veor	q11, q11, q4
973	vand	q10, q10, q9
974	vand	q11, q11, q9
975	veor	q6, q6, q10
976	vshl.u64	q10, q10, #2
977	veor	q4, q4, q11
978	vshl.u64	q11, q11, #2
979	veor	q1, q1, q10
980	veor	q0, q0, q11
981	vshr.u64	q10, q6, #4
982	vshr.u64	q11, q4, #4
983	veor	q10, q10, q5
984	veor	q11, q11, q2
985	vand	q10, q10, q8
986	vand	q11, q11, q8
987	veor	q5, q5, q10
988	vshl.u64	q10, q10, #4
989	veor	q2, q2, q11
990	vshl.u64	q11, q11, #4
991	veor	q6, q6, q10
992	veor	q4, q4, q11
993	vshr.u64	q10, q1, #4
994	vshr.u64	q11, q0, #4
995	veor	q10, q10, q7
996	veor	q11, q11, q3
997	vand	q10, q10, q8
998	vand	q11, q11, q8
999	veor	q7, q7, q10
1000	vshl.u64	q10, q10, #4
1001	veor	q3, q3, q11
1002	vshl.u64	q11, q11, #4
1003	veor	q1, q1, q10
1004	veor	q0, q0, q11
1005	vldmia	r4, {q8}			@ last round key
1006	veor	q4, q4, q8
1007	veor	q6, q6, q8
1008	veor	q3, q3, q8
1009	veor	q7, q7, q8
1010	veor	q2, q2, q8
1011	veor	q5, q5, q8
1012	veor	q0, q0, q8
1013	veor	q1, q1, q8
1014	bx	lr
1015.size	_bsaes_encrypt8,.-_bsaes_encrypt8
1016.type	_bsaes_key_convert,%function
1017.align	4
1018_bsaes_key_convert:
1019	adr	r6,.
1020	vld1.8	{q7},  [r4]!		@ load round 0 key
1021#if defined(__thumb2__) || defined(__APPLE__)
1022	adr	r6,.LM0
1023#else
1024	sub	r6,r6,#_bsaes_key_convert-.LM0
1025#endif
1026	vld1.8	{q15}, [r4]!		@ load round 1 key
1027
1028	vmov.i8	q8,  #0x01			@ bit masks
1029	vmov.i8	q9,  #0x02
1030	vmov.i8	q10, #0x04
1031	vmov.i8	q11, #0x08
1032	vmov.i8	q12, #0x10
1033	vmov.i8	q13, #0x20
1034	vldmia	r6, {q14}		@ .LM0
1035
1036#ifdef __ARMEL__
1037	vrev32.8	q7,  q7
1038	vrev32.8	q15, q15
1039#endif
1040	sub	r5,r5,#1
1041	vstmia	r12!, {q7}		@ save round 0 key
1042	b	.Lkey_loop
1043
1044.align	4
1045.Lkey_loop:
1046	vtbl.8	d14,{q15},d28
1047	vtbl.8	d15,{q15},d29
1048	vmov.i8	q6,  #0x40
1049	vmov.i8	q15, #0x80
1050
1051	vtst.8	q0, q7, q8
1052	vtst.8	q1, q7, q9
1053	vtst.8	q2, q7, q10
1054	vtst.8	q3, q7, q11
1055	vtst.8	q4, q7, q12
1056	vtst.8	q5, q7, q13
1057	vtst.8	q6, q7, q6
1058	vtst.8	q7, q7, q15
1059	vld1.8	{q15}, [r4]!		@ load next round key
1060	vmvn	q0, q0		@ "pnot"
1061	vmvn	q1, q1
1062	vmvn	q5, q5
1063	vmvn	q6, q6
1064#ifdef __ARMEL__
1065	vrev32.8	q15, q15
1066#endif
1067	subs	r5,r5,#1
1068	vstmia	r12!,{q0,q1,q2,q3,q4,q5,q6,q7}		@ write bit-sliced round key
1069	bne	.Lkey_loop
1070
1071	vmov.i8	q7,#0x63			@ compose .L63
1072	@ don't save last round key
1073	bx	lr
1074.size	_bsaes_key_convert,.-_bsaes_key_convert
1075.globl	bsaes_cbc_encrypt
1076.hidden	bsaes_cbc_encrypt
1077.type	bsaes_cbc_encrypt,%function
1078.align	5
1079bsaes_cbc_encrypt:
1080	@ In OpenSSL, this function had a fallback to aes_nohw_cbc_encrypt for
1081	@ short inputs. We patch this out, using bsaes for all input sizes.
1082
1083	@ it is up to the caller to make sure we are called with enc == 0
1084
1085	mov	ip, sp
1086	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}
1087	VFP_ABI_PUSH
1088	ldr	r8, [ip]			@ IV is 1st arg on the stack
1089	mov	r2, r2, lsr#4		@ len in 16 byte blocks
1090	sub	sp, #0x10			@ scratch space to carry over the IV
1091	mov	r9, sp				@ save sp
1092
1093	ldr	r10, [r3, #240]		@ get # of rounds
1094#ifndef	BSAES_ASM_EXTENDED_KEY
1095	@ allocate the key schedule on the stack
1096	sub	r12, sp, r10, lsl#7		@ 128 bytes per inner round key
1097	add	r12, #96			@ sifze of bit-slices key schedule
1098
1099	@ populate the key schedule
1100	mov	r4, r3			@ pass key
1101	mov	r5, r10			@ pass # of rounds
1102	mov	sp, r12				@ sp is sp
1103	bl	_bsaes_key_convert
1104	vldmia	sp, {q6}
1105	vstmia	r12,  {q15}		@ save last round key
1106	veor	q7, q7, q6	@ fix up round 0 key
1107	vstmia	sp, {q7}
1108#else
1109	ldr	r12, [r3, #244]
1110	eors	r12, #1
1111	beq	0f
1112
1113	@ populate the key schedule
1114	str	r12, [r3, #244]
1115	mov	r4, r3			@ pass key
1116	mov	r5, r10			@ pass # of rounds
1117	add	r12, r3, #248			@ pass key schedule
1118	bl	_bsaes_key_convert
1119	add	r4, r3, #248
1120	vldmia	r4, {q6}
1121	vstmia	r12, {q15}			@ save last round key
1122	veor	q7, q7, q6	@ fix up round 0 key
1123	vstmia	r4, {q7}
1124
1125.align	2
1126
1127#endif
1128
1129	vld1.8	{q15}, [r8]		@ load IV
1130	b	.Lcbc_dec_loop
1131
1132.align	4
1133.Lcbc_dec_loop:
1134	subs	r2, r2, #0x8
1135	bmi	.Lcbc_dec_loop_finish
1136
1137	vld1.8	{q0,q1}, [r0]!	@ load input
1138	vld1.8	{q2,q3}, [r0]!
1139#ifndef	BSAES_ASM_EXTENDED_KEY
1140	mov	r4, sp			@ pass the key
1141#else
1142	add	r4, r3, #248
1143#endif
1144	vld1.8	{q4,q5}, [r0]!
1145	mov	r5, r10
1146	vld1.8	{q6,q7}, [r0]
1147	sub	r0, r0, #0x60
1148	vstmia	r9, {q15}			@ put aside IV
1149
1150	bl	_bsaes_decrypt8
1151
1152	vldmia	r9, {q14}			@ reload IV
1153	vld1.8	{q8,q9}, [r0]!	@ reload input
1154	veor	q0, q0, q14	@ ^= IV
1155	vld1.8	{q10,q11}, [r0]!
1156	veor	q1, q1, q8
1157	veor	q6, q6, q9
1158	vld1.8	{q12,q13}, [r0]!
1159	veor	q4, q4, q10
1160	veor	q2, q2, q11
1161	vld1.8	{q14,q15}, [r0]!
1162	veor	q7, q7, q12
1163	vst1.8	{q0,q1}, [r1]!	@ write output
1164	veor	q3, q3, q13
1165	vst1.8	{q6}, [r1]!
1166	veor	q5, q5, q14
1167	vst1.8	{q4}, [r1]!
1168	vst1.8	{q2}, [r1]!
1169	vst1.8	{q7}, [r1]!
1170	vst1.8	{q3}, [r1]!
1171	vst1.8	{q5}, [r1]!
1172
1173	b	.Lcbc_dec_loop
1174
1175.Lcbc_dec_loop_finish:
1176	adds	r2, r2, #8
1177	beq	.Lcbc_dec_done
1178
1179	@ Set up most parameters for the _bsaes_decrypt8 call.
1180#ifndef	BSAES_ASM_EXTENDED_KEY
1181	mov	r4, sp			@ pass the key
1182#else
1183	add	r4, r3, #248
1184#endif
1185	mov	r5, r10
1186	vstmia	r9, {q15}			@ put aside IV
1187
1188	vld1.8	{q0}, [r0]!		@ load input
1189	cmp	r2, #2
1190	blo	.Lcbc_dec_one
1191	vld1.8	{q1}, [r0]!
1192	beq	.Lcbc_dec_two
1193	vld1.8	{q2}, [r0]!
1194	cmp	r2, #4
1195	blo	.Lcbc_dec_three
1196	vld1.8	{q3}, [r0]!
1197	beq	.Lcbc_dec_four
1198	vld1.8	{q4}, [r0]!
1199	cmp	r2, #6
1200	blo	.Lcbc_dec_five
1201	vld1.8	{q5}, [r0]!
1202	beq	.Lcbc_dec_six
1203	vld1.8	{q6}, [r0]!
1204	sub	r0, r0, #0x70
1205
1206	bl	_bsaes_decrypt8
1207
1208	vldmia	r9, {q14}			@ reload IV
1209	vld1.8	{q8,q9}, [r0]!	@ reload input
1210	veor	q0, q0, q14	@ ^= IV
1211	vld1.8	{q10,q11}, [r0]!
1212	veor	q1, q1, q8
1213	veor	q6, q6, q9
1214	vld1.8	{q12,q13}, [r0]!
1215	veor	q4, q4, q10
1216	veor	q2, q2, q11
1217	vld1.8	{q15}, [r0]!
1218	veor	q7, q7, q12
1219	vst1.8	{q0,q1}, [r1]!	@ write output
1220	veor	q3, q3, q13
1221	vst1.8	{q6}, [r1]!
1222	vst1.8	{q4}, [r1]!
1223	vst1.8	{q2}, [r1]!
1224	vst1.8	{q7}, [r1]!
1225	vst1.8	{q3}, [r1]!
1226	b	.Lcbc_dec_done
1227.align	4
1228.Lcbc_dec_six:
1229	sub	r0, r0, #0x60
1230	bl	_bsaes_decrypt8
1231	vldmia	r9,{q14}			@ reload IV
1232	vld1.8	{q8,q9}, [r0]!	@ reload input
1233	veor	q0, q0, q14	@ ^= IV
1234	vld1.8	{q10,q11}, [r0]!
1235	veor	q1, q1, q8
1236	veor	q6, q6, q9
1237	vld1.8	{q12}, [r0]!
1238	veor	q4, q4, q10
1239	veor	q2, q2, q11
1240	vld1.8	{q15}, [r0]!
1241	veor	q7, q7, q12
1242	vst1.8	{q0,q1}, [r1]!	@ write output
1243	vst1.8	{q6}, [r1]!
1244	vst1.8	{q4}, [r1]!
1245	vst1.8	{q2}, [r1]!
1246	vst1.8	{q7}, [r1]!
1247	b	.Lcbc_dec_done
1248.align	4
1249.Lcbc_dec_five:
1250	sub	r0, r0, #0x50
1251	bl	_bsaes_decrypt8
1252	vldmia	r9, {q14}			@ reload IV
1253	vld1.8	{q8,q9}, [r0]!	@ reload input
1254	veor	q0, q0, q14	@ ^= IV
1255	vld1.8	{q10,q11}, [r0]!
1256	veor	q1, q1, q8
1257	veor	q6, q6, q9
1258	vld1.8	{q15}, [r0]!
1259	veor	q4, q4, q10
1260	vst1.8	{q0,q1}, [r1]!	@ write output
1261	veor	q2, q2, q11
1262	vst1.8	{q6}, [r1]!
1263	vst1.8	{q4}, [r1]!
1264	vst1.8	{q2}, [r1]!
1265	b	.Lcbc_dec_done
1266.align	4
1267.Lcbc_dec_four:
1268	sub	r0, r0, #0x40
1269	bl	_bsaes_decrypt8
1270	vldmia	r9, {q14}			@ reload IV
1271	vld1.8	{q8,q9}, [r0]!	@ reload input
1272	veor	q0, q0, q14	@ ^= IV
1273	vld1.8	{q10}, [r0]!
1274	veor	q1, q1, q8
1275	veor	q6, q6, q9
1276	vld1.8	{q15}, [r0]!
1277	veor	q4, q4, q10
1278	vst1.8	{q0,q1}, [r1]!	@ write output
1279	vst1.8	{q6}, [r1]!
1280	vst1.8	{q4}, [r1]!
1281	b	.Lcbc_dec_done
1282.align	4
1283.Lcbc_dec_three:
1284	sub	r0, r0, #0x30
1285	bl	_bsaes_decrypt8
1286	vldmia	r9, {q14}			@ reload IV
1287	vld1.8	{q8,q9}, [r0]!	@ reload input
1288	veor	q0, q0, q14	@ ^= IV
1289	vld1.8	{q15}, [r0]!
1290	veor	q1, q1, q8
1291	veor	q6, q6, q9
1292	vst1.8	{q0,q1}, [r1]!	@ write output
1293	vst1.8	{q6}, [r1]!
1294	b	.Lcbc_dec_done
1295.align	4
1296.Lcbc_dec_two:
1297	sub	r0, r0, #0x20
1298	bl	_bsaes_decrypt8
1299	vldmia	r9, {q14}			@ reload IV
1300	vld1.8	{q8}, [r0]!		@ reload input
1301	veor	q0, q0, q14	@ ^= IV
1302	vld1.8	{q15}, [r0]!		@ reload input
1303	veor	q1, q1, q8
1304	vst1.8	{q0,q1}, [r1]!	@ write output
1305	b	.Lcbc_dec_done
1306.align	4
1307.Lcbc_dec_one:
1308	sub	r0, r0, #0x10
1309	bl	_bsaes_decrypt8
1310	vldmia	r9, {q14}			@ reload IV
1311	vld1.8	{q15}, [r0]!		@ reload input
1312	veor	q0, q0, q14	@ ^= IV
1313	vst1.8	{q0}, [r1]!		@ write output
1314
1315.Lcbc_dec_done:
1316#ifndef	BSAES_ASM_EXTENDED_KEY
1317	vmov.i32	q0, #0
1318	vmov.i32	q1, #0
1319.Lcbc_dec_bzero:@ wipe key schedule [if any]
1320	vstmia	sp!, {q0,q1}
1321	cmp	sp, r9
1322	bne	.Lcbc_dec_bzero
1323#endif
1324
1325	mov	sp, r9
1326	add	sp, #0x10			@ add sp,r9,#0x10 is no good for thumb
1327	vst1.8	{q15}, [r8]		@ return IV
1328	VFP_ABI_POP
1329	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}
1330.size	bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
1331.globl	bsaes_ctr32_encrypt_blocks
1332.hidden	bsaes_ctr32_encrypt_blocks
1333.type	bsaes_ctr32_encrypt_blocks,%function
1334.align	5
1335bsaes_ctr32_encrypt_blocks:
1336	@ In OpenSSL, short inputs fall back to aes_nohw_* here. We patch this
1337	@ out to retain a constant-time implementation.
1338	mov	ip, sp
1339	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}
1340	VFP_ABI_PUSH
1341	ldr	r8, [ip]			@ ctr is 1st arg on the stack
1342	sub	sp, sp, #0x10			@ scratch space to carry over the ctr
1343	mov	r9, sp				@ save sp
1344
1345	ldr	r10, [r3, #240]		@ get # of rounds
1346#ifndef	BSAES_ASM_EXTENDED_KEY
1347	@ allocate the key schedule on the stack
1348	sub	r12, sp, r10, lsl#7		@ 128 bytes per inner round key
1349	add	r12, #96			@ size of bit-sliced key schedule
1350
1351	@ populate the key schedule
1352	mov	r4, r3			@ pass key
1353	mov	r5, r10			@ pass # of rounds
1354	mov	sp, r12				@ sp is sp
1355	bl	_bsaes_key_convert
1356	veor	q7,q7,q15	@ fix up last round key
1357	vstmia	r12, {q7}			@ save last round key
1358
1359	vld1.8	{q0}, [r8]		@ load counter
1360#ifdef	__APPLE__
1361	mov	r8, #:lower16:(.LREVM0SR-.LM0)
1362	add	r8, r6, r8
1363#else
1364	add	r8, r6, #.LREVM0SR-.LM0	@ borrow r8
1365#endif
1366	vldmia	sp, {q4}		@ load round0 key
1367#else
1368	ldr	r12, [r3, #244]
1369	eors	r12, #1
1370	beq	0f
1371
1372	@ populate the key schedule
1373	str	r12, [r3, #244]
1374	mov	r4, r3			@ pass key
1375	mov	r5, r10			@ pass # of rounds
1376	add	r12, r3, #248			@ pass key schedule
1377	bl	_bsaes_key_convert
1378	veor	q7,q7,q15	@ fix up last round key
1379	vstmia	r12, {q7}			@ save last round key
1380
1381.align	2
1382	add	r12, r3, #248
1383	vld1.8	{q0}, [r8]		@ load counter
1384	adrl	r8, .LREVM0SR			@ borrow r8
1385	vldmia	r12, {q4}			@ load round0 key
1386	sub	sp, #0x10			@ place for adjusted round0 key
1387#endif
1388
1389	vmov.i32	q8,#1		@ compose 1<<96
1390	veor	q9,q9,q9
1391	vrev32.8	q0,q0
1392	vext.8	q8,q9,q8,#4
1393	vrev32.8	q4,q4
1394	vadd.u32	q9,q8,q8	@ compose 2<<96
1395	vstmia	sp, {q4}		@ save adjusted round0 key
1396	b	.Lctr_enc_loop
1397
1398.align	4
1399.Lctr_enc_loop:
1400	vadd.u32	q10, q8, q9	@ compose 3<<96
1401	vadd.u32	q1, q0, q8	@ +1
1402	vadd.u32	q2, q0, q9	@ +2
1403	vadd.u32	q3, q0, q10	@ +3
1404	vadd.u32	q4, q1, q10
1405	vadd.u32	q5, q2, q10
1406	vadd.u32	q6, q3, q10
1407	vadd.u32	q7, q4, q10
1408	vadd.u32	q10, q5, q10	@ next counter
1409
1410	@ Borrow prologue from _bsaes_encrypt8 to use the opportunity
1411	@ to flip byte order in 32-bit counter
1412
1413	vldmia	sp, {q9}		@ load round0 key
1414#ifndef	BSAES_ASM_EXTENDED_KEY
1415	add	r4, sp, #0x10		@ pass next round key
1416#else
1417	add	r4, r3, #264
1418#endif
1419	vldmia	r8, {q8}			@ .LREVM0SR
1420	mov	r5, r10			@ pass rounds
1421	vstmia	r9, {q10}			@ save next counter
1422#ifdef	__APPLE__
1423	mov	r6, #:lower16:(.LREVM0SR-.LSR)
1424	sub	r6, r8, r6
1425#else
1426	sub	r6, r8, #.LREVM0SR-.LSR	@ pass constants
1427#endif
1428
1429	bl	_bsaes_encrypt8_alt
1430
1431	subs	r2, r2, #8
1432	blo	.Lctr_enc_loop_done
1433
1434	vld1.8	{q8,q9}, [r0]!	@ load input
1435	vld1.8	{q10,q11}, [r0]!
1436	veor	q0, q8
1437	veor	q1, q9
1438	vld1.8	{q12,q13}, [r0]!
1439	veor	q4, q10
1440	veor	q6, q11
1441	vld1.8	{q14,q15}, [r0]!
1442	veor	q3, q12
1443	vst1.8	{q0,q1}, [r1]!	@ write output
1444	veor	q7, q13
1445	veor	q2, q14
1446	vst1.8	{q4}, [r1]!
1447	veor	q5, q15
1448	vst1.8	{q6}, [r1]!
1449	vmov.i32	q8, #1			@ compose 1<<96
1450	vst1.8	{q3}, [r1]!
1451	veor	q9, q9, q9
1452	vst1.8	{q7}, [r1]!
1453	vext.8	q8, q9, q8, #4
1454	vst1.8	{q2}, [r1]!
1455	vadd.u32	q9,q8,q8		@ compose 2<<96
1456	vst1.8	{q5}, [r1]!
1457	vldmia	r9, {q0}			@ load counter
1458
1459	bne	.Lctr_enc_loop
1460	b	.Lctr_enc_done
1461
1462.align	4
1463.Lctr_enc_loop_done:
1464	add	r2, r2, #8
1465	vld1.8	{q8}, [r0]!	@ load input
1466	veor	q0, q8
1467	vst1.8	{q0}, [r1]!	@ write output
1468	cmp	r2, #2
1469	blo	.Lctr_enc_done
1470	vld1.8	{q9}, [r0]!
1471	veor	q1, q9
1472	vst1.8	{q1}, [r1]!
1473	beq	.Lctr_enc_done
1474	vld1.8	{q10}, [r0]!
1475	veor	q4, q10
1476	vst1.8	{q4}, [r1]!
1477	cmp	r2, #4
1478	blo	.Lctr_enc_done
1479	vld1.8	{q11}, [r0]!
1480	veor	q6, q11
1481	vst1.8	{q6}, [r1]!
1482	beq	.Lctr_enc_done
1483	vld1.8	{q12}, [r0]!
1484	veor	q3, q12
1485	vst1.8	{q3}, [r1]!
1486	cmp	r2, #6
1487	blo	.Lctr_enc_done
1488	vld1.8	{q13}, [r0]!
1489	veor	q7, q13
1490	vst1.8	{q7}, [r1]!
1491	beq	.Lctr_enc_done
1492	vld1.8	{q14}, [r0]
1493	veor	q2, q14
1494	vst1.8	{q2}, [r1]!
1495
1496.Lctr_enc_done:
1497	vmov.i32	q0, #0
1498	vmov.i32	q1, #0
1499#ifndef	BSAES_ASM_EXTENDED_KEY
1500.Lctr_enc_bzero:@ wipe key schedule [if any]
1501	vstmia	sp!, {q0,q1}
1502	cmp	sp, r9
1503	bne	.Lctr_enc_bzero
1504#else
1505	vstmia	sp, {q0,q1}
1506#endif
1507
1508	mov	sp, r9
1509	add	sp, #0x10		@ add sp,r9,#0x10 is no good for thumb
1510	VFP_ABI_POP
1511	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}	@ return
1512
1513	@ OpenSSL contains aes_nohw_* fallback code here. We patch this
1514	@ out to retain a constant-time implementation.
1515.size	bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
1516#endif
1517#endif  // !OPENSSL_NO_ASM && defined(OPENSSL_ARM) && defined(__ELF__)
1518