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