18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * linux/arch/arm64/crypto/aes-ce.S - AES cipher for ARMv8 with
48c2ecf20Sopenharmony_ci *                                    Crypto Extensions
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 2013 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org>
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/linkage.h>
108c2ecf20Sopenharmony_ci#include <asm/assembler.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#define AES_FUNC_START(func)		SYM_FUNC_START(ce_ ## func)
138c2ecf20Sopenharmony_ci#define AES_FUNC_END(func)		SYM_FUNC_END(ce_ ## func)
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci	.arch		armv8-a+crypto
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci	xtsmask		.req	v16
188c2ecf20Sopenharmony_ci	cbciv		.req	v16
198c2ecf20Sopenharmony_ci	vctr		.req	v16
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci	.macro		xts_reload_mask, tmp
228c2ecf20Sopenharmony_ci	.endm
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci	.macro		xts_cts_skip_tw, reg, lbl
258c2ecf20Sopenharmony_ci	.endm
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci	/* preload all round keys */
288c2ecf20Sopenharmony_ci	.macro		load_round_keys, rounds, rk
298c2ecf20Sopenharmony_ci	cmp		\rounds, #12
308c2ecf20Sopenharmony_ci	blo		2222f		/* 128 bits */
318c2ecf20Sopenharmony_ci	beq		1111f		/* 192 bits */
328c2ecf20Sopenharmony_ci	ld1		{v17.4s-v18.4s}, [\rk], #32
338c2ecf20Sopenharmony_ci1111:	ld1		{v19.4s-v20.4s}, [\rk], #32
348c2ecf20Sopenharmony_ci2222:	ld1		{v21.4s-v24.4s}, [\rk], #64
358c2ecf20Sopenharmony_ci	ld1		{v25.4s-v28.4s}, [\rk], #64
368c2ecf20Sopenharmony_ci	ld1		{v29.4s-v31.4s}, [\rk]
378c2ecf20Sopenharmony_ci	.endm
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	/* prepare for encryption with key in rk[] */
408c2ecf20Sopenharmony_ci	.macro		enc_prepare, rounds, rk, temp
418c2ecf20Sopenharmony_ci	mov		\temp, \rk
428c2ecf20Sopenharmony_ci	load_round_keys	\rounds, \temp
438c2ecf20Sopenharmony_ci	.endm
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	/* prepare for encryption (again) but with new key in rk[] */
468c2ecf20Sopenharmony_ci	.macro		enc_switch_key, rounds, rk, temp
478c2ecf20Sopenharmony_ci	mov		\temp, \rk
488c2ecf20Sopenharmony_ci	load_round_keys	\rounds, \temp
498c2ecf20Sopenharmony_ci	.endm
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	/* prepare for decryption with key in rk[] */
528c2ecf20Sopenharmony_ci	.macro		dec_prepare, rounds, rk, temp
538c2ecf20Sopenharmony_ci	mov		\temp, \rk
548c2ecf20Sopenharmony_ci	load_round_keys	\rounds, \temp
558c2ecf20Sopenharmony_ci	.endm
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci	.macro		do_enc_Nx, de, mc, k, i0, i1, i2, i3, i4
588c2ecf20Sopenharmony_ci	aes\de		\i0\().16b, \k\().16b
598c2ecf20Sopenharmony_ci	aes\mc		\i0\().16b, \i0\().16b
608c2ecf20Sopenharmony_ci	.ifnb		\i1
618c2ecf20Sopenharmony_ci	aes\de		\i1\().16b, \k\().16b
628c2ecf20Sopenharmony_ci	aes\mc		\i1\().16b, \i1\().16b
638c2ecf20Sopenharmony_ci	.ifnb		\i3
648c2ecf20Sopenharmony_ci	aes\de		\i2\().16b, \k\().16b
658c2ecf20Sopenharmony_ci	aes\mc		\i2\().16b, \i2\().16b
668c2ecf20Sopenharmony_ci	aes\de		\i3\().16b, \k\().16b
678c2ecf20Sopenharmony_ci	aes\mc		\i3\().16b, \i3\().16b
688c2ecf20Sopenharmony_ci	.ifnb		\i4
698c2ecf20Sopenharmony_ci	aes\de		\i4\().16b, \k\().16b
708c2ecf20Sopenharmony_ci	aes\mc		\i4\().16b, \i4\().16b
718c2ecf20Sopenharmony_ci	.endif
728c2ecf20Sopenharmony_ci	.endif
738c2ecf20Sopenharmony_ci	.endif
748c2ecf20Sopenharmony_ci	.endm
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	/* up to 5 interleaved encryption rounds with the same round key */
778c2ecf20Sopenharmony_ci	.macro		round_Nx, enc, k, i0, i1, i2, i3, i4
788c2ecf20Sopenharmony_ci	.ifc		\enc, e
798c2ecf20Sopenharmony_ci	do_enc_Nx	e, mc, \k, \i0, \i1, \i2, \i3, \i4
808c2ecf20Sopenharmony_ci	.else
818c2ecf20Sopenharmony_ci	do_enc_Nx	d, imc, \k, \i0, \i1, \i2, \i3, \i4
828c2ecf20Sopenharmony_ci	.endif
838c2ecf20Sopenharmony_ci	.endm
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	/* up to 5 interleaved final rounds */
868c2ecf20Sopenharmony_ci	.macro		fin_round_Nx, de, k, k2, i0, i1, i2, i3, i4
878c2ecf20Sopenharmony_ci	aes\de		\i0\().16b, \k\().16b
888c2ecf20Sopenharmony_ci	.ifnb		\i1
898c2ecf20Sopenharmony_ci	aes\de		\i1\().16b, \k\().16b
908c2ecf20Sopenharmony_ci	.ifnb		\i3
918c2ecf20Sopenharmony_ci	aes\de		\i2\().16b, \k\().16b
928c2ecf20Sopenharmony_ci	aes\de		\i3\().16b, \k\().16b
938c2ecf20Sopenharmony_ci	.ifnb		\i4
948c2ecf20Sopenharmony_ci	aes\de		\i4\().16b, \k\().16b
958c2ecf20Sopenharmony_ci	.endif
968c2ecf20Sopenharmony_ci	.endif
978c2ecf20Sopenharmony_ci	.endif
988c2ecf20Sopenharmony_ci	eor		\i0\().16b, \i0\().16b, \k2\().16b
998c2ecf20Sopenharmony_ci	.ifnb		\i1
1008c2ecf20Sopenharmony_ci	eor		\i1\().16b, \i1\().16b, \k2\().16b
1018c2ecf20Sopenharmony_ci	.ifnb		\i3
1028c2ecf20Sopenharmony_ci	eor		\i2\().16b, \i2\().16b, \k2\().16b
1038c2ecf20Sopenharmony_ci	eor		\i3\().16b, \i3\().16b, \k2\().16b
1048c2ecf20Sopenharmony_ci	.ifnb		\i4
1058c2ecf20Sopenharmony_ci	eor		\i4\().16b, \i4\().16b, \k2\().16b
1068c2ecf20Sopenharmony_ci	.endif
1078c2ecf20Sopenharmony_ci	.endif
1088c2ecf20Sopenharmony_ci	.endif
1098c2ecf20Sopenharmony_ci	.endm
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci	/* up to 5 interleaved blocks */
1128c2ecf20Sopenharmony_ci	.macro		do_block_Nx, enc, rounds, i0, i1, i2, i3, i4
1138c2ecf20Sopenharmony_ci	cmp		\rounds, #12
1148c2ecf20Sopenharmony_ci	blo		2222f		/* 128 bits */
1158c2ecf20Sopenharmony_ci	beq		1111f		/* 192 bits */
1168c2ecf20Sopenharmony_ci	round_Nx	\enc, v17, \i0, \i1, \i2, \i3, \i4
1178c2ecf20Sopenharmony_ci	round_Nx	\enc, v18, \i0, \i1, \i2, \i3, \i4
1188c2ecf20Sopenharmony_ci1111:	round_Nx	\enc, v19, \i0, \i1, \i2, \i3, \i4
1198c2ecf20Sopenharmony_ci	round_Nx	\enc, v20, \i0, \i1, \i2, \i3, \i4
1208c2ecf20Sopenharmony_ci2222:	.irp		key, v21, v22, v23, v24, v25, v26, v27, v28, v29
1218c2ecf20Sopenharmony_ci	round_Nx	\enc, \key, \i0, \i1, \i2, \i3, \i4
1228c2ecf20Sopenharmony_ci	.endr
1238c2ecf20Sopenharmony_ci	fin_round_Nx	\enc, v30, v31, \i0, \i1, \i2, \i3, \i4
1248c2ecf20Sopenharmony_ci	.endm
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci	.macro		encrypt_block, in, rounds, t0, t1, t2
1278c2ecf20Sopenharmony_ci	do_block_Nx	e, \rounds, \in
1288c2ecf20Sopenharmony_ci	.endm
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	.macro		encrypt_block4x, i0, i1, i2, i3, rounds, t0, t1, t2
1318c2ecf20Sopenharmony_ci	do_block_Nx	e, \rounds, \i0, \i1, \i2, \i3
1328c2ecf20Sopenharmony_ci	.endm
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	.macro		encrypt_block5x, i0, i1, i2, i3, i4, rounds, t0, t1, t2
1358c2ecf20Sopenharmony_ci	do_block_Nx	e, \rounds, \i0, \i1, \i2, \i3, \i4
1368c2ecf20Sopenharmony_ci	.endm
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	.macro		decrypt_block, in, rounds, t0, t1, t2
1398c2ecf20Sopenharmony_ci	do_block_Nx	d, \rounds, \in
1408c2ecf20Sopenharmony_ci	.endm
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	.macro		decrypt_block4x, i0, i1, i2, i3, rounds, t0, t1, t2
1438c2ecf20Sopenharmony_ci	do_block_Nx	d, \rounds, \i0, \i1, \i2, \i3
1448c2ecf20Sopenharmony_ci	.endm
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ci	.macro		decrypt_block5x, i0, i1, i2, i3, i4, rounds, t0, t1, t2
1478c2ecf20Sopenharmony_ci	do_block_Nx	d, \rounds, \i0, \i1, \i2, \i3, \i4
1488c2ecf20Sopenharmony_ci	.endm
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci#define MAX_STRIDE	5
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci#include "aes-modes.S"
153