• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// This file is generated from a similarly-named Perl script in the BoringSSL
2// source tree. Do not edit by hand.
3
4#if !defined(__has_feature)
5#define __has_feature(x) 0
6#endif
7#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM)
8#define OPENSSL_NO_ASM
9#endif
10
11#if !defined(OPENSSL_NO_ASM)
12#if defined(__arm__)
13#include "ring_core_generated/prefix_symbols_asm.h"
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 <ring-core/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 __ARM_ARCH__ __LINUX_ARM_ARCH__
77# define __ARM_MAX_ARCH__ 7
78#endif
79
80#ifdef __thumb__
81# define adrl adr
82#endif
83
84#if __ARM_MAX_ARCH__>=7
85.arch	armv7-a
86.fpu	neon
87
88.text
89.syntax	unified 	@ ARMv7-capable assembler is expected to handle this
90#if defined(__thumb2__) && !defined(__APPLE__)
91.thumb
92#else
93.code	32
94# undef __thumb2__
95#endif
96
97.type	_bsaes_const,%object
98.align	6
99_bsaes_const:
100.LM0ISR:@ InvShiftRows constants
101.quad	0x0a0e0206070b0f03, 0x0004080c0d010509
102.LISR:
103.quad	0x0504070602010003, 0x0f0e0d0c080b0a09
104.LISRM0:
105.quad	0x01040b0e0205080f, 0x0306090c00070a0d
106.LM0SR:@ ShiftRows constants
107.quad	0x0a0e02060f03070b, 0x0004080c05090d01
108.LSR:
109.quad	0x0504070600030201, 0x0f0e0d0c0a09080b
110.LSRM0:
111.quad	0x0304090e00050a0f, 0x01060b0c0207080d
112.LM0:
113.quad	0x02060a0e03070b0f, 0x0004080c0105090d
114.LREVM0SR:
115.quad	0x090d01050c000408, 0x03070b0f060a0e02
116.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
117.align	2
118.align	6
119.size	_bsaes_const,.-_bsaes_const
120
121.type	_bsaes_encrypt8,%function
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
237.Lenc_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
267.Lenc_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
469.Lenc_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.size	_bsaes_encrypt8,.-_bsaes_encrypt8
556.type	_bsaes_key_convert,%function
557.align	4
558_bsaes_key_convert:
559	adr	r6,.
560	vld1.8	{q7},  [r4]!		@ load round 0 key
561#if defined(__thumb2__) || defined(__APPLE__)
562	adr	r6,.LM0
563#else
564	sub	r6,r6,#_bsaes_key_convert-.LM0
565#endif
566	vld1.8	{q15}, [r4]!		@ load round 1 key
567
568	vmov.i8	q8,  #0x01			@ bit masks
569	vmov.i8	q9,  #0x02
570	vmov.i8	q10, #0x04
571	vmov.i8	q11, #0x08
572	vmov.i8	q12, #0x10
573	vmov.i8	q13, #0x20
574	vldmia	r6, {q14}		@ .LM0
575
576#ifdef __ARMEL__
577	vrev32.8	q7,  q7
578	vrev32.8	q15, q15
579#endif
580	sub	r5,r5,#1
581	vstmia	r12!, {q7}		@ save round 0 key
582	b	.Lkey_loop
583
584.align	4
585.Lkey_loop:
586	vtbl.8	d14,{q15},d28
587	vtbl.8	d15,{q15},d29
588	vmov.i8	q6,  #0x40
589	vmov.i8	q15, #0x80
590
591	vtst.8	q0, q7, q8
592	vtst.8	q1, q7, q9
593	vtst.8	q2, q7, q10
594	vtst.8	q3, q7, q11
595	vtst.8	q4, q7, q12
596	vtst.8	q5, q7, q13
597	vtst.8	q6, q7, q6
598	vtst.8	q7, q7, q15
599	vld1.8	{q15}, [r4]!		@ load next round key
600	vmvn	q0, q0		@ "pnot"
601	vmvn	q1, q1
602	vmvn	q5, q5
603	vmvn	q6, q6
604#ifdef __ARMEL__
605	vrev32.8	q15, q15
606#endif
607	subs	r5,r5,#1
608	vstmia	r12!,{q0,q1,q2,q3,q4,q5,q6,q7}		@ write bit-sliced round key
609	bne	.Lkey_loop
610
611	vmov.i8	q7,#0x63			@ compose .L63
612	@ don't save last round key
613	bx	lr
614.size	_bsaes_key_convert,.-_bsaes_key_convert
615.globl	bsaes_ctr32_encrypt_blocks
616.hidden	bsaes_ctr32_encrypt_blocks
617.type	bsaes_ctr32_encrypt_blocks,%function
618.align	5
619bsaes_ctr32_encrypt_blocks:
620	@ In OpenSSL, short inputs fall back to aes_nohw_* here. We patch this
621	@ out to retain a constant-time implementation.
622	mov	ip, sp
623	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}
624	VFP_ABI_PUSH
625	ldr	r8, [ip]			@ ctr is 1st arg on the stack
626	sub	sp, sp, #0x10			@ scratch space to carry over the ctr
627	mov	r9, sp				@ save sp
628
629	ldr	r10, [r3, #240]		@ get # of rounds
630#ifndef	BSAES_ASM_EXTENDED_KEY
631	@ allocate the key schedule on the stack
632	sub	r12, sp, r10, lsl#7		@ 128 bytes per inner round key
633	add	r12, #96			@ size of bit-sliced key schedule
634
635	@ populate the key schedule
636	mov	r4, r3			@ pass key
637	mov	r5, r10			@ pass # of rounds
638	mov	sp, r12				@ sp is sp
639	bl	_bsaes_key_convert
640	veor	q7,q7,q15	@ fix up last round key
641	vstmia	r12, {q7}			@ save last round key
642
643	vld1.8	{q0}, [r8]		@ load counter
644#ifdef	__APPLE__
645	mov	r8, #:lower16:(.LREVM0SR-.LM0)
646	add	r8, r6, r8
647#else
648	add	r8, r6, #.LREVM0SR-.LM0	@ borrow r8
649#endif
650	vldmia	sp, {q4}		@ load round0 key
651#else
652	ldr	r12, [r3, #244]
653	eors	r12, #1
654	beq	0f
655
656	@ populate the key schedule
657	str	r12, [r3, #244]
658	mov	r4, r3			@ pass key
659	mov	r5, r10			@ pass # of rounds
660	add	r12, r3, #248			@ pass key schedule
661	bl	_bsaes_key_convert
662	veor	q7,q7,q15	@ fix up last round key
663	vstmia	r12, {q7}			@ save last round key
664
665.align	2
666	add	r12, r3, #248
667	vld1.8	{q0}, [r8]		@ load counter
668	adrl	r8, .LREVM0SR			@ borrow r8
669	vldmia	r12, {q4}			@ load round0 key
670	sub	sp, #0x10			@ place for adjusted round0 key
671#endif
672
673	vmov.i32	q8,#1		@ compose 1<<96
674	veor	q9,q9,q9
675	vrev32.8	q0,q0
676	vext.8	q8,q9,q8,#4
677	vrev32.8	q4,q4
678	vadd.u32	q9,q8,q8	@ compose 2<<96
679	vstmia	sp, {q4}		@ save adjusted round0 key
680	b	.Lctr_enc_loop
681
682.align	4
683.Lctr_enc_loop:
684	vadd.u32	q10, q8, q9	@ compose 3<<96
685	vadd.u32	q1, q0, q8	@ +1
686	vadd.u32	q2, q0, q9	@ +2
687	vadd.u32	q3, q0, q10	@ +3
688	vadd.u32	q4, q1, q10
689	vadd.u32	q5, q2, q10
690	vadd.u32	q6, q3, q10
691	vadd.u32	q7, q4, q10
692	vadd.u32	q10, q5, q10	@ next counter
693
694	@ Borrow prologue from _bsaes_encrypt8 to use the opportunity
695	@ to flip byte order in 32-bit counter
696
697	vldmia	sp, {q9}		@ load round0 key
698#ifndef	BSAES_ASM_EXTENDED_KEY
699	add	r4, sp, #0x10		@ pass next round key
700#else
701	add	r4, r3, #264
702#endif
703	vldmia	r8, {q8}			@ .LREVM0SR
704	mov	r5, r10			@ pass rounds
705	vstmia	r9, {q10}			@ save next counter
706#ifdef	__APPLE__
707	mov	r6, #:lower16:(.LREVM0SR-.LSR)
708	sub	r6, r8, r6
709#else
710	sub	r6, r8, #.LREVM0SR-.LSR	@ pass constants
711#endif
712
713	bl	_bsaes_encrypt8_alt
714
715	subs	r2, r2, #8
716	blo	.Lctr_enc_loop_done
717
718	vld1.8	{q8,q9}, [r0]!	@ load input
719	vld1.8	{q10,q11}, [r0]!
720	veor	q0, q8
721	veor	q1, q9
722	vld1.8	{q12,q13}, [r0]!
723	veor	q4, q10
724	veor	q6, q11
725	vld1.8	{q14,q15}, [r0]!
726	veor	q3, q12
727	vst1.8	{q0,q1}, [r1]!	@ write output
728	veor	q7, q13
729	veor	q2, q14
730	vst1.8	{q4}, [r1]!
731	veor	q5, q15
732	vst1.8	{q6}, [r1]!
733	vmov.i32	q8, #1			@ compose 1<<96
734	vst1.8	{q3}, [r1]!
735	veor	q9, q9, q9
736	vst1.8	{q7}, [r1]!
737	vext.8	q8, q9, q8, #4
738	vst1.8	{q2}, [r1]!
739	vadd.u32	q9,q8,q8		@ compose 2<<96
740	vst1.8	{q5}, [r1]!
741	vldmia	r9, {q0}			@ load counter
742
743	bne	.Lctr_enc_loop
744	b	.Lctr_enc_done
745
746.align	4
747.Lctr_enc_loop_done:
748	add	r2, r2, #8
749	vld1.8	{q8}, [r0]!	@ load input
750	veor	q0, q8
751	vst1.8	{q0}, [r1]!	@ write output
752	cmp	r2, #2
753	blo	.Lctr_enc_done
754	vld1.8	{q9}, [r0]!
755	veor	q1, q9
756	vst1.8	{q1}, [r1]!
757	beq	.Lctr_enc_done
758	vld1.8	{q10}, [r0]!
759	veor	q4, q10
760	vst1.8	{q4}, [r1]!
761	cmp	r2, #4
762	blo	.Lctr_enc_done
763	vld1.8	{q11}, [r0]!
764	veor	q6, q11
765	vst1.8	{q6}, [r1]!
766	beq	.Lctr_enc_done
767	vld1.8	{q12}, [r0]!
768	veor	q3, q12
769	vst1.8	{q3}, [r1]!
770	cmp	r2, #6
771	blo	.Lctr_enc_done
772	vld1.8	{q13}, [r0]!
773	veor	q7, q13
774	vst1.8	{q7}, [r1]!
775	beq	.Lctr_enc_done
776	vld1.8	{q14}, [r0]
777	veor	q2, q14
778	vst1.8	{q2}, [r1]!
779
780.Lctr_enc_done:
781	vmov.i32	q0, #0
782	vmov.i32	q1, #0
783#ifndef	BSAES_ASM_EXTENDED_KEY
784.Lctr_enc_bzero:@ wipe key schedule [if any]
785	vstmia	sp!, {q0,q1}
786	cmp	sp, r9
787	bne	.Lctr_enc_bzero
788#else
789	vstmia	sp, {q0,q1}
790#endif
791
792	mov	sp, r9
793	add	sp, #0x10		@ add sp,r9,#0x10 is no good for thumb
794	VFP_ABI_POP
795	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}	@ return
796
797	@ OpenSSL contains aes_nohw_* fallback code here. We patch this
798	@ out to retain a constant-time implementation.
799.size	bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
800#endif
801#endif
802#endif  // !OPENSSL_NO_ASM
803.section	.note.GNU-stack,"",%progbits
804