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