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