• 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#if defined(BORINGSSL_PREFIX)
14#include <boringssl_prefix_symbols_asm.h>
15#endif
16@ Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
17@
18@ Licensed under the OpenSSL license (the "License").  You may not use
19@ this file except in compliance with the License.  You can obtain a copy
20@ in the file LICENSE in the source distribution or at
21@ https://www.openssl.org/source/license.html
22
23
24@ ====================================================================
25@ Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
26@ project. The module is, however, dual licensed under OpenSSL and
27@ CRYPTOGAMS licenses depending on where you obtain it. For further
28@ details see http://www.openssl.org/~appro/cryptogams/.
29@
30@ Specific modes and adaptation for Linux kernel by Ard Biesheuvel
31@ of Linaro. Permission to use under GPL terms is granted.
32@ ====================================================================
33
34@ Bit-sliced AES for ARM NEON
35@
36@ February 2012.
37@
38@ This implementation is direct adaptation of bsaes-x86_64 module for
39@ ARM NEON. Except that this module is endian-neutral [in sense that
40@ it can be compiled for either endianness] by courtesy of vld1.8's
41@ neutrality. Initial version doesn't implement interface to OpenSSL,
42@ only low-level primitives and unsupported entry points, just enough
43@ to collect performance results, which for Cortex-A8 core are:
44@
45@ encrypt	19.5 cycles per byte processed with 128-bit key
46@ decrypt	22.1 cycles per byte processed with 128-bit key
47@ key conv.	440  cycles per 128-bit key/0.18 of 8x block
48@
49@ Snapdragon S4 encrypts byte in 17.6 cycles and decrypts in 19.7,
50@ which is [much] worse than anticipated (for further details see
51@ http://www.openssl.org/~appro/Snapdragon-S4.html).
52@
53@ Cortex-A15 manages in 14.2/16.1 cycles [when integer-only code
54@ manages in 20.0 cycles].
55@
56@ When comparing to x86_64 results keep in mind that NEON unit is
57@ [mostly] single-issue and thus can't [fully] benefit from
58@ instruction-level parallelism. And when comparing to aes-armv4
59@ results keep in mind key schedule conversion overhead (see
60@ bsaes-x86_64.pl for further details)...
61@
62@						<appro@openssl.org>
63
64@ April-August 2013
65@ Add CBC, CTR and XTS subroutines and adapt for kernel use; courtesy of Ard.
66
67#ifndef __KERNEL__
68# include <openssl/arm_arch.h>
69
70# define VFP_ABI_PUSH	vstmdb	sp!,{d8-d15}
71# define VFP_ABI_POP	vldmia	sp!,{d8-d15}
72# define VFP_ABI_FRAME	0x40
73#else
74# define VFP_ABI_PUSH
75# define VFP_ABI_POP
76# define VFP_ABI_FRAME	0
77# define BSAES_ASM_EXTENDED_KEY
78# define XTS_CHAIN_TWEAK
79# define __ARM_ARCH__ __LINUX_ARM_ARCH__
80# define __ARM_MAX_ARCH__ 7
81#endif
82
83#ifdef __thumb__
84# define adrl adr
85#endif
86
87#if __ARM_MAX_ARCH__>=7
88.arch	armv7-a
89.fpu	neon
90
91.text
92.syntax	unified 	@ ARMv7-capable assembler is expected to handle this
93#if defined(__thumb2__) && !defined(__APPLE__)
94.thumb
95#else
96.code	32
97# undef __thumb2__
98#endif
99
100.type	_bsaes_decrypt8,%function
101.align	4
102_bsaes_decrypt8:
103	adr	r6,.
104	vldmia	r4!, {q9}		@ round 0 key
105#if defined(__thumb2__) || defined(__APPLE__)
106	adr	r6,.LM0ISR
107#else
108	add	r6,r6,#.LM0ISR-_bsaes_decrypt8
109#endif
110
111	vldmia	r6!, {q8}		@ .LM0ISR
112	veor	q10, q0, q9	@ xor with round0 key
113	veor	q11, q1, q9
114	vtbl.8	d0, {q10}, d16
115	vtbl.8	d1, {q10}, d17
116	veor	q12, q2, q9
117	vtbl.8	d2, {q11}, d16
118	vtbl.8	d3, {q11}, d17
119	veor	q13, q3, q9
120	vtbl.8	d4, {q12}, d16
121	vtbl.8	d5, {q12}, d17
122	veor	q14, q4, q9
123	vtbl.8	d6, {q13}, d16
124	vtbl.8	d7, {q13}, d17
125	veor	q15, q5, q9
126	vtbl.8	d8, {q14}, d16
127	vtbl.8	d9, {q14}, d17
128	veor	q10, q6, q9
129	vtbl.8	d10, {q15}, d16
130	vtbl.8	d11, {q15}, d17
131	veor	q11, q7, q9
132	vtbl.8	d12, {q10}, d16
133	vtbl.8	d13, {q10}, d17
134	vtbl.8	d14, {q11}, d16
135	vtbl.8	d15, {q11}, d17
136	vmov.i8	q8,#0x55			@ compose .LBS0
137	vmov.i8	q9,#0x33			@ compose .LBS1
138	vshr.u64	q10, q6, #1
139	vshr.u64	q11, q4, #1
140	veor	q10, q10, q7
141	veor	q11, q11, q5
142	vand	q10, q10, q8
143	vand	q11, q11, q8
144	veor	q7, q7, q10
145	vshl.u64	q10, q10, #1
146	veor	q5, q5, q11
147	vshl.u64	q11, q11, #1
148	veor	q6, q6, q10
149	veor	q4, q4, q11
150	vshr.u64	q10, q2, #1
151	vshr.u64	q11, q0, #1
152	veor	q10, q10, q3
153	veor	q11, q11, q1
154	vand	q10, q10, q8
155	vand	q11, q11, q8
156	veor	q3, q3, q10
157	vshl.u64	q10, q10, #1
158	veor	q1, q1, q11
159	vshl.u64	q11, q11, #1
160	veor	q2, q2, q10
161	veor	q0, q0, q11
162	vmov.i8	q8,#0x0f			@ compose .LBS2
163	vshr.u64	q10, q5, #2
164	vshr.u64	q11, q4, #2
165	veor	q10, q10, q7
166	veor	q11, q11, q6
167	vand	q10, q10, q9
168	vand	q11, q11, q9
169	veor	q7, q7, q10
170	vshl.u64	q10, q10, #2
171	veor	q6, q6, q11
172	vshl.u64	q11, q11, #2
173	veor	q5, q5, q10
174	veor	q4, q4, q11
175	vshr.u64	q10, q1, #2
176	vshr.u64	q11, q0, #2
177	veor	q10, q10, q3
178	veor	q11, q11, q2
179	vand	q10, q10, q9
180	vand	q11, q11, q9
181	veor	q3, q3, q10
182	vshl.u64	q10, q10, #2
183	veor	q2, q2, q11
184	vshl.u64	q11, q11, #2
185	veor	q1, q1, q10
186	veor	q0, q0, q11
187	vshr.u64	q10, q3, #4
188	vshr.u64	q11, q2, #4
189	veor	q10, q10, q7
190	veor	q11, q11, q6
191	vand	q10, q10, q8
192	vand	q11, q11, q8
193	veor	q7, q7, q10
194	vshl.u64	q10, q10, #4
195	veor	q6, q6, q11
196	vshl.u64	q11, q11, #4
197	veor	q3, q3, q10
198	veor	q2, q2, q11
199	vshr.u64	q10, q1, #4
200	vshr.u64	q11, q0, #4
201	veor	q10, q10, q5
202	veor	q11, q11, q4
203	vand	q10, q10, q8
204	vand	q11, q11, q8
205	veor	q5, q5, q10
206	vshl.u64	q10, q10, #4
207	veor	q4, q4, q11
208	vshl.u64	q11, q11, #4
209	veor	q1, q1, q10
210	veor	q0, q0, q11
211	sub	r5,r5,#1
212	b	.Ldec_sbox
213.align	4
214.Ldec_loop:
215	vldmia	r4!, {q8,q9,q10,q11}
216	veor	q8, q8, q0
217	veor	q9, q9, q1
218	vtbl.8	d0, {q8}, d24
219	vtbl.8	d1, {q8}, d25
220	vldmia	r4!, {q8}
221	veor	q10, q10, q2
222	vtbl.8	d2, {q9}, d24
223	vtbl.8	d3, {q9}, d25
224	vldmia	r4!, {q9}
225	veor	q11, q11, q3
226	vtbl.8	d4, {q10}, d24
227	vtbl.8	d5, {q10}, d25
228	vldmia	r4!, {q10}
229	vtbl.8	d6, {q11}, d24
230	vtbl.8	d7, {q11}, d25
231	vldmia	r4!, {q11}
232	veor	q8, q8, q4
233	veor	q9, q9, q5
234	vtbl.8	d8, {q8}, d24
235	vtbl.8	d9, {q8}, d25
236	veor	q10, q10, q6
237	vtbl.8	d10, {q9}, d24
238	vtbl.8	d11, {q9}, d25
239	veor	q11, q11, q7
240	vtbl.8	d12, {q10}, d24
241	vtbl.8	d13, {q10}, d25
242	vtbl.8	d14, {q11}, d24
243	vtbl.8	d15, {q11}, d25
244.Ldec_sbox:
245	veor	q1, q1, q4
246	veor	q3, q3, q4
247
248	veor	q4, q4, q7
249	veor	q1, q1, q6
250	veor	q2, q2, q7
251	veor	q6, q6, q4
252
253	veor	q0, q0, q1
254	veor	q2, q2, q5
255	veor	q7, q7, q6
256	veor	q3, q3, q0
257	veor	q5, q5, q0
258	veor	q1, q1, q3
259	veor	q11, q3, q0
260	veor	q10, q7, q4
261	veor	q9, q1, q6
262	veor	q13, q4, q0
263	vmov	q8, q10
264	veor	q12, q5, q2
265
266	vorr	q10, q10, q9
267	veor	q15, q11, q8
268	vand	q14, q11, q12
269	vorr	q11, q11, q12
270	veor	q12, q12, q9
271	vand	q8, q8, q9
272	veor	q9, q6, q2
273	vand	q15, q15, q12
274	vand	q13, q13, q9
275	veor	q9, q3, q7
276	veor	q12, q1, q5
277	veor	q11, q11, q13
278	veor	q10, q10, q13
279	vand	q13, q9, q12
280	vorr	q9, q9, q12
281	veor	q11, q11, q15
282	veor	q8, q8, q13
283	veor	q10, q10, q14
284	veor	q9, q9, q15
285	veor	q8, q8, q14
286	vand	q12, q4, q6
287	veor	q9, q9, q14
288	vand	q13, q0, q2
289	vand	q14, q7, q1
290	vorr	q15, q3, q5
291	veor	q11, q11, q12
292	veor	q9, q9, q14
293	veor	q8, q8, q15
294	veor	q10, q10, q13
295
296	@ Inv_GF16 	0, 	1, 	2, 	3, s0, s1, s2, s3
297
298	@ new smaller inversion
299
300	vand	q14, q11, q9
301	vmov	q12, q8
302
303	veor	q13, q10, q14
304	veor	q15, q8, q14
305	veor	q14, q8, q14	@ q14=q15
306
307	vbsl	q13, q9, q8
308	vbsl	q15, q11, q10
309	veor	q11, q11, q10
310
311	vbsl	q12, q13, q14
312	vbsl	q8, q14, q13
313
314	vand	q14, q12, q15
315	veor	q9, q9, q8
316
317	veor	q14, q14, q11
318	veor	q12, q5, q2
319	veor	q8, q1, q6
320	veor	q10, q15, q14
321	vand	q10, q10, q5
322	veor	q5, q5, q1
323	vand	q11, q1, q15
324	vand	q5, q5, q14
325	veor	q1, q11, q10
326	veor	q5, q5, q11
327	veor	q15, q15, q13
328	veor	q14, q14, q9
329	veor	q11, q15, q14
330	veor	q10, q13, q9
331	vand	q11, q11, q12
332	vand	q10, q10, q2
333	veor	q12, q12, q8
334	veor	q2, q2, q6
335	vand	q8, q8, q15
336	vand	q6, q6, q13
337	vand	q12, q12, q14
338	vand	q2, q2, q9
339	veor	q8, q8, q12
340	veor	q2, q2, q6
341	veor	q12, q12, q11
342	veor	q6, q6, q10
343	veor	q5, q5, q12
344	veor	q2, q2, q12
345	veor	q1, q1, q8
346	veor	q6, q6, q8
347
348	veor	q12, q3, q0
349	veor	q8, q7, q4
350	veor	q11, q15, q14
351	veor	q10, q13, q9
352	vand	q11, q11, q12
353	vand	q10, q10, q0
354	veor	q12, q12, q8
355	veor	q0, q0, q4
356	vand	q8, q8, q15
357	vand	q4, q4, q13
358	vand	q12, q12, q14
359	vand	q0, q0, q9
360	veor	q8, q8, q12
361	veor	q0, q0, q4
362	veor	q12, q12, q11
363	veor	q4, q4, q10
364	veor	q15, q15, q13
365	veor	q14, q14, q9
366	veor	q10, q15, q14
367	vand	q10, q10, q3
368	veor	q3, q3, q7
369	vand	q11, q7, q15
370	vand	q3, q3, q14
371	veor	q7, q11, q10
372	veor	q3, q3, q11
373	veor	q3, q3, q12
374	veor	q0, q0, q12
375	veor	q7, q7, q8
376	veor	q4, q4, q8
377	veor	q1, q1, q7
378	veor	q6, q6, q5
379
380	veor	q4, q4, q1
381	veor	q2, q2, q7
382	veor	q5, q5, q7
383	veor	q4, q4, q2
384	veor	q7, q7, q0
385	veor	q4, q4, q5
386	veor	q3, q3, q6
387	veor	q6, q6, q1
388	veor	q3, q3, q4
389
390	veor	q4, q4, q0
391	veor	q7, q7, q3
392	subs	r5,r5,#1
393	bcc	.Ldec_done
394	@ multiplication by 0x05-0x00-0x04-0x00
395	vext.8	q8, q0, q0, #8
396	vext.8	q14, q3, q3, #8
397	vext.8	q15, q5, q5, #8
398	veor	q8, q8, q0
399	vext.8	q9, q1, q1, #8
400	veor	q14, q14, q3
401	vext.8	q10, q6, q6, #8
402	veor	q15, q15, q5
403	vext.8	q11, q4, q4, #8
404	veor	q9, q9, q1
405	vext.8	q12, q2, q2, #8
406	veor	q10, q10, q6
407	vext.8	q13, q7, q7, #8
408	veor	q11, q11, q4
409	veor	q12, q12, q2
410	veor	q13, q13, q7
411
412	veor	q0, q0, q14
413	veor	q1, q1, q14
414	veor	q6, q6, q8
415	veor	q2, q2, q10
416	veor	q4, q4, q9
417	veor	q1, q1, q15
418	veor	q6, q6, q15
419	veor	q2, q2, q14
420	veor	q7, q7, q11
421	veor	q4, q4, q14
422	veor	q3, q3, q12
423	veor	q2, q2, q15
424	veor	q7, q7, q15
425	veor	q5, q5, q13
426	vext.8	q8, q0, q0, #12	@ x0 <<< 32
427	vext.8	q9, q1, q1, #12
428	veor	q0, q0, q8		@ x0 ^ (x0 <<< 32)
429	vext.8	q10, q6, q6, #12
430	veor	q1, q1, q9
431	vext.8	q11, q4, q4, #12
432	veor	q6, q6, q10
433	vext.8	q12, q2, q2, #12
434	veor	q4, q4, q11
435	vext.8	q13, q7, q7, #12
436	veor	q2, q2, q12
437	vext.8	q14, q3, q3, #12
438	veor	q7, q7, q13
439	vext.8	q15, q5, q5, #12
440	veor	q3, q3, q14
441
442	veor	q9, q9, q0
443	veor	q5, q5, q15
444	vext.8	q0, q0, q0, #8		@ (x0 ^ (x0 <<< 32)) <<< 64)
445	veor	q10, q10, q1
446	veor	q8, q8, q5
447	veor	q9, q9, q5
448	vext.8	q1, q1, q1, #8
449	veor	q13, q13, q2
450	veor	q0, q0, q8
451	veor	q14, q14, q7
452	veor	q1, q1, q9
453	vext.8	q8, q2, q2, #8
454	veor	q12, q12, q4
455	vext.8	q9, q7, q7, #8
456	veor	q15, q15, q3
457	vext.8	q2, q4, q4, #8
458	veor	q11, q11, q6
459	vext.8	q7, q5, q5, #8
460	veor	q12, q12, q5
461	vext.8	q4, q3, q3, #8
462	veor	q11, q11, q5
463	vext.8	q3, q6, q6, #8
464	veor	q5, q9, q13
465	veor	q11, q11, q2
466	veor	q7, q7, q15
467	veor	q6, q4, q14
468	veor	q4, q8, q12
469	veor	q2, q3, q10
470	vmov	q3, q11
471	 @ vmov	q5, q9
472	vldmia	r6, {q12}		@ .LISR
473	ite	eq				@ Thumb2 thing, sanity check in ARM
474	addeq	r6,r6,#0x10
475	bne	.Ldec_loop
476	vldmia	r6, {q12}		@ .LISRM0
477	b	.Ldec_loop
478.align	4
479.Ldec_done:
480	vmov.i8	q8,#0x55			@ compose .LBS0
481	vmov.i8	q9,#0x33			@ compose .LBS1
482	vshr.u64	q10, q3, #1
483	vshr.u64	q11, q2, #1
484	veor	q10, q10, q5
485	veor	q11, q11, q7
486	vand	q10, q10, q8
487	vand	q11, q11, q8
488	veor	q5, q5, q10
489	vshl.u64	q10, q10, #1
490	veor	q7, q7, q11
491	vshl.u64	q11, q11, #1
492	veor	q3, q3, q10
493	veor	q2, q2, q11
494	vshr.u64	q10, q6, #1
495	vshr.u64	q11, q0, #1
496	veor	q10, q10, q4
497	veor	q11, q11, q1
498	vand	q10, q10, q8
499	vand	q11, q11, q8
500	veor	q4, q4, q10
501	vshl.u64	q10, q10, #1
502	veor	q1, q1, q11
503	vshl.u64	q11, q11, #1
504	veor	q6, q6, q10
505	veor	q0, q0, q11
506	vmov.i8	q8,#0x0f			@ compose .LBS2
507	vshr.u64	q10, q7, #2
508	vshr.u64	q11, q2, #2
509	veor	q10, q10, q5
510	veor	q11, q11, q3
511	vand	q10, q10, q9
512	vand	q11, q11, q9
513	veor	q5, q5, q10
514	vshl.u64	q10, q10, #2
515	veor	q3, q3, q11
516	vshl.u64	q11, q11, #2
517	veor	q7, q7, q10
518	veor	q2, q2, q11
519	vshr.u64	q10, q1, #2
520	vshr.u64	q11, q0, #2
521	veor	q10, q10, q4
522	veor	q11, q11, q6
523	vand	q10, q10, q9
524	vand	q11, q11, q9
525	veor	q4, q4, q10
526	vshl.u64	q10, q10, #2
527	veor	q6, q6, q11
528	vshl.u64	q11, q11, #2
529	veor	q1, q1, q10
530	veor	q0, q0, q11
531	vshr.u64	q10, q4, #4
532	vshr.u64	q11, q6, #4
533	veor	q10, q10, q5
534	veor	q11, q11, q3
535	vand	q10, q10, q8
536	vand	q11, q11, q8
537	veor	q5, q5, q10
538	vshl.u64	q10, q10, #4
539	veor	q3, q3, q11
540	vshl.u64	q11, q11, #4
541	veor	q4, q4, q10
542	veor	q6, q6, q11
543	vshr.u64	q10, q1, #4
544	vshr.u64	q11, q0, #4
545	veor	q10, q10, q7
546	veor	q11, q11, q2
547	vand	q10, q10, q8
548	vand	q11, q11, q8
549	veor	q7, q7, q10
550	vshl.u64	q10, q10, #4
551	veor	q2, q2, q11
552	vshl.u64	q11, q11, #4
553	veor	q1, q1, q10
554	veor	q0, q0, q11
555	vldmia	r4, {q8}			@ last round key
556	veor	q6, q6, q8
557	veor	q4, q4, q8
558	veor	q2, q2, q8
559	veor	q7, q7, q8
560	veor	q3, q3, q8
561	veor	q5, q5, q8
562	veor	q0, q0, q8
563	veor	q1, q1, q8
564	bx	lr
565.size	_bsaes_decrypt8,.-_bsaes_decrypt8
566
567.type	_bsaes_const,%object
568.align	6
569_bsaes_const:
570.LM0ISR:@ InvShiftRows constants
571.quad	0x0a0e0206070b0f03, 0x0004080c0d010509
572.LISR:
573.quad	0x0504070602010003, 0x0f0e0d0c080b0a09
574.LISRM0:
575.quad	0x01040b0e0205080f, 0x0306090c00070a0d
576.LM0SR:@ ShiftRows constants
577.quad	0x0a0e02060f03070b, 0x0004080c05090d01
578.LSR:
579.quad	0x0504070600030201, 0x0f0e0d0c0a09080b
580.LSRM0:
581.quad	0x0304090e00050a0f, 0x01060b0c0207080d
582.LM0:
583.quad	0x02060a0e03070b0f, 0x0004080c0105090d
584.LREVM0SR:
585.quad	0x090d01050c000408, 0x03070b0f060a0e02
586.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
587.align	2
588.align	6
589.size	_bsaes_const,.-_bsaes_const
590
591.type	_bsaes_encrypt8,%function
592.align	4
593_bsaes_encrypt8:
594	adr	r6,.
595	vldmia	r4!, {q9}		@ round 0 key
596#if defined(__thumb2__) || defined(__APPLE__)
597	adr	r6,.LM0SR
598#else
599	sub	r6,r6,#_bsaes_encrypt8-.LM0SR
600#endif
601
602	vldmia	r6!, {q8}		@ .LM0SR
603_bsaes_encrypt8_alt:
604	veor	q10, q0, q9	@ xor with round0 key
605	veor	q11, q1, q9
606	vtbl.8	d0, {q10}, d16
607	vtbl.8	d1, {q10}, d17
608	veor	q12, q2, q9
609	vtbl.8	d2, {q11}, d16
610	vtbl.8	d3, {q11}, d17
611	veor	q13, q3, q9
612	vtbl.8	d4, {q12}, d16
613	vtbl.8	d5, {q12}, d17
614	veor	q14, q4, q9
615	vtbl.8	d6, {q13}, d16
616	vtbl.8	d7, {q13}, d17
617	veor	q15, q5, q9
618	vtbl.8	d8, {q14}, d16
619	vtbl.8	d9, {q14}, d17
620	veor	q10, q6, q9
621	vtbl.8	d10, {q15}, d16
622	vtbl.8	d11, {q15}, d17
623	veor	q11, q7, q9
624	vtbl.8	d12, {q10}, d16
625	vtbl.8	d13, {q10}, d17
626	vtbl.8	d14, {q11}, d16
627	vtbl.8	d15, {q11}, d17
628_bsaes_encrypt8_bitslice:
629	vmov.i8	q8,#0x55			@ compose .LBS0
630	vmov.i8	q9,#0x33			@ compose .LBS1
631	vshr.u64	q10, q6, #1
632	vshr.u64	q11, q4, #1
633	veor	q10, q10, q7
634	veor	q11, q11, q5
635	vand	q10, q10, q8
636	vand	q11, q11, q8
637	veor	q7, q7, q10
638	vshl.u64	q10, q10, #1
639	veor	q5, q5, q11
640	vshl.u64	q11, q11, #1
641	veor	q6, q6, q10
642	veor	q4, q4, q11
643	vshr.u64	q10, q2, #1
644	vshr.u64	q11, q0, #1
645	veor	q10, q10, q3
646	veor	q11, q11, q1
647	vand	q10, q10, q8
648	vand	q11, q11, q8
649	veor	q3, q3, q10
650	vshl.u64	q10, q10, #1
651	veor	q1, q1, q11
652	vshl.u64	q11, q11, #1
653	veor	q2, q2, q10
654	veor	q0, q0, q11
655	vmov.i8	q8,#0x0f			@ compose .LBS2
656	vshr.u64	q10, q5, #2
657	vshr.u64	q11, q4, #2
658	veor	q10, q10, q7
659	veor	q11, q11, q6
660	vand	q10, q10, q9
661	vand	q11, q11, q9
662	veor	q7, q7, q10
663	vshl.u64	q10, q10, #2
664	veor	q6, q6, q11
665	vshl.u64	q11, q11, #2
666	veor	q5, q5, q10
667	veor	q4, q4, q11
668	vshr.u64	q10, q1, #2
669	vshr.u64	q11, q0, #2
670	veor	q10, q10, q3
671	veor	q11, q11, q2
672	vand	q10, q10, q9
673	vand	q11, q11, q9
674	veor	q3, q3, q10
675	vshl.u64	q10, q10, #2
676	veor	q2, q2, q11
677	vshl.u64	q11, q11, #2
678	veor	q1, q1, q10
679	veor	q0, q0, q11
680	vshr.u64	q10, q3, #4
681	vshr.u64	q11, q2, #4
682	veor	q10, q10, q7
683	veor	q11, q11, q6
684	vand	q10, q10, q8
685	vand	q11, q11, q8
686	veor	q7, q7, q10
687	vshl.u64	q10, q10, #4
688	veor	q6, q6, q11
689	vshl.u64	q11, q11, #4
690	veor	q3, q3, q10
691	veor	q2, q2, q11
692	vshr.u64	q10, q1, #4
693	vshr.u64	q11, q0, #4
694	veor	q10, q10, q5
695	veor	q11, q11, q4
696	vand	q10, q10, q8
697	vand	q11, q11, q8
698	veor	q5, q5, q10
699	vshl.u64	q10, q10, #4
700	veor	q4, q4, q11
701	vshl.u64	q11, q11, #4
702	veor	q1, q1, q10
703	veor	q0, q0, q11
704	sub	r5,r5,#1
705	b	.Lenc_sbox
706.align	4
707.Lenc_loop:
708	vldmia	r4!, {q8,q9,q10,q11}
709	veor	q8, q8, q0
710	veor	q9, q9, q1
711	vtbl.8	d0, {q8}, d24
712	vtbl.8	d1, {q8}, d25
713	vldmia	r4!, {q8}
714	veor	q10, q10, q2
715	vtbl.8	d2, {q9}, d24
716	vtbl.8	d3, {q9}, d25
717	vldmia	r4!, {q9}
718	veor	q11, q11, q3
719	vtbl.8	d4, {q10}, d24
720	vtbl.8	d5, {q10}, d25
721	vldmia	r4!, {q10}
722	vtbl.8	d6, {q11}, d24
723	vtbl.8	d7, {q11}, d25
724	vldmia	r4!, {q11}
725	veor	q8, q8, q4
726	veor	q9, q9, q5
727	vtbl.8	d8, {q8}, d24
728	vtbl.8	d9, {q8}, d25
729	veor	q10, q10, q6
730	vtbl.8	d10, {q9}, d24
731	vtbl.8	d11, {q9}, d25
732	veor	q11, q11, q7
733	vtbl.8	d12, {q10}, d24
734	vtbl.8	d13, {q10}, d25
735	vtbl.8	d14, {q11}, d24
736	vtbl.8	d15, {q11}, d25
737.Lenc_sbox:
738	veor	q2, q2, q1
739	veor	q5, q5, q6
740	veor	q3, q3, q0
741	veor	q6, q6, q2
742	veor	q5, q5, q0
743
744	veor	q6, q6, q3
745	veor	q3, q3, q7
746	veor	q7, q7, q5
747	veor	q3, q3, q4
748	veor	q4, q4, q5
749
750	veor	q2, q2, q7
751	veor	q3, q3, q1
752	veor	q1, q1, q5
753	veor	q11, q7, q4
754	veor	q10, q1, q2
755	veor	q9, q5, q3
756	veor	q13, q2, q4
757	vmov	q8, q10
758	veor	q12, q6, q0
759
760	vorr	q10, q10, q9
761	veor	q15, q11, q8
762	vand	q14, q11, q12
763	vorr	q11, q11, q12
764	veor	q12, q12, q9
765	vand	q8, q8, q9
766	veor	q9, q3, q0
767	vand	q15, q15, q12
768	vand	q13, q13, q9
769	veor	q9, q7, q1
770	veor	q12, q5, q6
771	veor	q11, q11, q13
772	veor	q10, q10, q13
773	vand	q13, q9, q12
774	vorr	q9, q9, q12
775	veor	q11, q11, q15
776	veor	q8, q8, q13
777	veor	q10, q10, q14
778	veor	q9, q9, q15
779	veor	q8, q8, q14
780	vand	q12, q2, q3
781	veor	q9, q9, q14
782	vand	q13, q4, q0
783	vand	q14, q1, q5
784	vorr	q15, q7, q6
785	veor	q11, q11, q12
786	veor	q9, q9, q14
787	veor	q8, q8, q15
788	veor	q10, q10, q13
789
790	@ Inv_GF16 	0, 	1, 	2, 	3, s0, s1, s2, s3
791
792	@ new smaller inversion
793
794	vand	q14, q11, q9
795	vmov	q12, q8
796
797	veor	q13, q10, q14
798	veor	q15, q8, q14
799	veor	q14, q8, q14	@ q14=q15
800
801	vbsl	q13, q9, q8
802	vbsl	q15, q11, q10
803	veor	q11, q11, q10
804
805	vbsl	q12, q13, q14
806	vbsl	q8, q14, q13
807
808	vand	q14, q12, q15
809	veor	q9, q9, q8
810
811	veor	q14, q14, q11
812	veor	q12, q6, q0
813	veor	q8, q5, q3
814	veor	q10, q15, q14
815	vand	q10, q10, q6
816	veor	q6, q6, q5
817	vand	q11, q5, q15
818	vand	q6, q6, q14
819	veor	q5, q11, q10
820	veor	q6, q6, q11
821	veor	q15, q15, q13
822	veor	q14, q14, q9
823	veor	q11, q15, q14
824	veor	q10, q13, q9
825	vand	q11, q11, q12
826	vand	q10, q10, q0
827	veor	q12, q12, q8
828	veor	q0, q0, q3
829	vand	q8, q8, q15
830	vand	q3, q3, q13
831	vand	q12, q12, q14
832	vand	q0, q0, q9
833	veor	q8, q8, q12
834	veor	q0, q0, q3
835	veor	q12, q12, q11
836	veor	q3, q3, q10
837	veor	q6, q6, q12
838	veor	q0, q0, q12
839	veor	q5, q5, q8
840	veor	q3, q3, q8
841
842	veor	q12, q7, q4
843	veor	q8, q1, q2
844	veor	q11, q15, q14
845	veor	q10, q13, q9
846	vand	q11, q11, q12
847	vand	q10, q10, q4
848	veor	q12, q12, q8
849	veor	q4, q4, q2
850	vand	q8, q8, q15
851	vand	q2, q2, q13
852	vand	q12, q12, q14
853	vand	q4, q4, q9
854	veor	q8, q8, q12
855	veor	q4, q4, q2
856	veor	q12, q12, q11
857	veor	q2, q2, q10
858	veor	q15, q15, q13
859	veor	q14, q14, q9
860	veor	q10, q15, q14
861	vand	q10, q10, q7
862	veor	q7, q7, q1
863	vand	q11, q1, q15
864	vand	q7, q7, q14
865	veor	q1, q11, q10
866	veor	q7, q7, q11
867	veor	q7, q7, q12
868	veor	q4, q4, q12
869	veor	q1, q1, q8
870	veor	q2, q2, q8
871	veor	q7, q7, q0
872	veor	q1, q1, q6
873	veor	q6, q6, q0
874	veor	q4, q4, q7
875	veor	q0, q0, q1
876
877	veor	q1, q1, q5
878	veor	q5, q5, q2
879	veor	q2, q2, q3
880	veor	q3, q3, q5
881	veor	q4, q4, q5
882
883	veor	q6, q6, q3
884	subs	r5,r5,#1
885	bcc	.Lenc_done
886	vext.8	q8, q0, q0, #12	@ x0 <<< 32
887	vext.8	q9, q1, q1, #12
888	veor	q0, q0, q8		@ x0 ^ (x0 <<< 32)
889	vext.8	q10, q4, q4, #12
890	veor	q1, q1, q9
891	vext.8	q11, q6, q6, #12
892	veor	q4, q4, q10
893	vext.8	q12, q3, q3, #12
894	veor	q6, q6, q11
895	vext.8	q13, q7, q7, #12
896	veor	q3, q3, q12
897	vext.8	q14, q2, q2, #12
898	veor	q7, q7, q13
899	vext.8	q15, q5, q5, #12
900	veor	q2, q2, q14
901
902	veor	q9, q9, q0
903	veor	q5, q5, q15
904	vext.8	q0, q0, q0, #8		@ (x0 ^ (x0 <<< 32)) <<< 64)
905	veor	q10, q10, q1
906	veor	q8, q8, q5
907	veor	q9, q9, q5
908	vext.8	q1, q1, q1, #8
909	veor	q13, q13, q3
910	veor	q0, q0, q8
911	veor	q14, q14, q7
912	veor	q1, q1, q9
913	vext.8	q8, q3, q3, #8
914	veor	q12, q12, q6
915	vext.8	q9, q7, q7, #8
916	veor	q15, q15, q2
917	vext.8	q3, q6, q6, #8
918	veor	q11, q11, q4
919	vext.8	q7, q5, q5, #8
920	veor	q12, q12, q5
921	vext.8	q6, q2, q2, #8
922	veor	q11, q11, q5
923	vext.8	q2, q4, q4, #8
924	veor	q5, q9, q13
925	veor	q4, q8, q12
926	veor	q3, q3, q11
927	veor	q7, q7, q15
928	veor	q6, q6, q14
929	 @ vmov	q4, q8
930	veor	q2, q2, q10
931	 @ vmov	q5, q9
932	vldmia	r6, {q12}		@ .LSR
933	ite	eq				@ Thumb2 thing, samity check in ARM
934	addeq	r6,r6,#0x10
935	bne	.Lenc_loop
936	vldmia	r6, {q12}		@ .LSRM0
937	b	.Lenc_loop
938.align	4
939.Lenc_done:
940	vmov.i8	q8,#0x55			@ compose .LBS0
941	vmov.i8	q9,#0x33			@ compose .LBS1
942	vshr.u64	q10, q2, #1
943	vshr.u64	q11, q3, #1
944	veor	q10, q10, q5
945	veor	q11, q11, q7
946	vand	q10, q10, q8
947	vand	q11, q11, q8
948	veor	q5, q5, q10
949	vshl.u64	q10, q10, #1
950	veor	q7, q7, q11
951	vshl.u64	q11, q11, #1
952	veor	q2, q2, q10
953	veor	q3, q3, q11
954	vshr.u64	q10, q4, #1
955	vshr.u64	q11, q0, #1
956	veor	q10, q10, q6
957	veor	q11, q11, q1
958	vand	q10, q10, q8
959	vand	q11, q11, q8
960	veor	q6, q6, q10
961	vshl.u64	q10, q10, #1
962	veor	q1, q1, q11
963	vshl.u64	q11, q11, #1
964	veor	q4, q4, q10
965	veor	q0, q0, q11
966	vmov.i8	q8,#0x0f			@ compose .LBS2
967	vshr.u64	q10, q7, #2
968	vshr.u64	q11, q3, #2
969	veor	q10, q10, q5
970	veor	q11, q11, q2
971	vand	q10, q10, q9
972	vand	q11, q11, q9
973	veor	q5, q5, q10
974	vshl.u64	q10, q10, #2
975	veor	q2, q2, q11
976	vshl.u64	q11, q11, #2
977	veor	q7, q7, q10
978	veor	q3, q3, q11
979	vshr.u64	q10, q1, #2
980	vshr.u64	q11, q0, #2
981	veor	q10, q10, q6
982	veor	q11, q11, q4
983	vand	q10, q10, q9
984	vand	q11, q11, q9
985	veor	q6, q6, q10
986	vshl.u64	q10, q10, #2
987	veor	q4, q4, q11
988	vshl.u64	q11, q11, #2
989	veor	q1, q1, q10
990	veor	q0, q0, q11
991	vshr.u64	q10, q6, #4
992	vshr.u64	q11, q4, #4
993	veor	q10, q10, q5
994	veor	q11, q11, q2
995	vand	q10, q10, q8
996	vand	q11, q11, q8
997	veor	q5, q5, q10
998	vshl.u64	q10, q10, #4
999	veor	q2, q2, q11
1000	vshl.u64	q11, q11, #4
1001	veor	q6, q6, q10
1002	veor	q4, q4, q11
1003	vshr.u64	q10, q1, #4
1004	vshr.u64	q11, q0, #4
1005	veor	q10, q10, q7
1006	veor	q11, q11, q3
1007	vand	q10, q10, q8
1008	vand	q11, q11, q8
1009	veor	q7, q7, q10
1010	vshl.u64	q10, q10, #4
1011	veor	q3, q3, q11
1012	vshl.u64	q11, q11, #4
1013	veor	q1, q1, q10
1014	veor	q0, q0, q11
1015	vldmia	r4, {q8}			@ last round key
1016	veor	q4, q4, q8
1017	veor	q6, q6, q8
1018	veor	q3, q3, q8
1019	veor	q7, q7, q8
1020	veor	q2, q2, q8
1021	veor	q5, q5, q8
1022	veor	q0, q0, q8
1023	veor	q1, q1, q8
1024	bx	lr
1025.size	_bsaes_encrypt8,.-_bsaes_encrypt8
1026.type	_bsaes_key_convert,%function
1027.align	4
1028_bsaes_key_convert:
1029	adr	r6,.
1030	vld1.8	{q7},  [r4]!		@ load round 0 key
1031#if defined(__thumb2__) || defined(__APPLE__)
1032	adr	r6,.LM0
1033#else
1034	sub	r6,r6,#_bsaes_key_convert-.LM0
1035#endif
1036	vld1.8	{q15}, [r4]!		@ load round 1 key
1037
1038	vmov.i8	q8,  #0x01			@ bit masks
1039	vmov.i8	q9,  #0x02
1040	vmov.i8	q10, #0x04
1041	vmov.i8	q11, #0x08
1042	vmov.i8	q12, #0x10
1043	vmov.i8	q13, #0x20
1044	vldmia	r6, {q14}		@ .LM0
1045
1046#ifdef __ARMEL__
1047	vrev32.8	q7,  q7
1048	vrev32.8	q15, q15
1049#endif
1050	sub	r5,r5,#1
1051	vstmia	r12!, {q7}		@ save round 0 key
1052	b	.Lkey_loop
1053
1054.align	4
1055.Lkey_loop:
1056	vtbl.8	d14,{q15},d28
1057	vtbl.8	d15,{q15},d29
1058	vmov.i8	q6,  #0x40
1059	vmov.i8	q15, #0x80
1060
1061	vtst.8	q0, q7, q8
1062	vtst.8	q1, q7, q9
1063	vtst.8	q2, q7, q10
1064	vtst.8	q3, q7, q11
1065	vtst.8	q4, q7, q12
1066	vtst.8	q5, q7, q13
1067	vtst.8	q6, q7, q6
1068	vtst.8	q7, q7, q15
1069	vld1.8	{q15}, [r4]!		@ load next round key
1070	vmvn	q0, q0		@ "pnot"
1071	vmvn	q1, q1
1072	vmvn	q5, q5
1073	vmvn	q6, q6
1074#ifdef __ARMEL__
1075	vrev32.8	q15, q15
1076#endif
1077	subs	r5,r5,#1
1078	vstmia	r12!,{q0,q1,q2,q3,q4,q5,q6,q7}		@ write bit-sliced round key
1079	bne	.Lkey_loop
1080
1081	vmov.i8	q7,#0x63			@ compose .L63
1082	@ don't save last round key
1083	bx	lr
1084.size	_bsaes_key_convert,.-_bsaes_key_convert
1085.globl	bsaes_cbc_encrypt
1086.hidden	bsaes_cbc_encrypt
1087.type	bsaes_cbc_encrypt,%function
1088.align	5
1089bsaes_cbc_encrypt:
1090	@ In OpenSSL, this function had a fallback to aes_nohw_cbc_encrypt for
1091	@ short inputs. We patch this out, using bsaes for all input sizes.
1092
1093	@ it is up to the caller to make sure we are called with enc == 0
1094
1095	mov	ip, sp
1096	stmdb	sp!, {r4,r5,r6,r7,r8,r9,r10, lr}
1097	VFP_ABI_PUSH
1098	ldr	r8, [ip]			@ IV is 1st arg on the stack
1099	mov	r2, r2, lsr#4		@ len in 16 byte blocks
1100	sub	sp, #0x10			@ scratch space to carry over the IV
1101	mov	r9, sp				@ save sp
1102
1103	ldr	r10, [r3, #240]		@ get # of rounds
1104#ifndef	BSAES_ASM_EXTENDED_KEY
1105	@ allocate the key schedule on the stack
1106	sub	r12, sp, r10, lsl#7		@ 128 bytes per inner round key
1107	add	r12, #96			@ sifze of bit-slices key schedule
1108
1109	@ populate the key schedule
1110	mov	r4, r3			@ pass key
1111	mov	r5, r10			@ pass # of rounds
1112	mov	sp, r12				@ sp is sp
1113	bl	_bsaes_key_convert
1114	vldmia	sp, {q6}
1115	vstmia	r12,  {q15}		@ save last round key
1116	veor	q7, q7, q6	@ fix up round 0 key
1117	vstmia	sp, {q7}
1118#else
1119	ldr	r12, [r3, #244]
1120	eors	r12, #1
1121	beq	0f
1122
1123	@ populate the key schedule
1124	str	r12, [r3, #244]
1125	mov	r4, r3			@ pass key
1126	mov	r5, r10			@ pass # of rounds
1127	add	r12, r3, #248			@ pass key schedule
1128	bl	_bsaes_key_convert
1129	add	r4, r3, #248
1130	vldmia	r4, {q6}
1131	vstmia	r12, {q15}			@ save last round key
1132	veor	q7, q7, q6	@ fix up round 0 key
1133	vstmia	r4, {q7}
1134
1135.align	2
1136
1137#endif
1138
1139	vld1.8	{q15}, [r8]		@ load IV
1140	b	.Lcbc_dec_loop
1141
1142.align	4
1143.Lcbc_dec_loop:
1144	subs	r2, r2, #0x8
1145	bmi	.Lcbc_dec_loop_finish
1146
1147	vld1.8	{q0,q1}, [r0]!	@ load input
1148	vld1.8	{q2,q3}, [r0]!
1149#ifndef	BSAES_ASM_EXTENDED_KEY
1150	mov	r4, sp			@ pass the key
1151#else
1152	add	r4, r3, #248
1153#endif
1154	vld1.8	{q4,q5}, [r0]!
1155	mov	r5, r10
1156	vld1.8	{q6,q7}, [r0]
1157	sub	r0, r0, #0x60
1158	vstmia	r9, {q15}			@ put aside IV
1159
1160	bl	_bsaes_decrypt8
1161
1162	vldmia	r9, {q14}			@ reload IV
1163	vld1.8	{q8,q9}, [r0]!	@ reload input
1164	veor	q0, q0, q14	@ ^= IV
1165	vld1.8	{q10,q11}, [r0]!
1166	veor	q1, q1, q8
1167	veor	q6, q6, q9
1168	vld1.8	{q12,q13}, [r0]!
1169	veor	q4, q4, q10
1170	veor	q2, q2, q11
1171	vld1.8	{q14,q15}, [r0]!
1172	veor	q7, q7, q12
1173	vst1.8	{q0,q1}, [r1]!	@ write output
1174	veor	q3, q3, q13
1175	vst1.8	{q6}, [r1]!
1176	veor	q5, q5, q14
1177	vst1.8	{q4}, [r1]!
1178	vst1.8	{q2}, [r1]!
1179	vst1.8	{q7}, [r1]!
1180	vst1.8	{q3}, [r1]!
1181	vst1.8	{q5}, [r1]!
1182
1183	b	.Lcbc_dec_loop
1184
1185.Lcbc_dec_loop_finish:
1186	adds	r2, r2, #8
1187	beq	.Lcbc_dec_done
1188
1189	@ Set up most parameters for the _bsaes_decrypt8 call.
1190#ifndef	BSAES_ASM_EXTENDED_KEY
1191	mov	r4, sp			@ pass the key
1192#else
1193	add	r4, r3, #248
1194#endif
1195	mov	r5, r10
1196	vstmia	r9, {q15}			@ put aside IV
1197
1198	vld1.8	{q0}, [r0]!		@ load input
1199	cmp	r2, #2
1200	blo	.Lcbc_dec_one
1201	vld1.8	{q1}, [r0]!
1202	beq	.Lcbc_dec_two
1203	vld1.8	{q2}, [r0]!
1204	cmp	r2, #4
1205	blo	.Lcbc_dec_three
1206	vld1.8	{q3}, [r0]!
1207	beq	.Lcbc_dec_four
1208	vld1.8	{q4}, [r0]!
1209	cmp	r2, #6
1210	blo	.Lcbc_dec_five
1211	vld1.8	{q5}, [r0]!
1212	beq	.Lcbc_dec_six
1213	vld1.8	{q6}, [r0]!
1214	sub	r0, r0, #0x70
1215
1216	bl	_bsaes_decrypt8
1217
1218	vldmia	r9, {q14}			@ reload IV
1219	vld1.8	{q8,q9}, [r0]!	@ reload input
1220	veor	q0, q0, q14	@ ^= IV
1221	vld1.8	{q10,q11}, [r0]!
1222	veor	q1, q1, q8
1223	veor	q6, q6, q9
1224	vld1.8	{q12,q13}, [r0]!
1225	veor	q4, q4, q10
1226	veor	q2, q2, q11
1227	vld1.8	{q15}, [r0]!
1228	veor	q7, q7, q12
1229	vst1.8	{q0,q1}, [r1]!	@ write output
1230	veor	q3, q3, q13
1231	vst1.8	{q6}, [r1]!
1232	vst1.8	{q4}, [r1]!
1233	vst1.8	{q2}, [r1]!
1234	vst1.8	{q7}, [r1]!
1235	vst1.8	{q3}, [r1]!
1236	b	.Lcbc_dec_done
1237.align	4
1238.Lcbc_dec_six:
1239	sub	r0, r0, #0x60
1240	bl	_bsaes_decrypt8
1241	vldmia	r9,{q14}			@ reload IV
1242	vld1.8	{q8,q9}, [r0]!	@ reload input
1243	veor	q0, q0, q14	@ ^= IV
1244	vld1.8	{q10,q11}, [r0]!
1245	veor	q1, q1, q8
1246	veor	q6, q6, q9
1247	vld1.8	{q12}, [r0]!
1248	veor	q4, q4, q10
1249	veor	q2, q2, q11
1250	vld1.8	{q15}, [r0]!
1251	veor	q7, q7, q12
1252	vst1.8	{q0,q1}, [r1]!	@ write output
1253	vst1.8	{q6}, [r1]!
1254	vst1.8	{q4}, [r1]!
1255	vst1.8	{q2}, [r1]!
1256	vst1.8	{q7}, [r1]!
1257	b	.Lcbc_dec_done
1258.align	4
1259.Lcbc_dec_five:
1260	sub	r0, r0, #0x50
1261	bl	_bsaes_decrypt8
1262	vldmia	r9, {q14}			@ reload IV
1263	vld1.8	{q8,q9}, [r0]!	@ reload input
1264	veor	q0, q0, q14	@ ^= IV
1265	vld1.8	{q10,q11}, [r0]!
1266	veor	q1, q1, q8
1267	veor	q6, q6, q9
1268	vld1.8	{q15}, [r0]!
1269	veor	q4, q4, q10
1270	vst1.8	{q0,q1}, [r1]!	@ write output
1271	veor	q2, q2, q11
1272	vst1.8	{q6}, [r1]!
1273	vst1.8	{q4}, [r1]!
1274	vst1.8	{q2}, [r1]!
1275	b	.Lcbc_dec_done
1276.align	4
1277.Lcbc_dec_four:
1278	sub	r0, r0, #0x40
1279	bl	_bsaes_decrypt8
1280	vldmia	r9, {q14}			@ reload IV
1281	vld1.8	{q8,q9}, [r0]!	@ reload input
1282	veor	q0, q0, q14	@ ^= IV
1283	vld1.8	{q10}, [r0]!
1284	veor	q1, q1, q8
1285	veor	q6, q6, q9
1286	vld1.8	{q15}, [r0]!
1287	veor	q4, q4, q10
1288	vst1.8	{q0,q1}, [r1]!	@ write output
1289	vst1.8	{q6}, [r1]!
1290	vst1.8	{q4}, [r1]!
1291	b	.Lcbc_dec_done
1292.align	4
1293.Lcbc_dec_three:
1294	sub	r0, r0, #0x30
1295	bl	_bsaes_decrypt8
1296	vldmia	r9, {q14}			@ reload IV
1297	vld1.8	{q8,q9}, [r0]!	@ reload input
1298	veor	q0, q0, q14	@ ^= IV
1299	vld1.8	{q15}, [r0]!
1300	veor	q1, q1, q8
1301	veor	q6, q6, q9
1302	vst1.8	{q0,q1}, [r1]!	@ write output
1303	vst1.8	{q6}, [r1]!
1304	b	.Lcbc_dec_done
1305.align	4
1306.Lcbc_dec_two:
1307	sub	r0, r0, #0x20
1308	bl	_bsaes_decrypt8
1309	vldmia	r9, {q14}			@ reload IV
1310	vld1.8	{q8}, [r0]!		@ reload input
1311	veor	q0, q0, q14	@ ^= IV
1312	vld1.8	{q15}, [r0]!		@ reload input
1313	veor	q1, q1, q8
1314	vst1.8	{q0,q1}, [r1]!	@ write output
1315	b	.Lcbc_dec_done
1316.align	4
1317.Lcbc_dec_one:
1318	sub	r0, r0, #0x10
1319	bl	_bsaes_decrypt8
1320	vldmia	r9, {q14}			@ reload IV
1321	vld1.8	{q15}, [r0]!		@ reload input
1322	veor	q0, q0, q14	@ ^= IV
1323	vst1.8	{q0}, [r1]!		@ write output
1324
1325.Lcbc_dec_done:
1326#ifndef	BSAES_ASM_EXTENDED_KEY
1327	vmov.i32	q0, #0
1328	vmov.i32	q1, #0
1329.Lcbc_dec_bzero:@ wipe key schedule [if any]
1330	vstmia	sp!, {q0,q1}
1331	cmp	sp, r9
1332	bne	.Lcbc_dec_bzero
1333#endif
1334
1335	mov	sp, r9
1336	add	sp, #0x10			@ add sp,r9,#0x10 is no good for thumb
1337	vst1.8	{q15}, [r8]		@ return IV
1338	VFP_ABI_POP
1339	ldmia	sp!, {r4,r5,r6,r7,r8,r9,r10, pc}
1340.size	bsaes_cbc_encrypt,.-bsaes_cbc_encrypt
1341.globl	bsaes_ctr32_encrypt_blocks
1342.hidden	bsaes_ctr32_encrypt_blocks
1343.type	bsaes_ctr32_encrypt_blocks,%function
1344.align	5
1345bsaes_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
1409.Lctr_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
1473.Lctr_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
1506.Lctr_enc_done:
1507	vmov.i32	q0, #0
1508	vmov.i32	q1, #0
1509#ifndef	BSAES_ASM_EXTENDED_KEY
1510.Lctr_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.size	bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks
1526#endif
1527#endif
1528#endif  // !OPENSSL_NO_ASM
1529.section	.note.GNU-stack,"",%progbits
1530