162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * sm3-ce-core.S - SM3 secure hash using ARMv8.2 Crypto Extensions
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2018 Linaro Ltd <ard.biesheuvel@linaro.org>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/linkage.h>
962306a36Sopenharmony_ci#include <linux/cfi_types.h>
1062306a36Sopenharmony_ci#include <asm/assembler.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci	.irp		b, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
1362306a36Sopenharmony_ci	.set		.Lv\b\().4s, \b
1462306a36Sopenharmony_ci	.endr
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci	.macro		sm3partw1, rd, rn, rm
1762306a36Sopenharmony_ci	.inst		0xce60c000 | .L\rd | (.L\rn << 5) | (.L\rm << 16)
1862306a36Sopenharmony_ci	.endm
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci	.macro		sm3partw2, rd, rn, rm
2162306a36Sopenharmony_ci	.inst		0xce60c400 | .L\rd | (.L\rn << 5) | (.L\rm << 16)
2262306a36Sopenharmony_ci	.endm
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	.macro		sm3ss1, rd, rn, rm, ra
2562306a36Sopenharmony_ci	.inst		0xce400000 | .L\rd | (.L\rn << 5) | (.L\ra << 10) | (.L\rm << 16)
2662306a36Sopenharmony_ci	.endm
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci	.macro		sm3tt1a, rd, rn, rm, imm2
2962306a36Sopenharmony_ci	.inst		0xce408000 | .L\rd | (.L\rn << 5) | ((\imm2) << 12) | (.L\rm << 16)
3062306a36Sopenharmony_ci	.endm
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	.macro		sm3tt1b, rd, rn, rm, imm2
3362306a36Sopenharmony_ci	.inst		0xce408400 | .L\rd | (.L\rn << 5) | ((\imm2) << 12) | (.L\rm << 16)
3462306a36Sopenharmony_ci	.endm
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	.macro		sm3tt2a, rd, rn, rm, imm2
3762306a36Sopenharmony_ci	.inst		0xce408800 | .L\rd | (.L\rn << 5) | ((\imm2) << 12) | (.L\rm << 16)
3862306a36Sopenharmony_ci	.endm
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	.macro		sm3tt2b, rd, rn, rm, imm2
4162306a36Sopenharmony_ci	.inst		0xce408c00 | .L\rd | (.L\rn << 5) | ((\imm2) << 12) | (.L\rm << 16)
4262306a36Sopenharmony_ci	.endm
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	.macro		round, ab, s0, t0, t1, i
4562306a36Sopenharmony_ci	sm3ss1		v5.4s, v8.4s, \t0\().4s, v9.4s
4662306a36Sopenharmony_ci	shl		\t1\().4s, \t0\().4s, #1
4762306a36Sopenharmony_ci	sri		\t1\().4s, \t0\().4s, #31
4862306a36Sopenharmony_ci	sm3tt1\ab	v8.4s, v5.4s, v10.4s, \i
4962306a36Sopenharmony_ci	sm3tt2\ab	v9.4s, v5.4s, \s0\().4s, \i
5062306a36Sopenharmony_ci	.endm
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	.macro		qround, ab, s0, s1, s2, s3, s4
5362306a36Sopenharmony_ci	.ifnb		\s4
5462306a36Sopenharmony_ci	ext		\s4\().16b, \s1\().16b, \s2\().16b, #12
5562306a36Sopenharmony_ci	ext		v6.16b, \s0\().16b, \s1\().16b, #12
5662306a36Sopenharmony_ci	ext		v7.16b, \s2\().16b, \s3\().16b, #8
5762306a36Sopenharmony_ci	sm3partw1	\s4\().4s, \s0\().4s, \s3\().4s
5862306a36Sopenharmony_ci	.endif
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	eor		v10.16b, \s0\().16b, \s1\().16b
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	round		\ab, \s0, v11, v12, 0
6362306a36Sopenharmony_ci	round		\ab, \s0, v12, v11, 1
6462306a36Sopenharmony_ci	round		\ab, \s0, v11, v12, 2
6562306a36Sopenharmony_ci	round		\ab, \s0, v12, v11, 3
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	.ifnb		\s4
6862306a36Sopenharmony_ci	sm3partw2	\s4\().4s, v7.4s, v6.4s
6962306a36Sopenharmony_ci	.endif
7062306a36Sopenharmony_ci	.endm
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	/*
7362306a36Sopenharmony_ci	 * void sm3_ce_transform(struct sm3_state *sst, u8 const *src,
7462306a36Sopenharmony_ci	 *                       int blocks)
7562306a36Sopenharmony_ci	 */
7662306a36Sopenharmony_ci	.text
7762306a36Sopenharmony_ciSYM_TYPED_FUNC_START(sm3_ce_transform)
7862306a36Sopenharmony_ci	/* load state */
7962306a36Sopenharmony_ci	ld1		{v8.4s-v9.4s}, [x0]
8062306a36Sopenharmony_ci	rev64		v8.4s, v8.4s
8162306a36Sopenharmony_ci	rev64		v9.4s, v9.4s
8262306a36Sopenharmony_ci	ext		v8.16b, v8.16b, v8.16b, #8
8362306a36Sopenharmony_ci	ext		v9.16b, v9.16b, v9.16b, #8
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	adr_l		x8, .Lt
8662306a36Sopenharmony_ci	ldp		s13, s14, [x8]
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	/* load input */
8962306a36Sopenharmony_ci0:	ld1		{v0.16b-v3.16b}, [x1], #64
9062306a36Sopenharmony_ci	sub		w2, w2, #1
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	mov		v15.16b, v8.16b
9362306a36Sopenharmony_ci	mov		v16.16b, v9.16b
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ciCPU_LE(	rev32		v0.16b, v0.16b		)
9662306a36Sopenharmony_ciCPU_LE(	rev32		v1.16b, v1.16b		)
9762306a36Sopenharmony_ciCPU_LE(	rev32		v2.16b, v2.16b		)
9862306a36Sopenharmony_ciCPU_LE(	rev32		v3.16b, v3.16b		)
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	ext		v11.16b, v13.16b, v13.16b, #4
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	qround		a, v0, v1, v2, v3, v4
10362306a36Sopenharmony_ci	qround		a, v1, v2, v3, v4, v0
10462306a36Sopenharmony_ci	qround		a, v2, v3, v4, v0, v1
10562306a36Sopenharmony_ci	qround		a, v3, v4, v0, v1, v2
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	ext		v11.16b, v14.16b, v14.16b, #4
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	qround		b, v4, v0, v1, v2, v3
11062306a36Sopenharmony_ci	qround		b, v0, v1, v2, v3, v4
11162306a36Sopenharmony_ci	qround		b, v1, v2, v3, v4, v0
11262306a36Sopenharmony_ci	qround		b, v2, v3, v4, v0, v1
11362306a36Sopenharmony_ci	qround		b, v3, v4, v0, v1, v2
11462306a36Sopenharmony_ci	qround		b, v4, v0, v1, v2, v3
11562306a36Sopenharmony_ci	qround		b, v0, v1, v2, v3, v4
11662306a36Sopenharmony_ci	qround		b, v1, v2, v3, v4, v0
11762306a36Sopenharmony_ci	qround		b, v2, v3, v4, v0, v1
11862306a36Sopenharmony_ci	qround		b, v3, v4
11962306a36Sopenharmony_ci	qround		b, v4, v0
12062306a36Sopenharmony_ci	qround		b, v0, v1
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	eor		v8.16b, v8.16b, v15.16b
12362306a36Sopenharmony_ci	eor		v9.16b, v9.16b, v16.16b
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	/* handled all input blocks? */
12662306a36Sopenharmony_ci	cbnz		w2, 0b
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	/* save state */
12962306a36Sopenharmony_ci	rev64		v8.4s, v8.4s
13062306a36Sopenharmony_ci	rev64		v9.4s, v9.4s
13162306a36Sopenharmony_ci	ext		v8.16b, v8.16b, v8.16b, #8
13262306a36Sopenharmony_ci	ext		v9.16b, v9.16b, v9.16b, #8
13362306a36Sopenharmony_ci	st1		{v8.4s-v9.4s}, [x0]
13462306a36Sopenharmony_ci	ret
13562306a36Sopenharmony_ciSYM_FUNC_END(sm3_ce_transform)
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	.section	".rodata", "a"
13862306a36Sopenharmony_ci	.align		3
13962306a36Sopenharmony_ci.Lt:	.word		0x79cc4519, 0x9d8a7a87
140