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