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@ Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
13@
14@ Licensed under the OpenSSL license (the "License").  You may not use
15@ this file except in compliance with the License.  You can obtain a copy
16@ in the file LICENSE in the source distribution or at
17@ https://www.openssl.org/source/license.html
18
19
20@ ====================================================================
21@ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
22@ project. The module is, however, dual licensed under OpenSSL and
23@ CRYPTOGAMS licenses depending on where you obtain it. For further
24@ details see http://www.openssl.org/~appro/cryptogams/.
25@
26@ Specific modes and adaptation for Linux kernel by Ard Biesheuvel
27@ of Linaro. Permission to use under GPL terms is granted.
28@ ====================================================================
29
30@ Bit-sliced AES for ARM NEON
31@
32@ February 2012.
33@
34@ This implementation is direct adaptation of bsaes-x86_64 module for
35@ ARM NEON. Except that this module is endian-neutral [in sense that
36@ it can be compiled for either endianness] by courtesy of vld1.8's
37@ neutrality. Initial version doesn't implement interface to OpenSSL,
38@ only low-level primitives and unsupported entry points, just enough
39@ to collect performance results, which for Cortex-A8 core are:
40@
41@ encrypt	19.5 cycles per byte processed with 128-bit key
42@ decrypt	22.1 cycles per byte processed with 128-bit key
43@ key conv.	440  cycles per 128-bit key/0.18 of 8x block
44@
45@ Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7,
46@ which is [much] worse than anticipated (for further details see
47@ http://www.openssl.org/~appro/Snapdragon-S4.html).
48@
49@ Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code
50@ manages in 20.0 cycles].
51@
52@ When comparing to x86_64 results keep in mind that NEON unit is
53@ [mostly] single-issue and thus can't [fully] benefit from
54@ instruction-level parallelism. And when comparing to aes-armv4
55@ results keep in mind key schedule conversion overhead (see
56@ bsaes-x86_64.pl for further details)...
57@
58@						<appro@openssl.org>
59
60@ April-August 2013
61@ Add CBC, CTR and XTS subroutines and adapt for kernel use; courtesy of Ard.
62
63#ifndef __KERNEL__
64# include <GFp/arm_arch.h>
65
66# define VFP_ABI_PUSH	vstmdb	sp!,{d8-d15}
67# define VFP_ABI_POP	vldmia	sp!,{d8-d15}
68# define VFP_ABI_FRAME	0x40
69#else
70# define VFP_ABI_PUSH
71# define VFP_ABI_POP
72# define VFP_ABI_FRAME	0
73# define BSAES_ASM_EXTENDED_KEY
74# define __ARM_ARCH__ __LINUX_ARM_ARCH__
75# define __ARM_MAX_ARCH__ 7
76#endif
77
78#ifdef __thumb__
79# define adrl adr
80#endif
81
82#if __ARM_MAX_ARCH__>=7
83
84
85
86.text
87.syntax	unified 	@ ARMv7-capable assembler is expected to handle this
88#if defined(__thumb2__) && !defined(__APPLE__)
89.thumb
90#else
91.code	32
92# undef __thumb2__
93#endif
94
95
96.align	6
97_bsaes_const:
98LM0ISR:@ InvShiftRows constants
99.quad	0x0a0e0206070b0f03, 0x0004080c0d010509
100LISR:
101.quad	0x0504070602010003, 0x0f0e0d0c080b0a09
102LISRM0:
103.quad	0x01040b0e0205080f, 0x0306090c00070a0d
104LM0SR:@ ShiftRows constants
105.quad	0x0a0e02060f03070b, 0x0004080c05090d01
106LSR:
107.quad	0x0504070600030201, 0x0f0e0d0c0a09080b
108LSRM0:
109.quad	0x0304090e00050a0f, 0x01060b0c0207080d
110LM0:
111.quad	0x02060a0e03070b0f, 0x0004080c0105090d
112LREVM0SR:
113.quad	0x090d01050c000408, 0x03070b0f060a0e02
114.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
115.align	2
116.align	6
117
118
119#ifdef __thumb2__
120.thumb_func	_bsaes_encrypt8
121#endif
122.align	4
123_bsaes_encrypt8:
124	adr	r6,.
125	vldmia	r4!, {q9}		@ round 0 key
126#if defined(__thumb2__) || defined(__APPLE__)
127	adr	r6,LM0SR
128#else
129	sub	r6,r6,#_bsaes_encrypt8-LM0SR
130#endif
131
132	vldmia	r6!, {q8}		@ LM0SR
133_bsaes_encrypt8_alt:
134	veor	q10, q0, q9	@ xor with round0 key
135	veor	q11, q1, q9
136	vtbl.8	d0, {q10}, d16
137	vtbl.8	d1, {q10}, d17
138	veor	q12, q2, q9
139	vtbl.8	d2, {q11}, d16
140	vtbl.8	d3, {q11}, d17
141	veor	q13, q3, q9
142	vtbl.8	d4, {q12}, d16
143	vtbl.8	d5, {q12}, d17
144	veor	q14, q4, q9
145	vtbl.8	d6, {q13}, d16
146	vtbl.8	d7, {q13}, d17
147	veor	q15, q5, q9
148	vtbl.8	d8, {q14}, d16
149	vtbl.8	d9, {q14}, d17
150	veor	q10, q6, q9
151	vtbl.8	d10, {q15}, d16
152	vtbl.8	d11, {q15}, d17
153	veor	q11, q7, q9
154	vtbl.8	d12, {q10}, d16
155	vtbl.8	d13, {q10}, d17
156	vtbl.8	d14, {q11}, d16
157	vtbl.8	d15, {q11}, d17
158_bsaes_encrypt8_bitslice:
159	vmov.i8	q8,#0x55			@ compose LBS0
160	vmov.i8	q9,#0x33			@ compose LBS1
161	vshr.u64	q10, q6, #1
162	vshr.u64	q11, q4, #1
163	veor	q10, q10, q7
164	veor	q11, q11, q5
165	vand	q10, q10, q8
166	vand	q11, q11, q8
167	veor	q7, q7, q10
168	vshl.u64	q10, q10, #1
169	veor	q5, q5, q11
170	vshl.u64	q11, q11, #1
171	veor	q6, q6, q10
172	veor	q4, q4, q11
173	vshr.u64	q10, q2, #1
174	vshr.u64	q11, q0, #1
175	veor	q10, q10, q3
176	veor	q11, q11, q1
177	vand	q10, q10, q8
178	vand	q11, q11, q8
179	veor	q3, q3, q10
180	vshl.u64	q10, q10, #1
181	veor	q1, q1, q11
182	vshl.u64	q11, q11, #1
183	veor	q2, q2, q10
184	veor	q0, q0, q11
185	vmov.i8	q8,#0x0f			@ compose LBS2
186	vshr.u64	q10, q5, #2
187	vshr.u64	q11, q4, #2
188	veor	q10, q10, q7
189	veor	q11, q11, q6
190	vand	q10, q10, q9
191	vand	q11, q11, q9
192	veor	q7, q7, q10
193	vshl.u64	q10, q10, #2
194	veor	q6, q6, q11
195	vshl.u64	q11, q11, #2
196	veor	q5, q5, q10
197	veor	q4, q4, q11
198	vshr.u64	q10, q1, #2
199	vshr.u64	q11, q0, #2
200	veor	q10, q10, q3
201	veor	q11, q11, q2
202	vand	q10, q10, q9
203	vand	q11, q11, q9
204	veor	q3, q3, q10
205	vshl.u64	q10, q10, #2
206	veor	q2, q2, q11
207	vshl.u64	q11, q11, #2
208	veor	q1, q1, q10
209	veor	q0, q0, q11
210	vshr.u64	q10, q3, #4
211	vshr.u64	q11, q2, #4
212	veor	q10, q10, q7
213	veor	q11, q11, q6
214	vand	q10, q10, q8
215	vand	q11, q11, q8
216	veor	q7, q7, q10
217	vshl.u64	q10, q10, #4
218	veor	q6, q6, q11
219	vshl.u64	q11, q11, #4
220	veor	q3, q3, q10
221	veor	q2, q2, q11
222	vshr.u64	q10, q1, #4
223	vshr.u64	q11, q0, #4
224	veor	q10, q10, q5
225	veor	q11, q11, q4
226	vand	q10, q10, q8
227	vand	q11, q11, q8
228	veor	q5, q5, q10
229	vshl.u64	q10, q10, #4
230	veor	q4, q4, q11
231	vshl.u64	q11, q11, #4
232	veor	q1, q1, q10
233	veor	q0, q0, q11
234	sub	r5,r5,#1
235	b	Lenc_sbox
236.align	4
237Lenc_loop:
238	vldmia	r4!, {q8,q9,q10,q11}
239	veor	q8, q8, q0
240	veor	q9, q9, q1
241	vtbl.8	d0, {q8}, d24
242	vtbl.8	d1, {q8}, d25
243	vldmia	r4!, {q8}
244	veor	q10, q10, q2
245	vtbl.8	d2, {q9}, d24
246	vtbl.8	d3, {q9}, d25
247	vldmia	r4!, {q9}
248	veor	q11, q11, q3
249	vtbl.8	d4, {q10}, d24
250	vtbl.8	d5, {q10}, d25
251	vldmia	r4!, {q10}
252	vtbl.8	d6, {q11}, d24
253	vtbl.8	d7, {q11}, d25
254	vldmia	r4!, {q11}
255	veor	q8, q8, q4
256	veor	q9, q9, q5
257	vtbl.8	d8, {q8}, d24
258	vtbl.8	d9, {q8}, d25
259	veor	q10, q10, q6
260	vtbl.8	d10, {q9}, d24
261	vtbl.8	d11, {q9}, d25
262	veor	q11, q11, q7
263	vtbl.8	d12, {q10}, d24
264	vtbl.8	d13, {q10}, d25
265	vtbl.8	d14, {q11}, d24
266	vtbl.8	d15, {q11}, d25
267Lenc_sbox:
268	veor	q2, q2, q1
269	veor	q5, q5, q6
270	veor	q3, q3, q0
271	veor	q6, q6, q2
272	veor	q5, q5, q0
273
274	veor	q6, q6, q3
275	veor	q3, q3, q7
276	veor	q7, q7, q5
277	veor	q3, q3, q4
278	veor	q4, q4, q5
279
280	veor	q2, q2, q7
281	veor	q3, q3, q1
282	veor	q1, q1, q5
283	veor	q11, q7, q4
284	veor	q10, q1, q2
285	veor	q9, q5, q3
286	veor	q13, q2, q4
287	vmov	q8, q10
288	veor	q12, q6, q0
289
290	vorr	q10, q10, q9
291	veor	q15, q11, q8
292	vand	q14, q11, q12
293	vorr	q11, q11, q12
294	veor	q12, q12, q9
295	vand	q8, q8, q9
296	veor	q9, q3, q0
297	vand	q15, q15, q12
298	vand	q13, q13, q9
299	veor	q9, q7, q1
300	veor	q12, q5, q6
301	veor	q11, q11, q13
302	veor	q10, q10, q13
303	vand	q13, q9, q12
304	vorr	q9, q9, q12
305	veor	q11, q11, q15
306	veor	q8, q8, q13
307	veor	q10, q10, q14
308	veor	q9, q9, q15
309	veor	q8, q8, q14
310	vand	q12, q2, q3
311	veor	q9, q9, q14
312	vand	q13, q4, q0
313	vand	q14, q1, q5
314	vorr	q15, q7, q6
315	veor	q11, q11, q12
316	veor	q9, q9, q14
317	veor	q8, q8, q15
318	veor	q10, q10, q13
319
320	@ Inv_GF16 	0, 	1, 	2, 	3, s0, s1, s2, s3
321
322	@ new smaller inversion
323
324	vand	q14, q11, q9
325	vmov	q12, q8
326
327	veor	q13, q10, q14
328	veor	q15, q8, q14
329	veor	q14, q8, q14	@ q14=q15
330
331	vbsl	q13, q9, q8
332	vbsl	q15, q11, q10
333	veor	q11, q11, q10
334
335	vbsl	q12, q13, q14
336	vbsl	q8, q14, q13
337
338	vand	q14, q12, q15
339	veor	q9, q9, q8
340
341	veor	q14, q14, q11
342	veor	q12, q6, q0
343	veor	q8, q5, q3
344	veor	q10, q15, q14
345	vand	q10, q10, q6
346	veor	q6, q6, q5
347	vand	q11, q5, q15
348	vand	q6, q6, q14
349	veor	q5, q11, q10
350	veor	q6, q6, q11
351	veor	q15, q15, q13
352	veor	q14, q14, q9
353	veor	q11, q15, q14
354	veor	q10, q13, q9
355	vand	q11, q11, q12
356	vand	q10, q10, q0
357	veor	q12, q12, q8
358	veor	q0, q0, q3
359	vand	q8, q8, q15
360	vand	q3, q3, q13
361	vand	q12, q12, q14
362	vand	q0, q0, q9
363	veor	q8, q8, q12
364	veor	q0, q0, q3
365	veor	q12, q12, q11
366	veor	q3, q3, q10
367	veor	q6, q6, q12
368	veor	q0, q0, q12
369	veor	q5, q5, q8
370	veor	q3, q3, q8
371
372	veor	q12, q7, q4
373	veor	q8, q1, q2
374	veor	q11, q15, q14
375	veor	q10, q13, q9
376	vand	q11, q11, q12
377	vand	q10, q10, q4
378	veor	q12, q12, q8
379	veor	q4, q4, q2
380	vand	q8, q8, q15
381	vand	q2, q2, q13
382	vand	q12, q12, q14
383	vand	q4, q4, q9
384	veor	q8, q8, q12
385	veor	q4, q4, q2
386	veor	q12, q12, q11
387	veor	q2, q2, q10
388	veor	q15, q15, q13
389	veor	q14, q14, q9
390	veor	q10, q15, q14
391	vand	q10, q10, q7
392	veor	q7, q7, q1
393	vand	q11, q1, q15
394	vand	q7, q7, q14
395	veor	q1, q11, q10
396	veor	q7, q7, q11
397	veor	q7, q7, q12
398	veor	q4, q4, q12
399	veor	q1, q1, q8
400	veor	q2, q2, q8
401	veor	q7, q7, q0
402	veor	q1, q1, q6
403	veor	q6, q6, q0
404	veor	q4, q4, q7
405	veor	q0, q0, q1
406
407	veor	q1, q1, q5
408	veor	q5, q5, q2
409	veor	q2, q2, q3
410	veor	q3, q3, q5
411	veor	q4, q4, q5
412
413	veor	q6, q6, q3
414	subs	r5,r5,#1
415	bcc	Lenc_done
416	vext.8	q8, q0, q0, #12	@ x0 <<< 32
417	vext.8	q9, q1, q1, #12
418	veor	q0, q0, q8		@ x0 ^ (x0 <<< 32)
419	vext.8	q10, q4, q4, #12
420	veor	q1, q1, q9
421	vext.8	q11, q6, q6, #12
422	veor	q4, q4, q10
423	vext.8	q12, q3, q3, #12
424	veor	q6, q6, q11
425	vext.8	q13, q7, q7, #12
426	veor	q3, q3, q12
427	vext.8	q14, q2, q2, #12
428	veor	q7, q7, q13
429	vext.8	q15, q5, q5, #12
430	veor	q2, q2, q14
431
432	veor	q9, q9, q0
433	veor	q5, q5, q15
434	vext.8	q0, q0, q0, #8		@ (x0 ^ (x0 <<< 32)) <<< 64)
435	veor	q10, q10, q1
436	veor	q8, q8, q5
437	veor	q9, q9, q5
438	vext.8	q1, q1, q1, #8
439	veor	q13, q13, q3
440	veor	q0, q0, q8
441	veor	q14, q14, q7
442	veor	q1, q1, q9
443	vext.8	q8, q3, q3, #8
444	veor	q12, q12, q6
445	vext.8	q9, q7, q7, #8
446	veor	q15, q15, q2
447	vext.8	q3, q6, q6, #8
448	veor	q11, q11, q4
449	vext.8	q7, q5, q5, #8
450	veor	q12, q12, q5
451	vext.8	q6, q2, q2, #8
452	veor	q11, q11, q5
453	vext.8	q2, q4, q4, #8
454	veor	q5, q9, q13
455	veor	q4, q8, q12
456	veor	q3, q3, q11
457	veor	q7, q7, q15
458	veor	q6, q6, q14
459	 @ vmov	q4, q8
460	veor	q2, q2, q10
461	 @ vmov	q5, q9
462	vldmia	r6, {q12}		@ LSR
463	ite	eq				@ Thumb2 thing, samity check in ARM
464	addeq	r6,r6,#0x10
465	bne	Lenc_loop
466	vldmia	r6, {q12}		@ LSRM0
467	b	Lenc_loop
468.align	4
469Lenc_done:
470	vmov.i8	q8,#0x55			@ compose LBS0
471	vmov.i8	q9,#0x33			@ compose LBS1
472	vshr.u64	q10, q2, #1
473	vshr.u64	q11, q3, #1
474	veor	q10, q10, q5
475	veor	q11, q11, q7
476	vand	q10, q10, q8
477	vand	q11, q11, q8
478	veor	q5, q5, q10
479	vshl.u64	q10, q10, #1
480	veor	q7, q7, q11
481	vshl.u64	q11, q11, #1
482	veor	q2, q2, q10
483	veor	q3, q3, q11
484	vshr.u64	q10, q4, #1
485	vshr.u64	q11, q0, #1
486	veor	q10, q10, q6
487	veor	q11, q11, q1
488	vand	q10, q10, q8
489	vand	q11, q11, q8
490	veor	q6, q6, q10
491	vshl.u64	q10, q10, #1
492	veor	q1, q1, q11
493	vshl.u64	q11, q11, #1
494	veor	q4, q4, q10
495	veor	q0, q0, q11
496	vmov.i8	q8,#0x0f			@ compose LBS2
497	vshr.u64	q10, q7, #2
498	vshr.u64	q11, q3, #2
499	veor	q10, q10, q5
500	veor	q11, q11, q2
501	vand	q10, q10, q9
502	vand	q11, q11, q9
503	veor	q5, q5, q10
504	vshl.u64	q10, q10, #2
505	veor	q2, q2, q11
506	vshl.u64	q11, q11, #2
507	veor	q7, q7, q10
508	veor	q3, q3, q11
509	vshr.u64	q10, q1, #2
510	vshr.u64	q11, q0, #2
511	veor	q10, q10, q6
512	veor	q11, q11, q4
513	vand	q10, q10, q9
514	vand	q11, q11, q9
515	veor	q6, q6, q10
516	vshl.u64	q10, q10, #2
517	veor	q4, q4, q11
518	vshl.u64	q11, q11, #2
519	veor	q1, q1, q10
520	veor	q0, q0, q11
521	vshr.u64	q10, q6, #4
522	vshr.u64	q11, q4, #4
523	veor	q10, q10, q5
524	veor	q11, q11, q2
525	vand	q10, q10, q8
526	vand	q11, q11, q8
527	veor	q5, q5, q10
528	vshl.u64	q10, q10, #4
529	veor	q2, q2, q11
530	vshl.u64	q11, q11, #4
531	veor	q6, q6, q10
532	veor	q4, q4, q11
533	vshr.u64	q10, q1, #4
534	vshr.u64	q11, q0, #4
535	veor	q10, q10, q7
536	veor	q11, q11, q3
537	vand	q10, q10, q8
538	vand	q11, q11, q8
539	veor	q7, q7, q10
540	vshl.u64	q10, q10, #4
541	veor	q3, q3, q11
542	vshl.u64	q11, q11, #4
543	veor	q1, q1, q10
544	veor	q0, q0, q11
545	vldmia	r4, {q8}			@ last round key
546	veor	q4, q4, q8
547	veor	q6, q6, q8
548	veor	q3, q3, q8
549	veor	q7, q7, q8
550	veor	q2, q2, q8
551	veor	q5, q5, q8
552	veor	q0, q0, q8
553	veor	q1, q1, q8
554	bx	lr
555
556#ifdef __thumb2__
557.thumb_func	_bsaes_key_convert
558#endif
559.align	4
560_bsaes_key_convert:
561	adr	r6,.
562	vld1.8	{q7},  [r4]!		@ load round 0 key
563#if defined(__thumb2__) || defined(__APPLE__)
564	adr	r6,LM0
565#else
566	sub	r6,r6,#_bsaes_key_convert-LM0
567#endif
568	vld1.8	{q15}, [r4]!		@ load round 1 key
569
570	vmov.i8	q8,  #0x01			@ bit masks
571	vmov.i8	q9,  #0x02
572	vmov.i8	q10, #0x04
573	vmov.i8	q11, #0x08
574	vmov.i8	q12, #0x10
575	vmov.i8	q13, #0x20
576	vldmia	r6, {q14}		@ LM0
577
578#ifdef __ARMEL__
579	vrev32.8	q7,  q7
580	vrev32.8	q15, q15
581#endif
582	sub	r5,r5,#1
583	vstmia	r12!, {q7}		@ save round 0 key
584	b	Lkey_loop
585
586.align	4
587Lkey_loop:
588	vtbl.8	d14,{q15},d28
589	vtbl.8	d15,{q15},d29
590	vmov.i8	q6,  #0x40
591	vmov.i8	q15, #0x80
592
593	vtst.8	q0, q7, q8
594	vtst.8	q1, q7, q9
595	vtst.8	q2, q7, q10
596	vtst.8	q3, q7, q11
597	vtst.8	q4, q7, q12
598	vtst.8	q5, q7, q13
599	vtst.8	q6, q7, q6
600	vtst.8	q7, q7, q15
601	vld1.8	{q15}, [r4]!		@ load next round key
602	vmvn	q0, q0		@ "pnot"
603	vmvn	q1, q1
604	vmvn	q5, q5
605	vmvn	q6, q6
606#ifdef __ARMEL__
607	vrev32.8	q15, q15
608#endif
609	subs	r5,r5,#1
610	vstmia	r12!,{q0,q1,q2,q3,q4,q5,q6,q7}		@ write bit-sliced round key
611	bne	Lkey_loop
612
613	vmov.i8	q7,#0x63			@ compose L63
614	@ don't save last round key
615	bx	lr
616
617.globl	_GFp_bsaes_ctr32_encrypt_blocks
618.private_extern	_GFp_bsaes_ctr32_encrypt_blocks
619#ifdef __thumb2__
620.thumb_func	_GFp_bsaes_ctr32_encrypt_blocks
621#endif
622.align	5
623_GFp_bsaes_ctr32_encrypt_blocks:
624	@ In OpenSSL, short inputs fall back to aes_nohw_* here. We patch this
625	@ out to retain a constant-time implementation.
626	mov	ip, sp
627	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}
628	VFP_ABI_PUSH
629	ldr	r8, [ip]			@ ctr is 1st arg on the stack
630	sub	sp, sp, #0x10			@ scratch space to carry over the ctr
631	mov	r9, sp				@ save sp
632
633	ldr	r10, [r3, #240]		@ get # of rounds
634#ifndef	BSAES_ASM_EXTENDED_KEY
635	@ allocate the key schedule on the stack
636	sub	r12, sp, r10, lsl#7		@ 128 bytes per inner round key
637	add	r12, #96			@ size of bit-sliced key schedule
638
639	@ populate the key schedule
640	mov	r4, r3			@ pass key
641	mov	r5, r10			@ pass # of rounds
642	mov	sp, r12				@ sp is sp
643	bl	_bsaes_key_convert
644	veor	q7,q7,q15	@ fix up last round key
645	vstmia	r12, {q7}			@ save last round key
646
647	vld1.8	{q0}, [r8]		@ load counter
648#ifdef	__APPLE__
649	mov	r8, #:lower16:(LREVM0SR-LM0)
650	add	r8, r6, r8
651#else
652	add	r8, r6, #LREVM0SR-LM0	@ borrow r8
653#endif
654	vldmia	sp, {q4}		@ load round0 key
655#else
656	ldr	r12, [r3, #244]
657	eors	r12, #1
658	beq	0f
659
660	@ populate the key schedule
661	str	r12, [r3, #244]
662	mov	r4, r3			@ pass key
663	mov	r5, r10			@ pass # of rounds
664	add	r12, r3, #248			@ pass key schedule
665	bl	_bsaes_key_convert
666	veor	q7,q7,q15	@ fix up last round key
667	vstmia	r12, {q7}			@ save last round key
668
669.align	2
670	add	r12, r3, #248
671	vld1.8	{q0}, [r8]		@ load counter
672	adrl	r8, LREVM0SR			@ borrow r8
673	vldmia	r12, {q4}			@ load round0 key
674	sub	sp, #0x10			@ place for adjusted round0 key
675#endif
676
677	vmov.i32	q8,#1		@ compose 1<<96
678	veor	q9,q9,q9
679	vrev32.8	q0,q0
680	vext.8	q8,q9,q8,#4
681	vrev32.8	q4,q4
682	vadd.u32	q9,q8,q8	@ compose 2<<96
683	vstmia	sp, {q4}		@ save adjusted round0 key
684	b	Lctr_enc_loop
685
686.align	4
687Lctr_enc_loop:
688	vadd.u32	q10, q8, q9	@ compose 3<<96
689	vadd.u32	q1, q0, q8	@ +1
690	vadd.u32	q2, q0, q9	@ +2
691	vadd.u32	q3, q0, q10	@ +3
692	vadd.u32	q4, q1, q10
693	vadd.u32	q5, q2, q10
694	vadd.u32	q6, q3, q10
695	vadd.u32	q7, q4, q10
696	vadd.u32	q10, q5, q10	@ next counter
697
698	@ Borrow prologue from _bsaes_encrypt8 to use the opportunity
699	@ to flip byte order in 32-bit counter
700
701	vldmia	sp, {q9}		@ load round0 key
702#ifndef	BSAES_ASM_EXTENDED_KEY
703	add	r4, sp, #0x10		@ pass next round key
704#else
705	add	r4, r3, #264
706#endif
707	vldmia	r8, {q8}			@ LREVM0SR
708	mov	r5, r10			@ pass rounds
709	vstmia	r9, {q10}			@ save next counter
710#ifdef	__APPLE__
711	mov	r6, #:lower16:(LREVM0SR-LSR)
712	sub	r6, r8, r6
713#else
714	sub	r6, r8, #LREVM0SR-LSR	@ pass constants
715#endif
716
717	bl	_bsaes_encrypt8_alt
718
719	subs	r2, r2, #8
720	blo	Lctr_enc_loop_done
721
722	vld1.8	{q8,q9}, [r0]!	@ load input
723	vld1.8	{q10,q11}, [r0]!
724	veor	q0, q8
725	veor	q1, q9
726	vld1.8	{q12,q13}, [r0]!
727	veor	q4, q10
728	veor	q6, q11
729	vld1.8	{q14,q15}, [r0]!
730	veor	q3, q12
731	vst1.8	{q0,q1}, [r1]!	@ write output
732	veor	q7, q13
733	veor	q2, q14
734	vst1.8	{q4}, [r1]!
735	veor	q5, q15
736	vst1.8	{q6}, [r1]!
737	vmov.i32	q8, #1			@ compose 1<<96
738	vst1.8	{q3}, [r1]!
739	veor	q9, q9, q9
740	vst1.8	{q7}, [r1]!
741	vext.8	q8, q9, q8, #4
742	vst1.8	{q2}, [r1]!
743	vadd.u32	q9,q8,q8		@ compose 2<<96
744	vst1.8	{q5}, [r1]!
745	vldmia	r9, {q0}			@ load counter
746
747	bne	Lctr_enc_loop
748	b	Lctr_enc_done
749
750.align	4
751Lctr_enc_loop_done:
752	add	r2, r2, #8
753	vld1.8	{q8}, [r0]!	@ load input
754	veor	q0, q8
755	vst1.8	{q0}, [r1]!	@ write output
756	cmp	r2, #2
757	blo	Lctr_enc_done
758	vld1.8	{q9}, [r0]!
759	veor	q1, q9
760	vst1.8	{q1}, [r1]!
761	beq	Lctr_enc_done
762	vld1.8	{q10}, [r0]!
763	veor	q4, q10
764	vst1.8	{q4}, [r1]!
765	cmp	r2, #4
766	blo	Lctr_enc_done
767	vld1.8	{q11}, [r0]!
768	veor	q6, q11
769	vst1.8	{q6}, [r1]!
770	beq	Lctr_enc_done
771	vld1.8	{q12}, [r0]!
772	veor	q3, q12
773	vst1.8	{q3}, [r1]!
774	cmp	r2, #6
775	blo	Lctr_enc_done
776	vld1.8	{q13}, [r0]!
777	veor	q7, q13
778	vst1.8	{q7}, [r1]!
779	beq	Lctr_enc_done
780	vld1.8	{q14}, [r0]
781	veor	q2, q14
782	vst1.8	{q2}, [r1]!
783
784Lctr_enc_done:
785	vmov.i32	q0, #0
786	vmov.i32	q1, #0
787#ifndef	BSAES_ASM_EXTENDED_KEY
788Lctr_enc_bzero:@ wipe key schedule [if any]
789	vstmia	sp!, {q0,q1}
790	cmp	sp, r9
791	bne	Lctr_enc_bzero
792#else
793	vstmia	sp, {q0,q1}
794#endif
795
796	mov	sp, r9
797	add	sp, #0x10		@ add sp,r9,#0x10 is no good for thumb
798	VFP_ABI_POP
799	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}	@ return
800
801	@ OpenSSL contains aes_nohw_* fallback code here. We patch this
802	@ out to retain a constant-time implementation.
803
804#endif
805#endif  // !OPENSSL_NO_ASM
806