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