xref: /linux/arch/arm64/crypto/aes-modes.S (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * linux/arch/arm64/crypto/aes-modes.S - chaining mode wrappers for AES
4 *
5 * Copyright (C) 2013 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org>
6 */
7
8/* included by aes-ce.S and aes-neon.S */
9
10	.text
11	.align		4
12
13#ifndef MAX_STRIDE
14#define MAX_STRIDE	4
15#endif
16
17#if MAX_STRIDE == 4
18#define ST4(x...) x
19#define ST5(x...)
20#else
21#define ST4(x...)
22#define ST5(x...) x
23#endif
24
25SYM_FUNC_START_LOCAL(aes_encrypt_block4x)
26	encrypt_block4x	v0, v1, v2, v3, w3, x2, x8, w7
27	ret
28SYM_FUNC_END(aes_encrypt_block4x)
29
30SYM_FUNC_START_LOCAL(aes_decrypt_block4x)
31	decrypt_block4x	v0, v1, v2, v3, w3, x2, x8, w7
32	ret
33SYM_FUNC_END(aes_decrypt_block4x)
34
35#if MAX_STRIDE == 5
36SYM_FUNC_START_LOCAL(aes_encrypt_block5x)
37	encrypt_block5x	v0, v1, v2, v3, v4, w3, x2, x8, w7
38	ret
39SYM_FUNC_END(aes_encrypt_block5x)
40
41SYM_FUNC_START_LOCAL(aes_decrypt_block5x)
42	decrypt_block5x	v0, v1, v2, v3, v4, w3, x2, x8, w7
43	ret
44SYM_FUNC_END(aes_decrypt_block5x)
45#endif
46
47	/*
48	 * aes_ecb_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
49	 *		   int blocks)
50	 * aes_ecb_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
51	 *		   int blocks)
52	 */
53
54AES_FUNC_START(aes_ecb_encrypt)
55	frame_push	0
56
57	enc_prepare	w3, x2, x5
58
59.LecbencloopNx:
60	subs		w4, w4, #MAX_STRIDE
61	bmi		.Lecbenc1x
62	ld1		{v0.16b-v3.16b}, [x1], #64	/* get 4 pt blocks */
63ST4(	bl		aes_encrypt_block4x		)
64ST5(	ld1		{v4.16b}, [x1], #16		)
65ST5(	bl		aes_encrypt_block5x		)
66	st1		{v0.16b-v3.16b}, [x0], #64
67ST5(	st1		{v4.16b}, [x0], #16		)
68	b		.LecbencloopNx
69.Lecbenc1x:
70	adds		w4, w4, #MAX_STRIDE
71	beq		.Lecbencout
72.Lecbencloop:
73	ld1		{v0.16b}, [x1], #16		/* get next pt block */
74	encrypt_block	v0, w3, x2, x5, w6
75	st1		{v0.16b}, [x0], #16
76	subs		w4, w4, #1
77	bne		.Lecbencloop
78.Lecbencout:
79	frame_pop
80	ret
81AES_FUNC_END(aes_ecb_encrypt)
82
83
84AES_FUNC_START(aes_ecb_decrypt)
85	frame_push	0
86
87	dec_prepare	w3, x2, x5
88
89.LecbdecloopNx:
90	subs		w4, w4, #MAX_STRIDE
91	bmi		.Lecbdec1x
92	ld1		{v0.16b-v3.16b}, [x1], #64	/* get 4 ct blocks */
93ST4(	bl		aes_decrypt_block4x		)
94ST5(	ld1		{v4.16b}, [x1], #16		)
95ST5(	bl		aes_decrypt_block5x		)
96	st1		{v0.16b-v3.16b}, [x0], #64
97ST5(	st1		{v4.16b}, [x0], #16		)
98	b		.LecbdecloopNx
99.Lecbdec1x:
100	adds		w4, w4, #MAX_STRIDE
101	beq		.Lecbdecout
102.Lecbdecloop:
103	ld1		{v0.16b}, [x1], #16		/* get next ct block */
104	decrypt_block	v0, w3, x2, x5, w6
105	st1		{v0.16b}, [x0], #16
106	subs		w4, w4, #1
107	bne		.Lecbdecloop
108.Lecbdecout:
109	frame_pop
110	ret
111AES_FUNC_END(aes_ecb_decrypt)
112
113
114	/*
115	 * aes_cbc_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
116	 *		   int blocks, u8 iv[])
117	 * aes_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
118	 *		   int blocks, u8 iv[])
119	 * aes_essiv_cbc_encrypt(u8 out[], u8 const in[], u32 const rk1[],
120	 *			 int rounds, int blocks, u8 iv[],
121	 *			 u32 const rk2[]);
122	 * aes_essiv_cbc_decrypt(u8 out[], u8 const in[], u32 const rk1[],
123	 *			 int rounds, int blocks, u8 iv[],
124	 *			 u32 const rk2[]);
125	 */
126
127AES_FUNC_START(aes_essiv_cbc_encrypt)
128	ld1		{v4.16b}, [x5]			/* get iv */
129
130	mov		w8, #14				/* AES-256: 14 rounds */
131	enc_prepare	w8, x6, x7
132	encrypt_block	v4, w8, x6, x7, w9
133	enc_switch_key	w3, x2, x6
134	b		.Lcbcencloop4x
135
136AES_FUNC_START(aes_cbc_encrypt)
137	ld1		{v4.16b}, [x5]			/* get iv */
138	enc_prepare	w3, x2, x6
139
140.Lcbcencloop4x:
141	subs		w4, w4, #4
142	bmi		.Lcbcenc1x
143	ld1		{v0.16b-v3.16b}, [x1], #64	/* get 4 pt blocks */
144	eor		v0.16b, v0.16b, v4.16b		/* ..and xor with iv */
145	encrypt_block	v0, w3, x2, x6, w7
146	eor		v1.16b, v1.16b, v0.16b
147	encrypt_block	v1, w3, x2, x6, w7
148	eor		v2.16b, v2.16b, v1.16b
149	encrypt_block	v2, w3, x2, x6, w7
150	eor		v3.16b, v3.16b, v2.16b
151	encrypt_block	v3, w3, x2, x6, w7
152	st1		{v0.16b-v3.16b}, [x0], #64
153	mov		v4.16b, v3.16b
154	b		.Lcbcencloop4x
155.Lcbcenc1x:
156	adds		w4, w4, #4
157	beq		.Lcbcencout
158.Lcbcencloop:
159	ld1		{v0.16b}, [x1], #16		/* get next pt block */
160	eor		v4.16b, v4.16b, v0.16b		/* ..and xor with iv */
161	encrypt_block	v4, w3, x2, x6, w7
162	st1		{v4.16b}, [x0], #16
163	subs		w4, w4, #1
164	bne		.Lcbcencloop
165.Lcbcencout:
166	st1		{v4.16b}, [x5]			/* return iv */
167	ret
168AES_FUNC_END(aes_cbc_encrypt)
169AES_FUNC_END(aes_essiv_cbc_encrypt)
170
171AES_FUNC_START(aes_essiv_cbc_decrypt)
172	ld1		{cbciv.16b}, [x5]		/* get iv */
173
174	mov		w8, #14				/* AES-256: 14 rounds */
175	enc_prepare	w8, x6, x7
176	encrypt_block	cbciv, w8, x6, x7, w9
177	b		.Lessivcbcdecstart
178
179AES_FUNC_START(aes_cbc_decrypt)
180	ld1		{cbciv.16b}, [x5]		/* get iv */
181.Lessivcbcdecstart:
182	frame_push	0
183	dec_prepare	w3, x2, x6
184
185.LcbcdecloopNx:
186	subs		w4, w4, #MAX_STRIDE
187	bmi		.Lcbcdec1x
188	ld1		{v0.16b-v3.16b}, [x1], #64	/* get 4 ct blocks */
189#if MAX_STRIDE == 5
190	ld1		{v4.16b}, [x1], #16		/* get 1 ct block */
191	mov		v5.16b, v0.16b
192	mov		v6.16b, v1.16b
193	mov		v7.16b, v2.16b
194	bl		aes_decrypt_block5x
195	sub		x1, x1, #32
196	eor		v0.16b, v0.16b, cbciv.16b
197	eor		v1.16b, v1.16b, v5.16b
198	ld1		{v5.16b}, [x1], #16		/* reload 1 ct block */
199	ld1		{cbciv.16b}, [x1], #16		/* reload 1 ct block */
200	eor		v2.16b, v2.16b, v6.16b
201	eor		v3.16b, v3.16b, v7.16b
202	eor		v4.16b, v4.16b, v5.16b
203#else
204	mov		v4.16b, v0.16b
205	mov		v5.16b, v1.16b
206	mov		v6.16b, v2.16b
207	bl		aes_decrypt_block4x
208	sub		x1, x1, #16
209	eor		v0.16b, v0.16b, cbciv.16b
210	eor		v1.16b, v1.16b, v4.16b
211	ld1		{cbciv.16b}, [x1], #16		/* reload 1 ct block */
212	eor		v2.16b, v2.16b, v5.16b
213	eor		v3.16b, v3.16b, v6.16b
214#endif
215	st1		{v0.16b-v3.16b}, [x0], #64
216ST5(	st1		{v4.16b}, [x0], #16		)
217	b		.LcbcdecloopNx
218.Lcbcdec1x:
219	adds		w4, w4, #MAX_STRIDE
220	beq		.Lcbcdecout
221.Lcbcdecloop:
222	ld1		{v1.16b}, [x1], #16		/* get next ct block */
223	mov		v0.16b, v1.16b			/* ...and copy to v0 */
224	decrypt_block	v0, w3, x2, x6, w7
225	eor		v0.16b, v0.16b, cbciv.16b	/* xor with iv => pt */
226	mov		cbciv.16b, v1.16b		/* ct is next iv */
227	st1		{v0.16b}, [x0], #16
228	subs		w4, w4, #1
229	bne		.Lcbcdecloop
230.Lcbcdecout:
231	st1		{cbciv.16b}, [x5]		/* return iv */
232	frame_pop
233	ret
234AES_FUNC_END(aes_cbc_decrypt)
235AES_FUNC_END(aes_essiv_cbc_decrypt)
236
237
238	/*
239	 * aes_cbc_cts_encrypt(u8 out[], u8 const in[], u32 const rk[],
240	 *		       int rounds, int bytes, u8 const iv[])
241	 * aes_cbc_cts_decrypt(u8 out[], u8 const in[], u32 const rk[],
242	 *		       int rounds, int bytes, u8 const iv[])
243	 */
244
245AES_FUNC_START(aes_cbc_cts_encrypt)
246	adr_l		x8, .Lcts_permute_table
247	sub		x4, x4, #16
248	add		x9, x8, #32
249	add		x8, x8, x4
250	sub		x9, x9, x4
251	ld1		{v3.16b}, [x8]
252	ld1		{v4.16b}, [x9]
253
254	ld1		{v0.16b}, [x1], x4		/* overlapping loads */
255	ld1		{v1.16b}, [x1]
256
257	ld1		{v5.16b}, [x5]			/* get iv */
258	enc_prepare	w3, x2, x6
259
260	eor		v0.16b, v0.16b, v5.16b		/* xor with iv */
261	tbl		v1.16b, {v1.16b}, v4.16b
262	encrypt_block	v0, w3, x2, x6, w7
263
264	eor		v1.16b, v1.16b, v0.16b
265	tbl		v0.16b, {v0.16b}, v3.16b
266	encrypt_block	v1, w3, x2, x6, w7
267
268	add		x4, x0, x4
269	st1		{v0.16b}, [x4]			/* overlapping stores */
270	st1		{v1.16b}, [x0]
271	ret
272AES_FUNC_END(aes_cbc_cts_encrypt)
273
274AES_FUNC_START(aes_cbc_cts_decrypt)
275	adr_l		x8, .Lcts_permute_table
276	sub		x4, x4, #16
277	add		x9, x8, #32
278	add		x8, x8, x4
279	sub		x9, x9, x4
280	ld1		{v3.16b}, [x8]
281	ld1		{v4.16b}, [x9]
282
283	ld1		{v0.16b}, [x1], x4		/* overlapping loads */
284	ld1		{v1.16b}, [x1]
285
286	ld1		{v5.16b}, [x5]			/* get iv */
287	dec_prepare	w3, x2, x6
288
289	decrypt_block	v0, w3, x2, x6, w7
290	tbl		v2.16b, {v0.16b}, v3.16b
291	eor		v2.16b, v2.16b, v1.16b
292
293	tbx		v0.16b, {v1.16b}, v4.16b
294	decrypt_block	v0, w3, x2, x6, w7
295	eor		v0.16b, v0.16b, v5.16b		/* xor with iv */
296
297	add		x4, x0, x4
298	st1		{v2.16b}, [x4]			/* overlapping stores */
299	st1		{v0.16b}, [x0]
300	ret
301AES_FUNC_END(aes_cbc_cts_decrypt)
302
303	.section	".rodata", "a"
304	.align		6
305.Lcts_permute_table:
306	.byte		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
307	.byte		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
308	.byte		 0x0,  0x1,  0x2,  0x3,  0x4,  0x5,  0x6,  0x7
309	.byte		 0x8,  0x9,  0xa,  0xb,  0xc,  0xd,  0xe,  0xf
310	.byte		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
311	.byte		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
312	.previous
313
314	/*
315	 * This macro generates the code for CTR and XCTR mode.
316	 */
317.macro ctr_encrypt xctr
318	// Arguments
319	OUT		.req x0
320	IN		.req x1
321	KEY		.req x2
322	ROUNDS_W	.req w3
323	BYTES_W		.req w4
324	IV		.req x5
325	BYTE_CTR_W 	.req w6		// XCTR only
326	// Intermediate values
327	CTR_W		.req w11	// XCTR only
328	CTR		.req x11	// XCTR only
329	IV_PART		.req x12
330	BLOCKS		.req x13
331	BLOCKS_W	.req w13
332
333	frame_push	0
334
335	enc_prepare	ROUNDS_W, KEY, IV_PART
336	ld1		{vctr.16b}, [IV]
337
338	/*
339	 * Keep 64 bits of the IV in a register.  For CTR mode this lets us
340	 * easily increment the IV.  For XCTR mode this lets us efficiently XOR
341	 * the 64-bit counter with the IV.
342	 */
343	.if \xctr
344		umov		IV_PART, vctr.d[0]
345		lsr		CTR_W, BYTE_CTR_W, #4
346	.else
347		umov		IV_PART, vctr.d[1]
348		rev		IV_PART, IV_PART
349	.endif
350
351.LctrloopNx\xctr:
352	add		BLOCKS_W, BYTES_W, #15
353	sub		BYTES_W, BYTES_W, #MAX_STRIDE << 4
354	lsr		BLOCKS_W, BLOCKS_W, #4
355	mov		w8, #MAX_STRIDE
356	cmp		BLOCKS_W, w8
357	csel		BLOCKS_W, BLOCKS_W, w8, lt
358
359	/*
360	 * Set up the counter values in v0-v{MAX_STRIDE-1}.
361	 *
362	 * If we are encrypting less than MAX_STRIDE blocks, the tail block
363	 * handling code expects the last keystream block to be in
364	 * v{MAX_STRIDE-1}.  For example: if encrypting two blocks with
365	 * MAX_STRIDE=5, then v3 and v4 should have the next two counter blocks.
366	 */
367	.if \xctr
368		add		CTR, CTR, BLOCKS
369	.else
370		adds		IV_PART, IV_PART, BLOCKS
371	.endif
372	mov		v0.16b, vctr.16b
373	mov		v1.16b, vctr.16b
374	mov		v2.16b, vctr.16b
375	mov		v3.16b, vctr.16b
376ST5(	mov		v4.16b, vctr.16b		)
377	.if \xctr
378		sub		x6, CTR, #MAX_STRIDE - 1
379		sub		x7, CTR, #MAX_STRIDE - 2
380		sub		x8, CTR, #MAX_STRIDE - 3
381		sub		x9, CTR, #MAX_STRIDE - 4
382ST5(		sub		x10, CTR, #MAX_STRIDE - 5	)
383		eor		x6, x6, IV_PART
384		eor		x7, x7, IV_PART
385		eor		x8, x8, IV_PART
386		eor		x9, x9, IV_PART
387ST5(		eor		x10, x10, IV_PART		)
388		mov		v0.d[0], x6
389		mov		v1.d[0], x7
390		mov		v2.d[0], x8
391		mov		v3.d[0], x9
392ST5(		mov		v4.d[0], x10			)
393	.else
394		bcs		0f
395		.subsection	1
396		/*
397		 * This subsection handles carries.
398		 *
399		 * Conditional branching here is allowed with respect to time
400		 * invariance since the branches are dependent on the IV instead
401		 * of the plaintext or key.  This code is rarely executed in
402		 * practice anyway.
403		 */
404
405		/* Apply carry to outgoing counter. */
4060:		umov		x8, vctr.d[0]
407		rev		x8, x8
408		add		x8, x8, #1
409		rev		x8, x8
410		ins		vctr.d[0], x8
411
412		/*
413		 * Apply carry to counter blocks if needed.
414		 *
415		 * Since the carry flag was set, we know 0 <= IV_PART <
416		 * MAX_STRIDE.  Using the value of IV_PART we can determine how
417		 * many counter blocks need to be updated.
418		 */
419		cbz		IV_PART, 2f
420		adr		x16, 1f
421		sub		x16, x16, IV_PART, lsl #3
422		br		x16
423		bti		c
424		mov		v0.d[0], vctr.d[0]
425		bti		c
426		mov		v1.d[0], vctr.d[0]
427		bti		c
428		mov		v2.d[0], vctr.d[0]
429		bti		c
430		mov		v3.d[0], vctr.d[0]
431ST5(		bti		c				)
432ST5(		mov		v4.d[0], vctr.d[0]		)
4331:		b		2f
434		.previous
435
4362:		rev		x7, IV_PART
437		ins		vctr.d[1], x7
438		sub		x7, IV_PART, #MAX_STRIDE - 1
439		sub		x8, IV_PART, #MAX_STRIDE - 2
440		sub		x9, IV_PART, #MAX_STRIDE - 3
441		rev		x7, x7
442		rev		x8, x8
443		mov		v1.d[1], x7
444		rev		x9, x9
445ST5(		sub		x10, IV_PART, #MAX_STRIDE - 4	)
446		mov		v2.d[1], x8
447ST5(		rev		x10, x10			)
448		mov		v3.d[1], x9
449ST5(		mov		v4.d[1], x10			)
450	.endif
451
452	/*
453	 * If there are at least MAX_STRIDE blocks left, XOR the data with
454	 * keystream and store.  Otherwise jump to tail handling.
455	 */
456	tbnz		BYTES_W, #31, .Lctrtail\xctr
457	ld1		{v5.16b-v7.16b}, [IN], #48
458ST4(	bl		aes_encrypt_block4x		)
459ST5(	bl		aes_encrypt_block5x		)
460	eor		v0.16b, v5.16b, v0.16b
461ST4(	ld1		{v5.16b}, [IN], #16		)
462	eor		v1.16b, v6.16b, v1.16b
463ST5(	ld1		{v5.16b-v6.16b}, [IN], #32	)
464	eor		v2.16b, v7.16b, v2.16b
465	eor		v3.16b, v5.16b, v3.16b
466ST5(	eor		v4.16b, v6.16b, v4.16b		)
467	st1		{v0.16b-v3.16b}, [OUT], #64
468ST5(	st1		{v4.16b}, [OUT], #16		)
469	cbz		BYTES_W, .Lctrout\xctr
470	b		.LctrloopNx\xctr
471
472.Lctrout\xctr:
473	.if !\xctr
474		st1		{vctr.16b}, [IV] /* return next CTR value */
475	.endif
476	frame_pop
477	ret
478
479.Lctrtail\xctr:
480	/*
481	 * Handle up to MAX_STRIDE * 16 - 1 bytes of plaintext
482	 *
483	 * This code expects the last keystream block to be in v{MAX_STRIDE-1}.
484	 * For example: if encrypting two blocks with MAX_STRIDE=5, then v3 and
485	 * v4 should have the next two counter blocks.
486	 *
487	 * This allows us to store the ciphertext by writing to overlapping
488	 * regions of memory.  Any invalid ciphertext blocks get overwritten by
489	 * correctly computed blocks.  This approach greatly simplifies the
490	 * logic for storing the ciphertext.
491	 */
492	mov		x16, #16
493	ands		w7, BYTES_W, #0xf
494	csel		x13, x7, x16, ne
495
496ST5(	cmp		BYTES_W, #64 - (MAX_STRIDE << 4))
497ST5(	csel		x14, x16, xzr, gt		)
498	cmp		BYTES_W, #48 - (MAX_STRIDE << 4)
499	csel		x15, x16, xzr, gt
500	cmp		BYTES_W, #32 - (MAX_STRIDE << 4)
501	csel		x16, x16, xzr, gt
502	cmp		BYTES_W, #16 - (MAX_STRIDE << 4)
503
504	adr_l		x9, .Lcts_permute_table
505	add		x9, x9, x13
506	ble		.Lctrtail1x\xctr
507
508ST5(	ld1		{v5.16b}, [IN], x14		)
509	ld1		{v6.16b}, [IN], x15
510	ld1		{v7.16b}, [IN], x16
511
512ST4(	bl		aes_encrypt_block4x		)
513ST5(	bl		aes_encrypt_block5x		)
514
515	ld1		{v8.16b}, [IN], x13
516	ld1		{v9.16b}, [IN]
517	ld1		{v10.16b}, [x9]
518
519ST4(	eor		v6.16b, v6.16b, v0.16b		)
520ST4(	eor		v7.16b, v7.16b, v1.16b		)
521ST4(	tbl		v3.16b, {v3.16b}, v10.16b	)
522ST4(	eor		v8.16b, v8.16b, v2.16b		)
523ST4(	eor		v9.16b, v9.16b, v3.16b		)
524
525ST5(	eor		v5.16b, v5.16b, v0.16b		)
526ST5(	eor		v6.16b, v6.16b, v1.16b		)
527ST5(	tbl		v4.16b, {v4.16b}, v10.16b	)
528ST5(	eor		v7.16b, v7.16b, v2.16b		)
529ST5(	eor		v8.16b, v8.16b, v3.16b		)
530ST5(	eor		v9.16b, v9.16b, v4.16b		)
531
532ST5(	st1		{v5.16b}, [OUT], x14		)
533	st1		{v6.16b}, [OUT], x15
534	st1		{v7.16b}, [OUT], x16
535	add		x13, x13, OUT
536	st1		{v9.16b}, [x13]		// overlapping stores
537	st1		{v8.16b}, [OUT]
538	b		.Lctrout\xctr
539
540.Lctrtail1x\xctr:
541	/*
542	 * Handle <= 16 bytes of plaintext
543	 *
544	 * This code always reads and writes 16 bytes.  To avoid out of bounds
545	 * accesses, XCTR and CTR modes must use a temporary buffer when
546	 * encrypting/decrypting less than 16 bytes.
547	 *
548	 * This code is unusual in that it loads the input and stores the output
549	 * relative to the end of the buffers rather than relative to the start.
550	 * This causes unusual behaviour when encrypting/decrypting less than 16
551	 * bytes; the end of the data is expected to be at the end of the
552	 * temporary buffer rather than the start of the data being at the start
553	 * of the temporary buffer.
554	 */
555	sub		x8, x7, #16
556	csel		x7, x7, x8, eq
557	add		IN, IN, x7
558	add		OUT, OUT, x7
559	ld1		{v5.16b}, [IN]
560	ld1		{v6.16b}, [OUT]
561ST5(	mov		v3.16b, v4.16b			)
562	encrypt_block	v3, ROUNDS_W, KEY, x8, w7
563	ld1		{v10.16b-v11.16b}, [x9]
564	tbl		v3.16b, {v3.16b}, v10.16b
565	sshr		v11.16b, v11.16b, #7
566	eor		v5.16b, v5.16b, v3.16b
567	bif		v5.16b, v6.16b, v11.16b
568	st1		{v5.16b}, [OUT]
569	b		.Lctrout\xctr
570
571	// Arguments
572	.unreq OUT
573	.unreq IN
574	.unreq KEY
575	.unreq ROUNDS_W
576	.unreq BYTES_W
577	.unreq IV
578	.unreq BYTE_CTR_W	// XCTR only
579	// Intermediate values
580	.unreq CTR_W		// XCTR only
581	.unreq CTR		// XCTR only
582	.unreq IV_PART
583	.unreq BLOCKS
584	.unreq BLOCKS_W
585.endm
586
587	/*
588	 * aes_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
589	 *		   int bytes, u8 ctr[])
590	 *
591	 * The input and output buffers must always be at least 16 bytes even if
592	 * encrypting/decrypting less than 16 bytes.  Otherwise out of bounds
593	 * accesses will occur.  The data to be encrypted/decrypted is expected
594	 * to be at the end of this 16-byte temporary buffer rather than the
595	 * start.
596	 */
597
598AES_FUNC_START(aes_ctr_encrypt)
599	ctr_encrypt 0
600AES_FUNC_END(aes_ctr_encrypt)
601
602	/*
603	 * aes_xctr_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
604	 *		   int bytes, u8 const iv[], int byte_ctr)
605	 *
606	 * The input and output buffers must always be at least 16 bytes even if
607	 * encrypting/decrypting less than 16 bytes.  Otherwise out of bounds
608	 * accesses will occur.  The data to be encrypted/decrypted is expected
609	 * to be at the end of this 16-byte temporary buffer rather than the
610	 * start.
611	 */
612
613AES_FUNC_START(aes_xctr_encrypt)
614	ctr_encrypt 1
615AES_FUNC_END(aes_xctr_encrypt)
616
617
618	/*
619	 * aes_xts_encrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
620	 *		   int bytes, u8 const rk2[], u8 iv[], int first)
621	 * aes_xts_decrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
622	 *		   int bytes, u8 const rk2[], u8 iv[], int first)
623	 */
624
625	.macro		next_tweak, out, in, tmp
626	sshr		\tmp\().2d,  \in\().2d,   #63
627	and		\tmp\().16b, \tmp\().16b, xtsmask.16b
628	add		\out\().2d,  \in\().2d,   \in\().2d
629	ext		\tmp\().16b, \tmp\().16b, \tmp\().16b, #8
630	eor		\out\().16b, \out\().16b, \tmp\().16b
631	.endm
632
633	.macro		xts_load_mask, tmp
634	movi		xtsmask.2s, #0x1
635	movi		\tmp\().2s, #0x87
636	uzp1		xtsmask.4s, xtsmask.4s, \tmp\().4s
637	.endm
638
639AES_FUNC_START(aes_xts_encrypt)
640	frame_push	0
641
642	ld1		{v4.16b}, [x6]
643	xts_load_mask	v8
644	cbz		w7, .Lxtsencnotfirst
645
646	enc_prepare	w3, x5, x8
647	xts_cts_skip_tw	w7, .LxtsencNx
648	encrypt_block	v4, w3, x5, x8, w7		/* first tweak */
649	enc_switch_key	w3, x2, x8
650	b		.LxtsencNx
651
652.Lxtsencnotfirst:
653	enc_prepare	w3, x2, x8
654.LxtsencloopNx:
655	next_tweak	v4, v4, v8
656.LxtsencNx:
657	subs		w4, w4, #64
658	bmi		.Lxtsenc1x
659	ld1		{v0.16b-v3.16b}, [x1], #64	/* get 4 pt blocks */
660	next_tweak	v5, v4, v8
661	eor		v0.16b, v0.16b, v4.16b
662	next_tweak	v6, v5, v8
663	eor		v1.16b, v1.16b, v5.16b
664	eor		v2.16b, v2.16b, v6.16b
665	next_tweak	v7, v6, v8
666	eor		v3.16b, v3.16b, v7.16b
667	bl		aes_encrypt_block4x
668	eor		v3.16b, v3.16b, v7.16b
669	eor		v0.16b, v0.16b, v4.16b
670	eor		v1.16b, v1.16b, v5.16b
671	eor		v2.16b, v2.16b, v6.16b
672	st1		{v0.16b-v3.16b}, [x0], #64
673	mov		v4.16b, v7.16b
674	cbz		w4, .Lxtsencret
675	xts_reload_mask	v8
676	b		.LxtsencloopNx
677.Lxtsenc1x:
678	adds		w4, w4, #64
679	beq		.Lxtsencout
680	subs		w4, w4, #16
681	bmi		.LxtsencctsNx
682.Lxtsencloop:
683	ld1		{v0.16b}, [x1], #16
684.Lxtsencctsout:
685	eor		v0.16b, v0.16b, v4.16b
686	encrypt_block	v0, w3, x2, x8, w7
687	eor		v0.16b, v0.16b, v4.16b
688	cbz		w4, .Lxtsencout
689	subs		w4, w4, #16
690	next_tweak	v4, v4, v8
691	bmi		.Lxtsenccts
692	st1		{v0.16b}, [x0], #16
693	b		.Lxtsencloop
694.Lxtsencout:
695	st1		{v0.16b}, [x0]
696.Lxtsencret:
697	st1		{v4.16b}, [x6]
698	frame_pop
699	ret
700
701.LxtsencctsNx:
702	mov		v0.16b, v3.16b
703	sub		x0, x0, #16
704.Lxtsenccts:
705	adr_l		x8, .Lcts_permute_table
706
707	add		x1, x1, w4, sxtw	/* rewind input pointer */
708	add		w4, w4, #16		/* # bytes in final block */
709	add		x9, x8, #32
710	add		x8, x8, x4
711	sub		x9, x9, x4
712	add		x4, x0, x4		/* output address of final block */
713
714	ld1		{v1.16b}, [x1]		/* load final block */
715	ld1		{v2.16b}, [x8]
716	ld1		{v3.16b}, [x9]
717
718	tbl		v2.16b, {v0.16b}, v2.16b
719	tbx		v0.16b, {v1.16b}, v3.16b
720	st1		{v2.16b}, [x4]			/* overlapping stores */
721	mov		w4, wzr
722	b		.Lxtsencctsout
723AES_FUNC_END(aes_xts_encrypt)
724
725AES_FUNC_START(aes_xts_decrypt)
726	frame_push	0
727
728	/* subtract 16 bytes if we are doing CTS */
729	sub		w8, w4, #0x10
730	tst		w4, #0xf
731	csel		w4, w4, w8, eq
732
733	ld1		{v4.16b}, [x6]
734	xts_load_mask	v8
735	xts_cts_skip_tw	w7, .Lxtsdecskiptw
736	cbz		w7, .Lxtsdecnotfirst
737
738	enc_prepare	w3, x5, x8
739	encrypt_block	v4, w3, x5, x8, w7		/* first tweak */
740.Lxtsdecskiptw:
741	dec_prepare	w3, x2, x8
742	b		.LxtsdecNx
743
744.Lxtsdecnotfirst:
745	dec_prepare	w3, x2, x8
746.LxtsdecloopNx:
747	next_tweak	v4, v4, v8
748.LxtsdecNx:
749	subs		w4, w4, #64
750	bmi		.Lxtsdec1x
751	ld1		{v0.16b-v3.16b}, [x1], #64	/* get 4 ct blocks */
752	next_tweak	v5, v4, v8
753	eor		v0.16b, v0.16b, v4.16b
754	next_tweak	v6, v5, v8
755	eor		v1.16b, v1.16b, v5.16b
756	eor		v2.16b, v2.16b, v6.16b
757	next_tweak	v7, v6, v8
758	eor		v3.16b, v3.16b, v7.16b
759	bl		aes_decrypt_block4x
760	eor		v3.16b, v3.16b, v7.16b
761	eor		v0.16b, v0.16b, v4.16b
762	eor		v1.16b, v1.16b, v5.16b
763	eor		v2.16b, v2.16b, v6.16b
764	st1		{v0.16b-v3.16b}, [x0], #64
765	mov		v4.16b, v7.16b
766	cbz		w4, .Lxtsdecout
767	xts_reload_mask	v8
768	b		.LxtsdecloopNx
769.Lxtsdec1x:
770	adds		w4, w4, #64
771	beq		.Lxtsdecout
772	subs		w4, w4, #16
773.Lxtsdecloop:
774	ld1		{v0.16b}, [x1], #16
775	bmi		.Lxtsdeccts
776.Lxtsdecctsout:
777	eor		v0.16b, v0.16b, v4.16b
778	decrypt_block	v0, w3, x2, x8, w7
779	eor		v0.16b, v0.16b, v4.16b
780	st1		{v0.16b}, [x0], #16
781	cbz		w4, .Lxtsdecout
782	subs		w4, w4, #16
783	next_tweak	v4, v4, v8
784	b		.Lxtsdecloop
785.Lxtsdecout:
786	st1		{v4.16b}, [x6]
787	frame_pop
788	ret
789
790.Lxtsdeccts:
791	adr_l		x8, .Lcts_permute_table
792
793	add		x1, x1, w4, sxtw	/* rewind input pointer */
794	add		w4, w4, #16		/* # bytes in final block */
795	add		x9, x8, #32
796	add		x8, x8, x4
797	sub		x9, x9, x4
798	add		x4, x0, x4		/* output address of final block */
799
800	next_tweak	v5, v4, v8
801
802	ld1		{v1.16b}, [x1]		/* load final block */
803	ld1		{v2.16b}, [x8]
804	ld1		{v3.16b}, [x9]
805
806	eor		v0.16b, v0.16b, v5.16b
807	decrypt_block	v0, w3, x2, x8, w7
808	eor		v0.16b, v0.16b, v5.16b
809
810	tbl		v2.16b, {v0.16b}, v2.16b
811	tbx		v0.16b, {v1.16b}, v3.16b
812
813	st1		{v2.16b}, [x4]			/* overlapping stores */
814	mov		w4, wzr
815	b		.Lxtsdecctsout
816AES_FUNC_END(aes_xts_decrypt)
817
818	/*
819	 * aes_mac_update(u8 const in[], u32 const rk[], int rounds,
820	 *		  int blocks, u8 dg[], int enc_before, int enc_after)
821	 */
822AES_FUNC_START(aes_mac_update)
823	ld1		{v0.16b}, [x4]			/* get dg */
824	enc_prepare	w2, x1, x7
825	cbz		w5, .Lmacloop4x
826
827	encrypt_block	v0, w2, x1, x7, w8
828
829.Lmacloop4x:
830	subs		w3, w3, #4
831	bmi		.Lmac1x
832	ld1		{v1.16b-v4.16b}, [x0], #64	/* get next pt block */
833	eor		v0.16b, v0.16b, v1.16b		/* ..and xor with dg */
834	encrypt_block	v0, w2, x1, x7, w8
835	eor		v0.16b, v0.16b, v2.16b
836	encrypt_block	v0, w2, x1, x7, w8
837	eor		v0.16b, v0.16b, v3.16b
838	encrypt_block	v0, w2, x1, x7, w8
839	eor		v0.16b, v0.16b, v4.16b
840	cmp		w3, wzr
841	csinv		x5, x6, xzr, eq
842	cbz		w5, .Lmacout
843	encrypt_block	v0, w2, x1, x7, w8
844	st1		{v0.16b}, [x4]			/* return dg */
845	cond_yield	.Lmacout, x7, x8
846	b		.Lmacloop4x
847.Lmac1x:
848	add		w3, w3, #4
849.Lmacloop:
850	cbz		w3, .Lmacout
851	ld1		{v1.16b}, [x0], #16		/* get next pt block */
852	eor		v0.16b, v0.16b, v1.16b		/* ..and xor with dg */
853
854	subs		w3, w3, #1
855	csinv		x5, x6, xzr, eq
856	cbz		w5, .Lmacout
857
858.Lmacenc:
859	encrypt_block	v0, w2, x1, x7, w8
860	b		.Lmacloop
861
862.Lmacout:
863	st1		{v0.16b}, [x4]			/* return dg */
864	mov		w0, w3
865	ret
866AES_FUNC_END(aes_mac_update)
867