162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * linux/arch/arm64/crypto/aes-ce.S - AES cipher for ARMv8 with
462306a36Sopenharmony_ci *                                    Crypto Extensions
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 2013 - 2017 Linaro Ltd <ard.biesheuvel@linaro.org>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/linkage.h>
1062306a36Sopenharmony_ci#include <asm/assembler.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#define AES_FUNC_START(func)		SYM_FUNC_START(ce_ ## func)
1362306a36Sopenharmony_ci#define AES_FUNC_END(func)		SYM_FUNC_END(ce_ ## func)
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci	.arch		armv8-a+crypto
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci	xtsmask		.req	v16
1862306a36Sopenharmony_ci	cbciv		.req	v16
1962306a36Sopenharmony_ci	vctr		.req	v16
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	.macro		xts_reload_mask, tmp
2262306a36Sopenharmony_ci	.endm
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	.macro		xts_cts_skip_tw, reg, lbl
2562306a36Sopenharmony_ci	.endm
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	/* preload all round keys */
2862306a36Sopenharmony_ci	.macro		load_round_keys, rounds, rk
2962306a36Sopenharmony_ci	cmp		\rounds, #12
3062306a36Sopenharmony_ci	blo		2222f		/* 128 bits */
3162306a36Sopenharmony_ci	beq		1111f		/* 192 bits */
3262306a36Sopenharmony_ci	ld1		{v17.4s-v18.4s}, [\rk], #32
3362306a36Sopenharmony_ci1111:	ld1		{v19.4s-v20.4s}, [\rk], #32
3462306a36Sopenharmony_ci2222:	ld1		{v21.4s-v24.4s}, [\rk], #64
3562306a36Sopenharmony_ci	ld1		{v25.4s-v28.4s}, [\rk], #64
3662306a36Sopenharmony_ci	ld1		{v29.4s-v31.4s}, [\rk]
3762306a36Sopenharmony_ci	.endm
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	/* prepare for encryption with key in rk[] */
4062306a36Sopenharmony_ci	.macro		enc_prepare, rounds, rk, temp
4162306a36Sopenharmony_ci	mov		\temp, \rk
4262306a36Sopenharmony_ci	load_round_keys	\rounds, \temp
4362306a36Sopenharmony_ci	.endm
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	/* prepare for encryption (again) but with new key in rk[] */
4662306a36Sopenharmony_ci	.macro		enc_switch_key, rounds, rk, temp
4762306a36Sopenharmony_ci	mov		\temp, \rk
4862306a36Sopenharmony_ci	load_round_keys	\rounds, \temp
4962306a36Sopenharmony_ci	.endm
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	/* prepare for decryption with key in rk[] */
5262306a36Sopenharmony_ci	.macro		dec_prepare, rounds, rk, temp
5362306a36Sopenharmony_ci	mov		\temp, \rk
5462306a36Sopenharmony_ci	load_round_keys	\rounds, \temp
5562306a36Sopenharmony_ci	.endm
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	.macro		do_enc_Nx, de, mc, k, i0, i1, i2, i3, i4
5862306a36Sopenharmony_ci	aes\de		\i0\().16b, \k\().16b
5962306a36Sopenharmony_ci	aes\mc		\i0\().16b, \i0\().16b
6062306a36Sopenharmony_ci	.ifnb		\i1
6162306a36Sopenharmony_ci	aes\de		\i1\().16b, \k\().16b
6262306a36Sopenharmony_ci	aes\mc		\i1\().16b, \i1\().16b
6362306a36Sopenharmony_ci	.ifnb		\i3
6462306a36Sopenharmony_ci	aes\de		\i2\().16b, \k\().16b
6562306a36Sopenharmony_ci	aes\mc		\i2\().16b, \i2\().16b
6662306a36Sopenharmony_ci	aes\de		\i3\().16b, \k\().16b
6762306a36Sopenharmony_ci	aes\mc		\i3\().16b, \i3\().16b
6862306a36Sopenharmony_ci	.ifnb		\i4
6962306a36Sopenharmony_ci	aes\de		\i4\().16b, \k\().16b
7062306a36Sopenharmony_ci	aes\mc		\i4\().16b, \i4\().16b
7162306a36Sopenharmony_ci	.endif
7262306a36Sopenharmony_ci	.endif
7362306a36Sopenharmony_ci	.endif
7462306a36Sopenharmony_ci	.endm
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	/* up to 5 interleaved encryption rounds with the same round key */
7762306a36Sopenharmony_ci	.macro		round_Nx, enc, k, i0, i1, i2, i3, i4
7862306a36Sopenharmony_ci	.ifc		\enc, e
7962306a36Sopenharmony_ci	do_enc_Nx	e, mc, \k, \i0, \i1, \i2, \i3, \i4
8062306a36Sopenharmony_ci	.else
8162306a36Sopenharmony_ci	do_enc_Nx	d, imc, \k, \i0, \i1, \i2, \i3, \i4
8262306a36Sopenharmony_ci	.endif
8362306a36Sopenharmony_ci	.endm
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	/* up to 5 interleaved final rounds */
8662306a36Sopenharmony_ci	.macro		fin_round_Nx, de, k, k2, i0, i1, i2, i3, i4
8762306a36Sopenharmony_ci	aes\de		\i0\().16b, \k\().16b
8862306a36Sopenharmony_ci	.ifnb		\i1
8962306a36Sopenharmony_ci	aes\de		\i1\().16b, \k\().16b
9062306a36Sopenharmony_ci	.ifnb		\i3
9162306a36Sopenharmony_ci	aes\de		\i2\().16b, \k\().16b
9262306a36Sopenharmony_ci	aes\de		\i3\().16b, \k\().16b
9362306a36Sopenharmony_ci	.ifnb		\i4
9462306a36Sopenharmony_ci	aes\de		\i4\().16b, \k\().16b
9562306a36Sopenharmony_ci	.endif
9662306a36Sopenharmony_ci	.endif
9762306a36Sopenharmony_ci	.endif
9862306a36Sopenharmony_ci	eor		\i0\().16b, \i0\().16b, \k2\().16b
9962306a36Sopenharmony_ci	.ifnb		\i1
10062306a36Sopenharmony_ci	eor		\i1\().16b, \i1\().16b, \k2\().16b
10162306a36Sopenharmony_ci	.ifnb		\i3
10262306a36Sopenharmony_ci	eor		\i2\().16b, \i2\().16b, \k2\().16b
10362306a36Sopenharmony_ci	eor		\i3\().16b, \i3\().16b, \k2\().16b
10462306a36Sopenharmony_ci	.ifnb		\i4
10562306a36Sopenharmony_ci	eor		\i4\().16b, \i4\().16b, \k2\().16b
10662306a36Sopenharmony_ci	.endif
10762306a36Sopenharmony_ci	.endif
10862306a36Sopenharmony_ci	.endif
10962306a36Sopenharmony_ci	.endm
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	/* up to 5 interleaved blocks */
11262306a36Sopenharmony_ci	.macro		do_block_Nx, enc, rounds, i0, i1, i2, i3, i4
11362306a36Sopenharmony_ci	cmp		\rounds, #12
11462306a36Sopenharmony_ci	blo		2222f		/* 128 bits */
11562306a36Sopenharmony_ci	beq		1111f		/* 192 bits */
11662306a36Sopenharmony_ci	round_Nx	\enc, v17, \i0, \i1, \i2, \i3, \i4
11762306a36Sopenharmony_ci	round_Nx	\enc, v18, \i0, \i1, \i2, \i3, \i4
11862306a36Sopenharmony_ci1111:	round_Nx	\enc, v19, \i0, \i1, \i2, \i3, \i4
11962306a36Sopenharmony_ci	round_Nx	\enc, v20, \i0, \i1, \i2, \i3, \i4
12062306a36Sopenharmony_ci2222:	.irp		key, v21, v22, v23, v24, v25, v26, v27, v28, v29
12162306a36Sopenharmony_ci	round_Nx	\enc, \key, \i0, \i1, \i2, \i3, \i4
12262306a36Sopenharmony_ci	.endr
12362306a36Sopenharmony_ci	fin_round_Nx	\enc, v30, v31, \i0, \i1, \i2, \i3, \i4
12462306a36Sopenharmony_ci	.endm
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	.macro		encrypt_block, in, rounds, t0, t1, t2
12762306a36Sopenharmony_ci	do_block_Nx	e, \rounds, \in
12862306a36Sopenharmony_ci	.endm
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	.macro		encrypt_block4x, i0, i1, i2, i3, rounds, t0, t1, t2
13162306a36Sopenharmony_ci	do_block_Nx	e, \rounds, \i0, \i1, \i2, \i3
13262306a36Sopenharmony_ci	.endm
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci	.macro		encrypt_block5x, i0, i1, i2, i3, i4, rounds, t0, t1, t2
13562306a36Sopenharmony_ci	do_block_Nx	e, \rounds, \i0, \i1, \i2, \i3, \i4
13662306a36Sopenharmony_ci	.endm
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	.macro		decrypt_block, in, rounds, t0, t1, t2
13962306a36Sopenharmony_ci	do_block_Nx	d, \rounds, \in
14062306a36Sopenharmony_ci	.endm
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	.macro		decrypt_block4x, i0, i1, i2, i3, rounds, t0, t1, t2
14362306a36Sopenharmony_ci	do_block_Nx	d, \rounds, \i0, \i1, \i2, \i3
14462306a36Sopenharmony_ci	.endm
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	.macro		decrypt_block5x, i0, i1, i2, i3, i4, rounds, t0, t1, t2
14762306a36Sopenharmony_ci	do_block_Nx	d, \rounds, \i0, \i1, \i2, \i3, \i4
14862306a36Sopenharmony_ci	.endm
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci#define MAX_STRIDE	5
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci#include "aes-modes.S"
153