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