1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * Key handling functions for PPC AES implementation
4 *
5 * Copyright (c) 2015 Markus Stockhausen <stockhausen@collogia.de>
6 */
7
8#include <asm/ppc_asm.h>
9
10#ifdef __BIG_ENDIAN__
11#define LOAD_KEY(d, s, off) \
12	lwz		d,off(s);
13#else
14#define LOAD_KEY(d, s, off) \
15	li		r0,off; \
16	lwbrx		d,s,r0;
17#endif
18
19#define INITIALIZE_KEY \
20	stwu		r1,-32(r1);	/* create stack frame		*/ \
21	stw		r14,8(r1);	/* save registers		*/ \
22	stw		r15,12(r1);					   \
23	stw		r16,16(r1);
24
25#define FINALIZE_KEY \
26	lwz		r14,8(r1);	/* restore registers		*/ \
27	lwz		r15,12(r1);					   \
28	lwz		r16,16(r1);					   \
29	xor		r5,r5,r5;	/* clear sensitive data		*/ \
30	xor		r6,r6,r6;					   \
31	xor		r7,r7,r7;					   \
32	xor		r8,r8,r8;					   \
33	xor		r9,r9,r9;					   \
34	xor		r10,r10,r10;					   \
35	xor		r11,r11,r11;					   \
36	xor		r12,r12,r12;					   \
37	addi		r1,r1,32;	/* cleanup stack		*/
38
39#define LS_BOX(r, t1, t2) \
40	lis		t2,PPC_AES_4K_ENCTAB@h;				   \
41	ori		t2,t2,PPC_AES_4K_ENCTAB@l;			   \
42	rlwimi		t2,r,4,20,27;					   \
43	lbz		t1,8(t2);					   \
44	rlwimi		r,t1,0,24,31;					   \
45	rlwimi		t2,r,28,20,27;					   \
46	lbz		t1,8(t2);					   \
47	rlwimi		r,t1,8,16,23;					   \
48	rlwimi		t2,r,20,20,27;					   \
49	lbz		t1,8(t2);					   \
50	rlwimi		r,t1,16,8,15;					   \
51	rlwimi		t2,r,12,20,27;					   \
52	lbz		t1,8(t2);					   \
53	rlwimi		r,t1,24,0,7;
54
55#define GF8_MUL(out, in, t1, t2) \
56	lis t1,0x8080;			/* multiplication in GF8	*/ \
57	ori t1,t1,0x8080; 						   \
58	and t1,t1,in; 							   \
59	srwi t1,t1,7; 							   \
60	mulli t1,t1,0x1b; 						   \
61	lis t2,0x7f7f; 							   \
62	ori t2,t2,0x7f7f; 						   \
63	and t2,t2,in; 							   \
64	slwi t2,t2,1; 							   \
65	xor out,t1,t2;
66
67/*
68 * ppc_expand_key_128(u32 *key_enc, const u8 *key)
69 *
70 * Expand 128 bit key into 176 bytes encryption key. It consists of
71 * key itself plus 10 rounds with 16 bytes each
72 *
73 */
74_GLOBAL(ppc_expand_key_128)
75	INITIALIZE_KEY
76	LOAD_KEY(r5,r4,0)
77	LOAD_KEY(r6,r4,4)
78	LOAD_KEY(r7,r4,8)
79	LOAD_KEY(r8,r4,12)
80	stw		r5,0(r3)	/* key[0..3] = input data	*/
81	stw		r6,4(r3)
82	stw		r7,8(r3)
83	stw		r8,12(r3)
84	li		r16,10		/* 10 expansion rounds		*/
85	lis		r0,0x0100	/* RCO(1)			*/
86ppc_expand_128_loop:
87	addi		r3,r3,16
88	mr		r14,r8		/* apply LS_BOX to 4th temp	*/
89	rotlwi		r14,r14,8
90	LS_BOX(r14, r15, r4)
91	xor		r14,r14,r0
92	xor		r5,r5,r14	/* xor next 4 keys		*/
93	xor		r6,r6,r5
94	xor		r7,r7,r6
95	xor		r8,r8,r7
96	stw		r5,0(r3)	/* store next 4 keys		*/
97	stw		r6,4(r3)
98	stw		r7,8(r3)
99	stw		r8,12(r3)
100	GF8_MUL(r0, r0, r4, r14)	/* multiply RCO by 2 in GF	*/
101	subi		r16,r16,1
102	cmpwi		r16,0
103	bt		eq,ppc_expand_128_end
104	b		ppc_expand_128_loop
105ppc_expand_128_end:
106	FINALIZE_KEY
107	blr
108
109/*
110 * ppc_expand_key_192(u32 *key_enc, const u8 *key)
111 *
112 * Expand 192 bit key into 208 bytes encryption key. It consists of key
113 * itself plus 12 rounds with 16 bytes each
114 *
115 */
116_GLOBAL(ppc_expand_key_192)
117	INITIALIZE_KEY
118	LOAD_KEY(r5,r4,0)
119	LOAD_KEY(r6,r4,4)
120	LOAD_KEY(r7,r4,8)
121	LOAD_KEY(r8,r4,12)
122	LOAD_KEY(r9,r4,16)
123	LOAD_KEY(r10,r4,20)
124	stw		r5,0(r3)
125	stw		r6,4(r3)
126	stw		r7,8(r3)
127	stw		r8,12(r3)
128	stw		r9,16(r3)
129	stw		r10,20(r3)
130	li		r16,8		/* 8 expansion rounds		*/
131	lis		r0,0x0100	/* RCO(1)			*/
132ppc_expand_192_loop:
133	addi		r3,r3,24
134	mr		r14,r10		/* apply LS_BOX to 6th temp	*/
135	rotlwi		r14,r14,8
136	LS_BOX(r14, r15, r4)
137	xor		r14,r14,r0
138	xor		r5,r5,r14	/* xor next 6 keys		*/
139	xor		r6,r6,r5
140	xor		r7,r7,r6
141	xor		r8,r8,r7
142	xor		r9,r9,r8
143	xor		r10,r10,r9
144	stw		r5,0(r3)
145	stw		r6,4(r3)
146	stw		r7,8(r3)
147	stw		r8,12(r3)
148	subi		r16,r16,1
149	cmpwi		r16,0		/* last round early kick out	*/
150	bt		eq,ppc_expand_192_end
151	stw		r9,16(r3)
152	stw		r10,20(r3)
153	GF8_MUL(r0, r0, r4, r14)	/* multiply RCO GF8		*/
154	b		ppc_expand_192_loop
155ppc_expand_192_end:
156	FINALIZE_KEY
157	blr
158
159/*
160 * ppc_expand_key_256(u32 *key_enc, const u8 *key)
161 *
162 * Expand 256 bit key into 240 bytes encryption key. It consists of key
163 * itself plus 14 rounds with 16 bytes each
164 *
165 */
166_GLOBAL(ppc_expand_key_256)
167	INITIALIZE_KEY
168	LOAD_KEY(r5,r4,0)
169	LOAD_KEY(r6,r4,4)
170	LOAD_KEY(r7,r4,8)
171	LOAD_KEY(r8,r4,12)
172	LOAD_KEY(r9,r4,16)
173	LOAD_KEY(r10,r4,20)
174	LOAD_KEY(r11,r4,24)
175	LOAD_KEY(r12,r4,28)
176	stw		r5,0(r3)
177	stw		r6,4(r3)
178	stw		r7,8(r3)
179	stw		r8,12(r3)
180	stw		r9,16(r3)
181	stw		r10,20(r3)
182	stw		r11,24(r3)
183	stw		r12,28(r3)
184	li		r16,7		/* 7 expansion rounds		*/
185	lis		r0,0x0100	/* RCO(1)			*/
186ppc_expand_256_loop:
187	addi		r3,r3,32
188	mr		r14,r12		/* apply LS_BOX to 8th temp	*/
189	rotlwi		r14,r14,8
190	LS_BOX(r14, r15, r4)
191	xor		r14,r14,r0
192	xor		r5,r5,r14	/* xor 4 keys			*/
193	xor		r6,r6,r5
194	xor		r7,r7,r6
195	xor		r8,r8,r7
196	mr		r14,r8
197	LS_BOX(r14, r15, r4)		/* apply LS_BOX to 4th temp	*/
198	xor		r9,r9,r14	/* xor 4 keys			*/
199	xor		r10,r10,r9
200	xor		r11,r11,r10
201	xor		r12,r12,r11
202	stw		r5,0(r3)
203	stw		r6,4(r3)
204	stw		r7,8(r3)
205	stw		r8,12(r3)
206	subi		r16,r16,1
207	cmpwi		r16,0		/* last round early kick out	*/
208	bt		eq,ppc_expand_256_end
209	stw		r9,16(r3)
210	stw		r10,20(r3)
211	stw		r11,24(r3)
212	stw		r12,28(r3)
213	GF8_MUL(r0, r0, r4, r14)
214	b		ppc_expand_256_loop
215ppc_expand_256_end:
216	FINALIZE_KEY
217	blr
218
219/*
220 * ppc_generate_decrypt_key: derive decryption key from encryption key
221 * number of bytes to handle are calculated from length of key (16/24/32)
222 *
223 */
224_GLOBAL(ppc_generate_decrypt_key)
225	addi		r6,r5,24
226	slwi		r6,r6,2
227	lwzx		r7,r4,r6	/* first/last 4 words are same	*/
228	stw		r7,0(r3)
229	lwz		r7,0(r4)
230	stwx		r7,r3,r6
231	addi		r6,r6,4
232	lwzx		r7,r4,r6
233	stw		r7,4(r3)
234	lwz		r7,4(r4)
235	stwx		r7,r3,r6
236	addi		r6,r6,4
237	lwzx		r7,r4,r6
238	stw		r7,8(r3)
239	lwz		r7,8(r4)
240	stwx		r7,r3,r6
241	addi		r6,r6,4
242	lwzx		r7,r4,r6
243	stw		r7,12(r3)
244	lwz		r7,12(r4)
245	stwx		r7,r3,r6
246	addi		r3,r3,16
247	add		r4,r4,r6
248	subi		r4,r4,28
249	addi		r5,r5,20
250	srwi		r5,r5,2
251ppc_generate_decrypt_block:
252	li	r6,4
253	mtctr	r6
254ppc_generate_decrypt_word:
255	lwz		r6,0(r4)
256	GF8_MUL(r7, r6, r0, r7)
257	GF8_MUL(r8, r7, r0, r8)
258	GF8_MUL(r9, r8, r0, r9)
259	xor		r10,r9,r6
260	xor		r11,r7,r8
261	xor		r11,r11,r9
262	xor		r12,r7,r10
263	rotrwi		r12,r12,24
264	xor		r11,r11,r12
265	xor		r12,r8,r10
266	rotrwi		r12,r12,16
267	xor		r11,r11,r12
268	rotrwi		r12,r10,8
269	xor		r11,r11,r12
270	stw		r11,0(r3)
271	addi		r3,r3,4
272	addi		r4,r4,4
273	bdnz		ppc_generate_decrypt_word
274	subi		r4,r4,32
275	subi		r5,r5,1
276	cmpwi		r5,0
277	bt		gt,ppc_generate_decrypt_block
278	blr
279