1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Bit sliced AES using NEON instructions
4 *
5 * Copyright (C) 2017 Linaro Ltd.
6 * Author: Ard Biesheuvel <ard.biesheuvel@linaro.org>
7 */
8
9/*
10 * The algorithm implemented here is described in detail by the paper
11 * 'Faster and Timing-Attack Resistant AES-GCM' by Emilia Kaesper and
12 * Peter Schwabe (https://eprint.iacr.org/2009/129.pdf)
13 *
14 * This implementation is based primarily on the OpenSSL implementation
15 * for 32-bit ARM written by Andy Polyakov <appro@openssl.org>
16 */
17
18#include <linux/linkage.h>
19#include <asm/assembler.h>
20
21	.text
22	.fpu		neon
23
24	rounds		.req	ip
25	bskey		.req	r4
26
27	q0l		.req	d0
28	q0h		.req	d1
29	q1l		.req	d2
30	q1h		.req	d3
31	q2l		.req	d4
32	q2h		.req	d5
33	q3l		.req	d6
34	q3h		.req	d7
35	q4l		.req	d8
36	q4h		.req	d9
37	q5l		.req	d10
38	q5h		.req	d11
39	q6l		.req	d12
40	q6h		.req	d13
41	q7l		.req	d14
42	q7h		.req	d15
43	q8l		.req	d16
44	q8h		.req	d17
45	q9l		.req	d18
46	q9h		.req	d19
47	q10l		.req	d20
48	q10h		.req	d21
49	q11l		.req	d22
50	q11h		.req	d23
51	q12l		.req	d24
52	q12h		.req	d25
53	q13l		.req	d26
54	q13h		.req	d27
55	q14l		.req	d28
56	q14h		.req	d29
57	q15l		.req	d30
58	q15h		.req	d31
59
60	.macro		__tbl, out, tbl, in, tmp
61	.ifc		\out, \tbl
62	.ifb		\tmp
63	.error		__tbl needs temp register if out == tbl
64	.endif
65	vmov		\tmp, \out
66	.endif
67	vtbl.8		\out\()l, {\tbl}, \in\()l
68	.ifc		\out, \tbl
69	vtbl.8		\out\()h, {\tmp}, \in\()h
70	.else
71	vtbl.8		\out\()h, {\tbl}, \in\()h
72	.endif
73	.endm
74
75	.macro		__ldr, out, sym
76	vldr		\out\()l, \sym
77	vldr		\out\()h, \sym + 8
78	.endm
79
80	.macro		in_bs_ch, b0, b1, b2, b3, b4, b5, b6, b7
81	veor		\b2, \b2, \b1
82	veor		\b5, \b5, \b6
83	veor		\b3, \b3, \b0
84	veor		\b6, \b6, \b2
85	veor		\b5, \b5, \b0
86	veor		\b6, \b6, \b3
87	veor		\b3, \b3, \b7
88	veor		\b7, \b7, \b5
89	veor		\b3, \b3, \b4
90	veor		\b4, \b4, \b5
91	veor		\b2, \b2, \b7
92	veor		\b3, \b3, \b1
93	veor		\b1, \b1, \b5
94	.endm
95
96	.macro		out_bs_ch, b0, b1, b2, b3, b4, b5, b6, b7
97	veor		\b0, \b0, \b6
98	veor		\b1, \b1, \b4
99	veor		\b4, \b4, \b6
100	veor		\b2, \b2, \b0
101	veor		\b6, \b6, \b1
102	veor		\b1, \b1, \b5
103	veor		\b5, \b5, \b3
104	veor		\b3, \b3, \b7
105	veor		\b7, \b7, \b5
106	veor		\b2, \b2, \b5
107	veor		\b4, \b4, \b7
108	.endm
109
110	.macro		inv_in_bs_ch, b6, b1, b2, b4, b7, b0, b3, b5
111	veor		\b1, \b1, \b7
112	veor		\b4, \b4, \b7
113	veor		\b7, \b7, \b5
114	veor		\b1, \b1, \b3
115	veor		\b2, \b2, \b5
116	veor		\b3, \b3, \b7
117	veor		\b6, \b6, \b1
118	veor		\b2, \b2, \b0
119	veor		\b5, \b5, \b3
120	veor		\b4, \b4, \b6
121	veor		\b0, \b0, \b6
122	veor		\b1, \b1, \b4
123	.endm
124
125	.macro		inv_out_bs_ch, b6, b5, b0, b3, b7, b1, b4, b2
126	veor		\b1, \b1, \b5
127	veor		\b2, \b2, \b7
128	veor		\b3, \b3, \b1
129	veor		\b4, \b4, \b5
130	veor		\b7, \b7, \b5
131	veor		\b3, \b3, \b4
132	veor 		\b5, \b5, \b0
133	veor		\b3, \b3, \b7
134	veor		\b6, \b6, \b2
135	veor		\b2, \b2, \b1
136	veor		\b6, \b6, \b3
137	veor		\b3, \b3, \b0
138	veor		\b5, \b5, \b6
139	.endm
140
141	.macro		mul_gf4, x0, x1, y0, y1, t0, t1
142	veor 		\t0, \y0, \y1
143	vand		\t0, \t0, \x0
144	veor		\x0, \x0, \x1
145	vand		\t1, \x1, \y0
146	vand		\x0, \x0, \y1
147	veor		\x1, \t1, \t0
148	veor		\x0, \x0, \t1
149	.endm
150
151	.macro		mul_gf4_n_gf4, x0, x1, y0, y1, t0, x2, x3, y2, y3, t1
152	veor		\t0, \y0, \y1
153	veor 		\t1, \y2, \y3
154	vand		\t0, \t0, \x0
155	vand		\t1, \t1, \x2
156	veor		\x0, \x0, \x1
157	veor		\x2, \x2, \x3
158	vand		\x1, \x1, \y0
159	vand		\x3, \x3, \y2
160	vand		\x0, \x0, \y1
161	vand		\x2, \x2, \y3
162	veor		\x1, \x1, \x0
163	veor		\x2, \x2, \x3
164	veor		\x0, \x0, \t0
165	veor		\x3, \x3, \t1
166	.endm
167
168	.macro		mul_gf16_2, x0, x1, x2, x3, x4, x5, x6, x7, \
169				    y0, y1, y2, y3, t0, t1, t2, t3
170	veor		\t0, \x0, \x2
171	veor		\t1, \x1, \x3
172	mul_gf4  	\x0, \x1, \y0, \y1, \t2, \t3
173	veor		\y0, \y0, \y2
174	veor		\y1, \y1, \y3
175	mul_gf4_n_gf4	\t0, \t1, \y0, \y1, \t3, \x2, \x3, \y2, \y3, \t2
176	veor		\x0, \x0, \t0
177	veor		\x2, \x2, \t0
178	veor		\x1, \x1, \t1
179	veor		\x3, \x3, \t1
180	veor		\t0, \x4, \x6
181	veor		\t1, \x5, \x7
182	mul_gf4_n_gf4	\t0, \t1, \y0, \y1, \t3, \x6, \x7, \y2, \y3, \t2
183	veor		\y0, \y0, \y2
184	veor		\y1, \y1, \y3
185	mul_gf4  	\x4, \x5, \y0, \y1, \t2, \t3
186	veor		\x4, \x4, \t0
187	veor		\x6, \x6, \t0
188	veor		\x5, \x5, \t1
189	veor		\x7, \x7, \t1
190	.endm
191
192	.macro		inv_gf256, x0, x1, x2, x3, x4, x5, x6, x7, \
193				   t0, t1, t2, t3, s0, s1, s2, s3
194	veor		\t3, \x4, \x6
195	veor		\t0, \x5, \x7
196	veor		\t1, \x1, \x3
197	veor		\s1, \x7, \x6
198	veor		\s0, \x0, \x2
199	veor		\s3, \t3, \t0
200	vorr		\t2, \t0, \t1
201	vand		\s2, \t3, \s0
202	vorr		\t3, \t3, \s0
203	veor		\s0, \s0, \t1
204	vand		\t0, \t0, \t1
205	veor		\t1, \x3, \x2
206	vand		\s3, \s3, \s0
207	vand		\s1, \s1, \t1
208	veor		\t1, \x4, \x5
209	veor		\s0, \x1, \x0
210	veor		\t3, \t3, \s1
211	veor		\t2, \t2, \s1
212	vand		\s1, \t1, \s0
213	vorr		\t1, \t1, \s0
214	veor		\t3, \t3, \s3
215	veor		\t0, \t0, \s1
216	veor		\t2, \t2, \s2
217	veor		\t1, \t1, \s3
218	veor		\t0, \t0, \s2
219	vand		\s0, \x7, \x3
220	veor		\t1, \t1, \s2
221	vand		\s1, \x6, \x2
222	vand		\s2, \x5, \x1
223	vorr		\s3, \x4, \x0
224	veor		\t3, \t3, \s0
225	veor		\t1, \t1, \s2
226	veor		\s0, \t0, \s3
227	veor		\t2, \t2, \s1
228	vand		\s2, \t3, \t1
229	veor		\s1, \t2, \s2
230	veor		\s3, \s0, \s2
231	vbsl		\s1, \t1, \s0
232	vmvn		\t0, \s0
233	vbsl		\s0, \s1, \s3
234	vbsl		\t0, \s1, \s3
235	vbsl		\s3, \t3, \t2
236	veor		\t3, \t3, \t2
237	vand		\s2, \s0, \s3
238	veor		\t1, \t1, \t0
239	veor		\s2, \s2, \t3
240	mul_gf16_2	\x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \
241			\s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3
242	.endm
243
244	.macro		sbox, b0, b1, b2, b3, b4, b5, b6, b7, \
245			      t0, t1, t2, t3, s0, s1, s2, s3
246	in_bs_ch	\b0, \b1, \b2, \b3, \b4, \b5, \b6, \b7
247	inv_gf256	\b6, \b5, \b0, \b3, \b7, \b1, \b4, \b2, \
248			\t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
249	out_bs_ch	\b7, \b1, \b4, \b2, \b6, \b5, \b0, \b3
250	.endm
251
252	.macro		inv_sbox, b0, b1, b2, b3, b4, b5, b6, b7, \
253				  t0, t1, t2, t3, s0, s1, s2, s3
254	inv_in_bs_ch	\b0, \b1, \b2, \b3, \b4, \b5, \b6, \b7
255	inv_gf256	\b5, \b1, \b2, \b6, \b3, \b7, \b0, \b4, \
256			\t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3
257	inv_out_bs_ch	\b3, \b7, \b0, \b4, \b5, \b1, \b2, \b6
258	.endm
259
260	.macro		shift_rows, x0, x1, x2, x3, x4, x5, x6, x7, \
261				    t0, t1, t2, t3, mask
262	vld1.8		{\t0-\t1}, [bskey, :256]!
263	veor		\t0, \t0, \x0
264	vld1.8		{\t2-\t3}, [bskey, :256]!
265	veor		\t1, \t1, \x1
266	__tbl		\x0, \t0, \mask
267	veor		\t2, \t2, \x2
268	__tbl		\x1, \t1, \mask
269	vld1.8		{\t0-\t1}, [bskey, :256]!
270	veor		\t3, \t3, \x3
271	__tbl		\x2, \t2, \mask
272	__tbl		\x3, \t3, \mask
273	vld1.8		{\t2-\t3}, [bskey, :256]!
274	veor		\t0, \t0, \x4
275	veor		\t1, \t1, \x5
276	__tbl		\x4, \t0, \mask
277	veor		\t2, \t2, \x6
278	__tbl		\x5, \t1, \mask
279	veor		\t3, \t3, \x7
280	__tbl		\x6, \t2, \mask
281	__tbl		\x7, \t3, \mask
282	.endm
283
284	.macro		inv_shift_rows, x0, x1, x2, x3, x4, x5, x6, x7, \
285					t0, t1, t2, t3, mask
286	__tbl		\x0, \x0, \mask, \t0
287	__tbl		\x1, \x1, \mask, \t1
288	__tbl		\x2, \x2, \mask, \t2
289	__tbl		\x3, \x3, \mask, \t3
290	__tbl		\x4, \x4, \mask, \t0
291	__tbl		\x5, \x5, \mask, \t1
292	__tbl		\x6, \x6, \mask, \t2
293	__tbl		\x7, \x7, \mask, \t3
294	.endm
295
296	.macro		mix_cols, x0, x1, x2, x3, x4, x5, x6, x7, \
297				  t0, t1, t2, t3, t4, t5, t6, t7, inv
298	vext.8		\t0, \x0, \x0, #12
299	vext.8		\t1, \x1, \x1, #12
300	veor		\x0, \x0, \t0
301	vext.8		\t2, \x2, \x2, #12
302	veor		\x1, \x1, \t1
303	vext.8		\t3, \x3, \x3, #12
304	veor		\x2, \x2, \t2
305	vext.8		\t4, \x4, \x4, #12
306	veor		\x3, \x3, \t3
307	vext.8		\t5, \x5, \x5, #12
308	veor		\x4, \x4, \t4
309	vext.8		\t6, \x6, \x6, #12
310	veor		\x5, \x5, \t5
311	vext.8		\t7, \x7, \x7, #12
312	veor		\x6, \x6, \t6
313	veor		\t1, \t1, \x0
314	veor.8		\x7, \x7, \t7
315	vext.8		\x0, \x0, \x0, #8
316	veor		\t2, \t2, \x1
317	veor		\t0, \t0, \x7
318	veor		\t1, \t1, \x7
319	vext.8		\x1, \x1, \x1, #8
320	veor		\t5, \t5, \x4
321	veor		\x0, \x0, \t0
322	veor		\t6, \t6, \x5
323	veor		\x1, \x1, \t1
324	vext.8		\t0, \x4, \x4, #8
325	veor		\t4, \t4, \x3
326	vext.8		\t1, \x5, \x5, #8
327	veor		\t7, \t7, \x6
328	vext.8		\x4, \x3, \x3, #8
329	veor		\t3, \t3, \x2
330	vext.8		\x5, \x7, \x7, #8
331	veor		\t4, \t4, \x7
332	vext.8		\x3, \x6, \x6, #8
333	veor		\t3, \t3, \x7
334	vext.8		\x6, \x2, \x2, #8
335	veor		\x7, \t1, \t5
336	.ifb		\inv
337	veor		\x2, \t0, \t4
338	veor		\x4, \x4, \t3
339	veor		\x5, \x5, \t7
340	veor		\x3, \x3, \t6
341	veor		\x6, \x6, \t2
342	.else
343	veor		\t3, \t3, \x4
344	veor		\x5, \x5, \t7
345	veor		\x2, \x3, \t6
346	veor		\x3, \t0, \t4
347	veor		\x4, \x6, \t2
348	vmov		\x6, \t3
349	.endif
350	.endm
351
352	.macro		inv_mix_cols, x0, x1, x2, x3, x4, x5, x6, x7, \
353				      t0, t1, t2, t3, t4, t5, t6, t7
354	vld1.8		{\t0-\t1}, [bskey, :256]!
355	veor		\x0, \x0, \t0
356	vld1.8		{\t2-\t3}, [bskey, :256]!
357	veor		\x1, \x1, \t1
358	vld1.8		{\t4-\t5}, [bskey, :256]!
359	veor		\x2, \x2, \t2
360	vld1.8		{\t6-\t7}, [bskey, :256]
361	sub		bskey, bskey, #224
362	veor		\x3, \x3, \t3
363	veor		\x4, \x4, \t4
364	veor		\x5, \x5, \t5
365	veor		\x6, \x6, \t6
366	veor		\x7, \x7, \t7
367	vext.8		\t0, \x0, \x0, #8
368	vext.8		\t6, \x6, \x6, #8
369	vext.8		\t7, \x7, \x7, #8
370	veor		\t0, \t0, \x0
371	vext.8		\t1, \x1, \x1, #8
372	veor		\t6, \t6, \x6
373	vext.8		\t2, \x2, \x2, #8
374	veor		\t7, \t7, \x7
375	vext.8		\t3, \x3, \x3, #8
376	veor		\t1, \t1, \x1
377	vext.8		\t4, \x4, \x4, #8
378	veor		\t2, \t2, \x2
379	vext.8		\t5, \x5, \x5, #8
380	veor		\t3, \t3, \x3
381	veor		\t4, \t4, \x4
382	veor		\t5, \t5, \x5
383	veor		\x0, \x0, \t6
384	veor		\x1, \x1, \t6
385	veor		\x2, \x2, \t0
386	veor		\x4, \x4, \t2
387	veor		\x3, \x3, \t1
388	veor		\x1, \x1, \t7
389	veor		\x2, \x2, \t7
390	veor		\x4, \x4, \t6
391	veor		\x5, \x5, \t3
392	veor		\x3, \x3, \t6
393	veor		\x6, \x6, \t4
394	veor		\x4, \x4, \t7
395	veor		\x5, \x5, \t7
396	veor		\x7, \x7, \t5
397	mix_cols	\x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \
398			\t0, \t1, \t2, \t3, \t4, \t5, \t6, \t7, 1
399	.endm
400
401	.macro		swapmove_2x, a0, b0, a1, b1, n, mask, t0, t1
402	vshr.u64	\t0, \b0, #\n
403	vshr.u64	\t1, \b1, #\n
404	veor		\t0, \t0, \a0
405	veor		\t1, \t1, \a1
406	vand		\t0, \t0, \mask
407	vand		\t1, \t1, \mask
408	veor		\a0, \a0, \t0
409	vshl.s64	\t0, \t0, #\n
410	veor		\a1, \a1, \t1
411	vshl.s64	\t1, \t1, #\n
412	veor		\b0, \b0, \t0
413	veor		\b1, \b1, \t1
414	.endm
415
416	.macro		bitslice, x7, x6, x5, x4, x3, x2, x1, x0, t0, t1, t2, t3
417	vmov.i8		\t0, #0x55
418	vmov.i8		\t1, #0x33
419	swapmove_2x	\x0, \x1, \x2, \x3, 1, \t0, \t2, \t3
420	swapmove_2x	\x4, \x5, \x6, \x7, 1, \t0, \t2, \t3
421	vmov.i8		\t0, #0x0f
422	swapmove_2x	\x0, \x2, \x1, \x3, 2, \t1, \t2, \t3
423	swapmove_2x	\x4, \x6, \x5, \x7, 2, \t1, \t2, \t3
424	swapmove_2x	\x0, \x4, \x1, \x5, 4, \t0, \t2, \t3
425	swapmove_2x	\x2, \x6, \x3, \x7, 4, \t0, \t2, \t3
426	.endm
427
428	.align		4
429M0:	.quad		0x02060a0e03070b0f, 0x0004080c0105090d
430
431	/*
432	 * void aesbs_convert_key(u8 out[], u32 const rk[], int rounds)
433	 */
434ENTRY(aesbs_convert_key)
435	vld1.32		{q7}, [r1]!		// load round 0 key
436	vld1.32		{q15}, [r1]!		// load round 1 key
437
438	vmov.i8		q8,  #0x01		// bit masks
439	vmov.i8		q9,  #0x02
440	vmov.i8		q10, #0x04
441	vmov.i8		q11, #0x08
442	vmov.i8		q12, #0x10
443	vmov.i8		q13, #0x20
444	__ldr		q14, M0
445
446	sub		r2, r2, #1
447	vst1.8		{q7}, [r0, :128]!	// save round 0 key
448
449.Lkey_loop:
450	__tbl		q7, q15, q14
451	vmov.i8		q6, #0x40
452	vmov.i8		q15, #0x80
453
454	vtst.8		q0, q7, q8
455	vtst.8		q1, q7, q9
456	vtst.8		q2, q7, q10
457	vtst.8		q3, q7, q11
458	vtst.8		q4, q7, q12
459	vtst.8		q5, q7, q13
460	vtst.8		q6, q7, q6
461	vtst.8		q7, q7, q15
462	vld1.32		{q15}, [r1]!		// load next round key
463	vmvn		q0, q0
464	vmvn		q1, q1
465	vmvn		q5, q5
466	vmvn		q6, q6
467
468	subs		r2, r2, #1
469	vst1.8		{q0-q1}, [r0, :256]!
470	vst1.8		{q2-q3}, [r0, :256]!
471	vst1.8		{q4-q5}, [r0, :256]!
472	vst1.8		{q6-q7}, [r0, :256]!
473	bne		.Lkey_loop
474
475	vmov.i8		q7, #0x63		// compose .L63
476	veor		q15, q15, q7
477	vst1.8		{q15}, [r0, :128]
478	bx		lr
479ENDPROC(aesbs_convert_key)
480
481	.align		4
482M0SR:	.quad		0x0a0e02060f03070b, 0x0004080c05090d01
483
484aesbs_encrypt8:
485	vld1.8		{q9}, [bskey, :128]!	// round 0 key
486	__ldr		q8, M0SR
487
488	veor		q10, q0, q9		// xor with round0 key
489	veor		q11, q1, q9
490	__tbl		q0, q10, q8
491	veor		q12, q2, q9
492	__tbl		q1, q11, q8
493	veor		q13, q3, q9
494	__tbl		q2, q12, q8
495	veor		q14, q4, q9
496	__tbl		q3, q13, q8
497	veor		q15, q5, q9
498	__tbl		q4, q14, q8
499	veor		q10, q6, q9
500	__tbl		q5, q15, q8
501	veor		q11, q7, q9
502	__tbl		q6, q10, q8
503	__tbl		q7, q11, q8
504
505	bitslice	q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11
506
507	sub		rounds, rounds, #1
508	b		.Lenc_sbox
509
510	.align		5
511SR:	.quad		0x0504070600030201, 0x0f0e0d0c0a09080b
512SRM0:	.quad		0x0304090e00050a0f, 0x01060b0c0207080d
513
514.Lenc_last:
515	__ldr		q12, SRM0
516.Lenc_loop:
517	shift_rows	q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12
518.Lenc_sbox:
519	sbox		q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, \
520								q13, q14, q15
521	subs		rounds, rounds, #1
522	bcc		.Lenc_done
523
524	mix_cols	q0, q1, q4, q6, q3, q7, q2, q5, q8, q9, q10, q11, q12, \
525								q13, q14, q15
526
527	beq		.Lenc_last
528	__ldr		q12, SR
529	b		.Lenc_loop
530
531.Lenc_done:
532	vld1.8		{q12}, [bskey, :128]	// last round key
533
534	bitslice	q0, q1, q4, q6, q3, q7, q2, q5, q8, q9, q10, q11
535
536	veor		q0, q0, q12
537	veor		q1, q1, q12
538	veor		q4, q4, q12
539	veor		q6, q6, q12
540	veor		q3, q3, q12
541	veor		q7, q7, q12
542	veor		q2, q2, q12
543	veor		q5, q5, q12
544	bx		lr
545ENDPROC(aesbs_encrypt8)
546
547	.align		4
548M0ISR:	.quad		0x0a0e0206070b0f03, 0x0004080c0d010509
549
550aesbs_decrypt8:
551	add		bskey, bskey, rounds, lsl #7
552	sub		bskey, bskey, #112
553	vld1.8		{q9}, [bskey, :128]	// round 0 key
554	sub		bskey, bskey, #128
555	__ldr		q8, M0ISR
556
557	veor		q10, q0, q9		// xor with round0 key
558	veor		q11, q1, q9
559	__tbl		q0, q10, q8
560	veor		q12, q2, q9
561	__tbl		q1, q11, q8
562	veor		q13, q3, q9
563	__tbl		q2, q12, q8
564	veor		q14, q4, q9
565	__tbl		q3, q13, q8
566	veor		q15, q5, q9
567	__tbl		q4, q14, q8
568	veor		q10, q6, q9
569	__tbl		q5, q15, q8
570	veor		q11, q7, q9
571	__tbl		q6, q10, q8
572	__tbl		q7, q11, q8
573
574	bitslice	q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11
575
576	sub		rounds, rounds, #1
577	b		.Ldec_sbox
578
579	.align		5
580ISR:	.quad		0x0504070602010003, 0x0f0e0d0c080b0a09
581ISRM0:	.quad		0x01040b0e0205080f, 0x0306090c00070a0d
582
583.Ldec_last:
584	__ldr		q12, ISRM0
585.Ldec_loop:
586	inv_shift_rows	q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12
587.Ldec_sbox:
588	inv_sbox	q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, \
589								q13, q14, q15
590	subs		rounds, rounds, #1
591	bcc		.Ldec_done
592
593	inv_mix_cols	q0, q1, q6, q4, q2, q7, q3, q5, q8, q9, q10, q11, q12, \
594								q13, q14, q15
595
596	beq		.Ldec_last
597	__ldr		q12, ISR
598	b		.Ldec_loop
599
600.Ldec_done:
601	add		bskey, bskey, #112
602	vld1.8		{q12}, [bskey, :128]	// last round key
603
604	bitslice	q0, q1, q6, q4, q2, q7, q3, q5, q8, q9, q10, q11
605
606	veor		q0, q0, q12
607	veor		q1, q1, q12
608	veor		q6, q6, q12
609	veor		q4, q4, q12
610	veor		q2, q2, q12
611	veor		q7, q7, q12
612	veor		q3, q3, q12
613	veor		q5, q5, q12
614	bx		lr
615ENDPROC(aesbs_decrypt8)
616
617	/*
618	 * aesbs_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
619	 *		     int blocks)
620	 * aesbs_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
621	 *		     int blocks)
622	 */
623	.macro		__ecb_crypt, do8, o0, o1, o2, o3, o4, o5, o6, o7
624	push		{r4-r6, lr}
625	ldr		r5, [sp, #16]		// number of blocks
626
62799:	adr		ip, 0f
628	and		lr, r5, #7
629	cmp		r5, #8
630	sub		ip, ip, lr, lsl #2
631	movlt		pc, ip			// computed goto if blocks < 8
632
633	vld1.8		{q0}, [r1]!
634	vld1.8		{q1}, [r1]!
635	vld1.8		{q2}, [r1]!
636	vld1.8		{q3}, [r1]!
637	vld1.8		{q4}, [r1]!
638	vld1.8		{q5}, [r1]!
639	vld1.8		{q6}, [r1]!
640	vld1.8		{q7}, [r1]!
641
6420:	mov		bskey, r2
643	mov		rounds, r3
644	bl		\do8
645
646	adr		ip, 1f
647	and		lr, r5, #7
648	cmp		r5, #8
649	sub		ip, ip, lr, lsl #2
650	movlt		pc, ip			// computed goto if blocks < 8
651
652	vst1.8		{\o0}, [r0]!
653	vst1.8		{\o1}, [r0]!
654	vst1.8		{\o2}, [r0]!
655	vst1.8		{\o3}, [r0]!
656	vst1.8		{\o4}, [r0]!
657	vst1.8		{\o5}, [r0]!
658	vst1.8		{\o6}, [r0]!
659	vst1.8		{\o7}, [r0]!
660
6611:	subs		r5, r5, #8
662	bgt		99b
663
664	pop		{r4-r6, pc}
665	.endm
666
667	.align		4
668ENTRY(aesbs_ecb_encrypt)
669	__ecb_crypt	aesbs_encrypt8, q0, q1, q4, q6, q3, q7, q2, q5
670ENDPROC(aesbs_ecb_encrypt)
671
672	.align		4
673ENTRY(aesbs_ecb_decrypt)
674	__ecb_crypt	aesbs_decrypt8, q0, q1, q6, q4, q2, q7, q3, q5
675ENDPROC(aesbs_ecb_decrypt)
676
677	/*
678	 * aesbs_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
679	 *		     int rounds, int blocks, u8 iv[])
680	 */
681	.align		4
682ENTRY(aesbs_cbc_decrypt)
683	mov		ip, sp
684	push		{r4-r6, lr}
685	ldm		ip, {r5-r6}		// load args 4-5
686
68799:	adr		ip, 0f
688	and		lr, r5, #7
689	cmp		r5, #8
690	sub		ip, ip, lr, lsl #2
691	mov		lr, r1
692	movlt		pc, ip			// computed goto if blocks < 8
693
694	vld1.8		{q0}, [lr]!
695	vld1.8		{q1}, [lr]!
696	vld1.8		{q2}, [lr]!
697	vld1.8		{q3}, [lr]!
698	vld1.8		{q4}, [lr]!
699	vld1.8		{q5}, [lr]!
700	vld1.8		{q6}, [lr]!
701	vld1.8		{q7}, [lr]
702
7030:	mov		bskey, r2
704	mov		rounds, r3
705	bl		aesbs_decrypt8
706
707	vld1.8		{q8}, [r6]
708	vmov		q9, q8
709	vmov		q10, q8
710	vmov		q11, q8
711	vmov		q12, q8
712	vmov		q13, q8
713	vmov		q14, q8
714	vmov		q15, q8
715
716	adr		ip, 1f
717	and		lr, r5, #7
718	cmp		r5, #8
719	sub		ip, ip, lr, lsl #2
720	movlt		pc, ip			// computed goto if blocks < 8
721
722	vld1.8		{q9}, [r1]!
723	vld1.8		{q10}, [r1]!
724	vld1.8		{q11}, [r1]!
725	vld1.8		{q12}, [r1]!
726	vld1.8		{q13}, [r1]!
727	vld1.8		{q14}, [r1]!
728	vld1.8		{q15}, [r1]!
729	W(nop)
730
7311:	adr		ip, 2f
732	sub		ip, ip, lr, lsl #3
733	movlt		pc, ip			// computed goto if blocks < 8
734
735	veor		q0, q0, q8
736	vst1.8		{q0}, [r0]!
737	veor		q1, q1, q9
738	vst1.8		{q1}, [r0]!
739	veor		q6, q6, q10
740	vst1.8		{q6}, [r0]!
741	veor		q4, q4, q11
742	vst1.8		{q4}, [r0]!
743	veor		q2, q2, q12
744	vst1.8		{q2}, [r0]!
745	veor		q7, q7, q13
746	vst1.8		{q7}, [r0]!
747	veor		q3, q3, q14
748	vst1.8		{q3}, [r0]!
749	veor		q5, q5, q15
750	vld1.8		{q8}, [r1]!		// load next round's iv
7512:	vst1.8		{q5}, [r0]!
752
753	subs		r5, r5, #8
754	vst1.8		{q8}, [r6]		// store next round's iv
755	bgt		99b
756
757	pop		{r4-r6, pc}
758ENDPROC(aesbs_cbc_decrypt)
759
760	.macro		next_ctr, q
761	vmov.32		\q\()h[1], r10
762	adds		r10, r10, #1
763	vmov.32		\q\()h[0], r9
764	adcs		r9, r9, #0
765	vmov.32		\q\()l[1], r8
766	adcs		r8, r8, #0
767	vmov.32		\q\()l[0], r7
768	adc		r7, r7, #0
769	vrev32.8	\q, \q
770	.endm
771
772	/*
773	 * aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
774	 *		     int rounds, int blocks, u8 ctr[], u8 final[])
775	 */
776ENTRY(aesbs_ctr_encrypt)
777	mov		ip, sp
778	push		{r4-r10, lr}
779
780	ldm		ip, {r5-r7}		// load args 4-6
781	teq		r7, #0
782	addne		r5, r5, #1		// one extra block if final != 0
783
784	vld1.8		{q0}, [r6]		// load counter
785	vrev32.8	q1, q0
786	vmov		r9, r10, d3
787	vmov		r7, r8, d2
788
789	adds		r10, r10, #1
790	adcs		r9, r9, #0
791	adcs		r8, r8, #0
792	adc		r7, r7, #0
793
79499:	vmov		q1, q0
795	vmov		q2, q0
796	vmov		q3, q0
797	vmov		q4, q0
798	vmov		q5, q0
799	vmov		q6, q0
800	vmov		q7, q0
801
802	adr		ip, 0f
803	sub		lr, r5, #1
804	and		lr, lr, #7
805	cmp		r5, #8
806	sub		ip, ip, lr, lsl #5
807	sub		ip, ip, lr, lsl #2
808	movlt		pc, ip			// computed goto if blocks < 8
809
810	next_ctr	q1
811	next_ctr	q2
812	next_ctr	q3
813	next_ctr	q4
814	next_ctr	q5
815	next_ctr	q6
816	next_ctr	q7
817
8180:	mov		bskey, r2
819	mov		rounds, r3
820	bl		aesbs_encrypt8
821
822	adr		ip, 1f
823	and		lr, r5, #7
824	cmp		r5, #8
825	movgt		r4, #0
826	ldrle		r4, [sp, #40]		// load final in the last round
827	sub		ip, ip, lr, lsl #2
828	movlt		pc, ip			// computed goto if blocks < 8
829
830	vld1.8		{q8}, [r1]!
831	vld1.8		{q9}, [r1]!
832	vld1.8		{q10}, [r1]!
833	vld1.8		{q11}, [r1]!
834	vld1.8		{q12}, [r1]!
835	vld1.8		{q13}, [r1]!
836	vld1.8		{q14}, [r1]!
837	teq		r4, #0			// skip last block if 'final'
8381:	bne		2f
839	vld1.8		{q15}, [r1]!
840
8412:	adr		ip, 3f
842	cmp		r5, #8
843	sub		ip, ip, lr, lsl #3
844	movlt		pc, ip			// computed goto if blocks < 8
845
846	veor		q0, q0, q8
847	vst1.8		{q0}, [r0]!
848	veor		q1, q1, q9
849	vst1.8		{q1}, [r0]!
850	veor		q4, q4, q10
851	vst1.8		{q4}, [r0]!
852	veor		q6, q6, q11
853	vst1.8		{q6}, [r0]!
854	veor		q3, q3, q12
855	vst1.8		{q3}, [r0]!
856	veor		q7, q7, q13
857	vst1.8		{q7}, [r0]!
858	veor		q2, q2, q14
859	vst1.8		{q2}, [r0]!
860	teq		r4, #0			// skip last block if 'final'
861	W(bne)		5f
8623:	veor		q5, q5, q15
863	vst1.8		{q5}, [r0]!
864
8654:	next_ctr	q0
866
867	subs		r5, r5, #8
868	bgt		99b
869
870	vst1.8		{q0}, [r6]
871	pop		{r4-r10, pc}
872
8735:	vst1.8		{q5}, [r4]
874	b		4b
875ENDPROC(aesbs_ctr_encrypt)
876
877	.macro		next_tweak, out, in, const, tmp
878	vshr.s64	\tmp, \in, #63
879	vand		\tmp, \tmp, \const
880	vadd.u64	\out, \in, \in
881	vext.8		\tmp, \tmp, \tmp, #8
882	veor		\out, \out, \tmp
883	.endm
884
885	/*
886	 * aesbs_xts_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
887	 *		     int blocks, u8 iv[], int reorder_last_tweak)
888	 * aesbs_xts_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
889	 *		     int blocks, u8 iv[], int reorder_last_tweak)
890	 */
891__xts_prepare8:
892	vld1.8		{q14}, [r7]		// load iv
893	vmov.i32	d30, #0x87		// compose tweak mask vector
894	vmovl.u32	q15, d30
895	vshr.u64	d30, d31, #7
896	vmov		q12, q14
897
898	adr		ip, 0f
899	and		r4, r6, #7
900	cmp		r6, #8
901	sub		ip, ip, r4, lsl #5
902	mov		r4, sp
903	movlt		pc, ip			// computed goto if blocks < 8
904
905	vld1.8		{q0}, [r1]!
906	next_tweak	q12, q14, q15, q13
907	veor		q0, q0, q14
908	vst1.8		{q14}, [r4, :128]!
909
910	vld1.8		{q1}, [r1]!
911	next_tweak	q14, q12, q15, q13
912	veor		q1, q1, q12
913	vst1.8		{q12}, [r4, :128]!
914
915	vld1.8		{q2}, [r1]!
916	next_tweak	q12, q14, q15, q13
917	veor		q2, q2, q14
918	vst1.8		{q14}, [r4, :128]!
919
920	vld1.8		{q3}, [r1]!
921	next_tweak	q14, q12, q15, q13
922	veor		q3, q3, q12
923	vst1.8		{q12}, [r4, :128]!
924
925	vld1.8		{q4}, [r1]!
926	next_tweak	q12, q14, q15, q13
927	veor		q4, q4, q14
928	vst1.8		{q14}, [r4, :128]!
929
930	vld1.8		{q5}, [r1]!
931	next_tweak	q14, q12, q15, q13
932	veor		q5, q5, q12
933	vst1.8		{q12}, [r4, :128]!
934
935	vld1.8		{q6}, [r1]!
936	next_tweak	q12, q14, q15, q13
937	veor		q6, q6, q14
938	vst1.8		{q14}, [r4, :128]!
939
940	vld1.8		{q7}, [r1]!
941	next_tweak	q14, q12, q15, q13
942THUMB(	itt		le		)
943	W(cmple)	r8, #0
944	ble		1f
9450:	veor		q7, q7, q12
946	vst1.8		{q12}, [r4, :128]
947
948	vst1.8		{q14}, [r7]		// store next iv
949	bx		lr
950
9511:	vswp		q12, q14
952	b		0b
953ENDPROC(__xts_prepare8)
954
955	.macro		__xts_crypt, do8, o0, o1, o2, o3, o4, o5, o6, o7
956	push		{r4-r8, lr}
957	mov		r5, sp			// preserve sp
958	ldrd		r6, r7, [sp, #24]	// get blocks and iv args
959	rsb		r8, ip, #1
960	sub		ip, sp, #128		// make room for 8x tweak
961	bic		ip, ip, #0xf		// align sp to 16 bytes
962	mov		sp, ip
963
96499:	bl		__xts_prepare8
965
966	mov		bskey, r2
967	mov		rounds, r3
968	bl		\do8
969
970	adr		ip, 0f
971	and		lr, r6, #7
972	cmp		r6, #8
973	sub		ip, ip, lr, lsl #2
974	mov		r4, sp
975	movlt		pc, ip			// computed goto if blocks < 8
976
977	vld1.8		{q8}, [r4, :128]!
978	vld1.8		{q9}, [r4, :128]!
979	vld1.8		{q10}, [r4, :128]!
980	vld1.8		{q11}, [r4, :128]!
981	vld1.8		{q12}, [r4, :128]!
982	vld1.8		{q13}, [r4, :128]!
983	vld1.8		{q14}, [r4, :128]!
984	vld1.8		{q15}, [r4, :128]
985
9860:	adr		ip, 1f
987	sub		ip, ip, lr, lsl #3
988	movlt		pc, ip			// computed goto if blocks < 8
989
990	veor		\o0, \o0, q8
991	vst1.8		{\o0}, [r0]!
992	veor		\o1, \o1, q9
993	vst1.8		{\o1}, [r0]!
994	veor		\o2, \o2, q10
995	vst1.8		{\o2}, [r0]!
996	veor		\o3, \o3, q11
997	vst1.8		{\o3}, [r0]!
998	veor		\o4, \o4, q12
999	vst1.8		{\o4}, [r0]!
1000	veor		\o5, \o5, q13
1001	vst1.8		{\o5}, [r0]!
1002	veor		\o6, \o6, q14
1003	vst1.8		{\o6}, [r0]!
1004	veor		\o7, \o7, q15
1005	vst1.8		{\o7}, [r0]!
1006
10071:	subs		r6, r6, #8
1008	bgt		99b
1009
1010	mov		sp, r5
1011	pop		{r4-r8, pc}
1012	.endm
1013
1014ENTRY(aesbs_xts_encrypt)
1015	mov		ip, #0			// never reorder final tweak
1016	__xts_crypt	aesbs_encrypt8, q0, q1, q4, q6, q3, q7, q2, q5
1017ENDPROC(aesbs_xts_encrypt)
1018
1019ENTRY(aesbs_xts_decrypt)
1020	ldr		ip, [sp, #8]		// reorder final tweak?
1021	__xts_crypt	aesbs_decrypt8, q0, q1, q6, q4, q2, q7, q3, q5
1022ENDPROC(aesbs_xts_decrypt)
1023