1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * sha2-ce-core.S - core SHA-224/SHA-256 transform using v8 Crypto Extensions
4  *
5  * Copyright (C) 2014 Linaro Ltd <ard.biesheuvel@linaro.org>
6  */
7 
8 #include <linux/linkage.h>
9 #include <asm/assembler.h>
10 
11 	.text
12 	.arch		armv8-a+crypto
13 
14 	dga		.req	q20
15 	dgav		.req	v20
16 	dgb		.req	q21
17 	dgbv		.req	v21
18 
19 	t0		.req	v22
20 	t1		.req	v23
21 
22 	dg0q		.req	q24
23 	dg0v		.req	v24
24 	dg1q		.req	q25
25 	dg1v		.req	v25
26 	dg2q		.req	q26
27 	dg2v		.req	v26
28 
29 	.macro		add_only, ev, rc, s0
30 	mov		dg2v.16b, dg0v.16b
31 	.ifeq		\ev
32 	add		t1.4s, v\s0\().4s, \rc\().4s
33 	sha256h		dg0q, dg1q, t0.4s
34 	sha256h2	dg1q, dg2q, t0.4s
35 	.else
36 	.ifnb		\s0
37 	add		t0.4s, v\s0\().4s, \rc\().4s
38 	.endif
39 	sha256h		dg0q, dg1q, t1.4s
40 	sha256h2	dg1q, dg2q, t1.4s
41 	.endif
42 	.endm
43 
44 	.macro		add_update, ev, rc, s0, s1, s2, s3
45 	sha256su0	v\s0\().4s, v\s1\().4s
46 	add_only	\ev, \rc, \s1
47 	sha256su1	v\s0\().4s, v\s2\().4s, v\s3\().4s
48 	.endm
49 
50 	/*
51 	 * The SHA-256 round constants
52 	 */
53 	.section	".rodata", "a"
54 	.align		4
55 .Lsha2_rcon:
56 	.word		0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5
57 	.word		0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5
58 	.word		0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3
59 	.word		0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174
60 	.word		0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc
61 	.word		0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da
62 	.word		0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
63 	.word		0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967
64 	.word		0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13
65 	.word		0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85
66 	.word		0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3
67 	.word		0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070
68 	.word		0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5
69 	.word		0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
70 	.word		0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208
71 	.word		0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
72 
73 	/*
74 	 * void sha2_ce_transform(struct sha256_ce_state *sst, u8 const *src,
75 	 *			  int blocks)
76 	 */
77 	.text
78 SYM_FUNC_START(sha2_ce_transform)
79 	/* load round constants */
80 	adr_l		x8, .Lsha2_rcon
81 	ld1		{ v0.4s- v3.4s}, [x8], #64
82 	ld1		{ v4.4s- v7.4s}, [x8], #64
83 	ld1		{ v8.4s-v11.4s}, [x8], #64
84 	ld1		{v12.4s-v15.4s}, [x8]
85 
86 	/* load state */
87 	ld1		{dgav.4s, dgbv.4s}, [x0]
88 
89 	/* load sha256_ce_state::finalize */
90 	ldr_l		w4, sha256_ce_offsetof_finalize, x4
91 	ldr		w4, [x0, x4]
92 
93 	/* load input */
94 0:	ld1		{v16.4s-v19.4s}, [x1], #64
95 	sub		w2, w2, #1
96 
97 CPU_LE(	rev32		v16.16b, v16.16b	)
98 CPU_LE(	rev32		v17.16b, v17.16b	)
99 CPU_LE(	rev32		v18.16b, v18.16b	)
100 CPU_LE(	rev32		v19.16b, v19.16b	)
101 
102 1:	add		t0.4s, v16.4s, v0.4s
103 	mov		dg0v.16b, dgav.16b
104 	mov		dg1v.16b, dgbv.16b
105 
106 	add_update	0,  v1, 16, 17, 18, 19
107 	add_update	1,  v2, 17, 18, 19, 16
108 	add_update	0,  v3, 18, 19, 16, 17
109 	add_update	1,  v4, 19, 16, 17, 18
110 
111 	add_update	0,  v5, 16, 17, 18, 19
112 	add_update	1,  v6, 17, 18, 19, 16
113 	add_update	0,  v7, 18, 19, 16, 17
114 	add_update	1,  v8, 19, 16, 17, 18
115 
116 	add_update	0,  v9, 16, 17, 18, 19
117 	add_update	1, v10, 17, 18, 19, 16
118 	add_update	0, v11, 18, 19, 16, 17
119 	add_update	1, v12, 19, 16, 17, 18
120 
121 	add_only	0, v13, 17
122 	add_only	1, v14, 18
123 	add_only	0, v15, 19
124 	add_only	1
125 
126 	/* update state */
127 	add		dgav.4s, dgav.4s, dg0v.4s
128 	add		dgbv.4s, dgbv.4s, dg1v.4s
129 
130 	/* handled all input blocks? */
131 	cbz		w2, 2f
132 	cond_yield	3f, x5, x6
133 	b		0b
134 
135 	/*
136 	 * Final block: add padding and total bit count.
137 	 * Skip if the input size was not a round multiple of the block size,
138 	 * the padding is handled by the C code in that case.
139 	 */
140 2:	cbz		x4, 3f
141 	ldr_l		w4, sha256_ce_offsetof_count, x4
142 	ldr		x4, [x0, x4]
143 	movi		v17.2d, #0
144 	mov		x8, #0x80000000
145 	movi		v18.2d, #0
146 	ror		x7, x4, #29		// ror(lsl(x4, 3), 32)
147 	fmov		d16, x8
148 	mov		x4, #0
149 	mov		v19.d[0], xzr
150 	mov		v19.d[1], x7
151 	b		1b
152 
153 	/* store new state */
154 3:	st1		{dgav.4s, dgbv.4s}, [x0]
155 	mov		w0, w2
156 	ret
157 SYM_FUNC_END(sha2_ce_transform)
158