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