summaryrefslogtreecommitdiffstats
path: root/kernel/arch/powerpc/crypto/aes-spe-keys.S
blob: be8090f3d700a6163a69427b63b147283d6e1852 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
/*
 * Key handling functions for PPC AES implementation
 *
 * Copyright (c) 2015 Markus Stockhausen <stockhausen@collogia.de>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 */

#include <asm/ppc_asm.h>

#ifdef __BIG_ENDIAN__
#define LOAD_KEY(d, s, off) \
	lwz		d,off(s);
#else
#define LOAD_KEY(d, s, off) \
	li		r0,off; \
	lwbrx		d,s,r0;
#endif

#define INITIALIZE_KEY \
	stwu		r1,-32(r1);	/* create stack frame		*/ \
	stw		r14,8(r1);	/* save registers		*/ \
	stw		r15,12(r1);					   \
	stw		r16,16(r1);

#define FINALIZE_KEY \
	lwz		r14,8(r1);	/* restore registers		*/ \
	lwz		r15,12(r1);					   \
	lwz		r16,16(r1);					   \
	xor		r5,r5,r5;	/* clear sensitive data		*/ \
	xor		r6,r6,r6;					   \
	xor		r7,r7,r7;					   \
	xor		r8,r8,r8;					   \
	xor		r9,r9,r9;					   \
	xor		r10,r10,r10;					   \
	xor		r11,r11,r11;					   \
	xor		r12,r12,r12;					   \
	addi		r1,r1,32;	/* cleanup stack		*/

#define LS_BOX(r, t1, t2) \
	lis		t2,PPC_AES_4K_ENCTAB@h;				   \
	ori		t2,t2,PPC_AES_4K_ENCTAB@l;			   \
	rlwimi		t2,r,4,20,27;					   \
	lbz		t1,8(t2);					   \
	rlwimi		r,t1,0,24,31;					   \
	rlwimi		t2,r,28,20,27;					   \
	lbz		t1,8(t2);					   \
	rlwimi		r,t1,8,16,23;					   \
	rlwimi		t2,r,20,20,27;					   \
	lbz		t1,8(t2);					   \
	rlwimi		r,t1,16,8,15;					   \
	rlwimi		t2,r,12,20,27;					   \
	lbz		t1,8(t2);					   \
	rlwimi		r,t1,24,0,7;

#define GF8_MUL(out, in, t1, t2) \
	lis t1,0x8080;			/* multiplication in GF8	*/ \
	ori t1,t1,0x8080; 						   \
	and t1,t1,in; 							   \
	srwi t1,t1,7; 							   \
	mulli t1,t1,0x1b; 						   \
	lis t2,0x7f7f; 							   \
	ori t2,t2,0x7f7f; 						   \
	and t2,t2,in; 							   \
	slwi t2,t2,1; 							   \
	xor out,t1,t2;

/*
 * ppc_expand_key_128(u32 *key_enc, const u8 *key)
 *
 * Expand 128 bit key into 176 bytes encryption key. It consists of
 * key itself plus 10 rounds with 16 bytes each
 *
 */
_GLOBAL(ppc_expand_key_128)
	INITIALIZE_KEY
	LOAD_KEY(r5,r4,0)
	LOAD_KEY(r6,r4,4)
	LOAD_KEY(r7,r4,8)
	LOAD_KEY(r8,r4,12)
	stw		r5,0(r3)	/* key[0..3] = input data	*/
	stw		r6,4(r3)
	stw		r7,8(r3)
	stw		r8,12(r3)
	li		r16,10		/* 10 expansion rounds		*/
	lis		r0,0x0100	/* RCO(1)			*/
ppc_expand_128_loop:
	addi		r3,r3,16
	mr		r14,r8		/* apply LS_BOX to 4th temp	*/
	rotlwi		r14,r14,8
	LS_BOX(r14, r15, r4)
	xor		r14,r14,r0
	xor		r5,r5,r14	/* xor next 4 keys		*/
	xor		r6,r6,r5
	xor		r7,r7,r6
	xor		r8,r8,r7
	stw		r5,0(r3)	/* store next 4 keys		*/
	stw		r6,4(r3)
	stw		r7,8(r3)
	stw		r8,12(r3)
	GF8_MUL(r0, r0, r4, r14)	/* multiply RCO by 2 in GF	*/
	subi		r16,r16,1
	cmpwi		r16,0
	bt		eq,ppc_expand_128_end
	b		ppc_expand_128_loop
ppc_expand_128_end:
	FINALIZE_KEY
	blr

/*
 * ppc_expand_key_192(u32 *key_enc, const u8 *key)
 *
 * Expand 192 bit key into 208 bytes encryption key. It consists of key
 * itself plus 12 rounds with 16 bytes each
 *
 */
_GLOBAL(ppc_expand_key_192)
	INITIALIZE_KEY
	LOAD_KEY(r5,r4,0)
	LOAD_KEY(r6,r4,4)
	LOAD_KEY(r7,r4,8)
	LOAD_KEY(r8,r4,12)
	LOAD_KEY(r9,r4,16)
	LOAD_KEY(r10,r4,20)
	stw		r5,0(r3)
	stw		r6,4(r3)
	stw		r7,8(r3)
	stw		r8,12(r3)
	stw		r9,16(r3)
	stw		r10,20(r3)
	li		r16,8		/* 8 expansion rounds		*/
	lis		r0,0x0100	/* RCO(1)			*/
ppc_expand_192_loop:
	addi		r3,r3,24
	mr		r14,r10		/* apply LS_BOX to 6th temp	*/
	rotlwi		r14,r14,8
	LS_BOX(r14, r15, r4)
	xor		r14,r14,r0
	xor		r5,r5,r14	/* xor next 6 keys		*/
	xor		r6,r6,r5
	xor		r7,r7,r6
	xor		r8,r8,r7
	xor		r9,r9,r8
	xor		r10,r10,r9
	stw		r5,0(r3)
	stw		r6,4(r3)
	stw		r7,8(r3)
	stw		r8,12(r3)
	subi		r16,r16,1
	cmpwi		r16,0		/* last round early kick out	*/
	bt		eq,ppc_expand_192_end
	stw		r9,16(r3)
	stw		r10,20(r3)
	GF8_MUL(r0, r0, r4, r14)	/* multiply RCO GF8		*/
	b		ppc_expand_192_loop
ppc_expand_192_end:
	FINALIZE_KEY
	blr

/*
 * ppc_expand_key_256(u32 *key_enc, const u8 *key)
 *
 * Expand 256 bit key into 240 bytes encryption key. It consists of key
 * itself plus 14 rounds with 16 bytes each
 *
 */
_GLOBAL(ppc_expand_key_256)
	INITIALIZE_KEY
	LOAD_KEY(r5,r4,0)
	LOAD_KEY(r6,r4,4)
	LOAD_KEY(r7,r4,8)
	LOAD_KEY(r8,r4,12)
	LOAD_KEY(r9,r4,16)
	LOAD_KEY(r10,r4,20)
	LOAD_KEY(r11,r4,24)
	LOAD_KEY(r12,r4,28)
	stw		r5,0(r3)
	stw		r6,4(r3)
	stw		r7,8(r3)
	stw		r8,12(r3)
	stw		r9,16(r3)
	stw		r10,20(r3)
	stw		r11,24(r3)
	stw		r12,28(r3)
	li		r16,7		/* 7 expansion rounds		*/
	lis		r0,0x0100	/* RCO(1)			*/
ppc_expand_256_loop:
	addi		r3,r3,32
	mr		r14,r12		/* apply LS_BOX to 8th temp	*/
	rotlwi		r14,r14,8
	LS_BOX(r14, r15, r4)
	xor		r14,r14,r0
	xor		r5,r5,r14	/* xor 4 keys			*/
	xor		r6,r6,r5
	xor		r7,r7,r6
	xor		r8,r8,r7
	mr		r14,r8
	LS_BOX(r14, r15, r4)		/* apply LS_BOX to 4th temp	*/
	xor		r9,r9,r14	/* xor 4 keys			*/
	xor		r10,r10,r9
	xor		r11,r11,r10
	xor		r12,r12,r11
	stw		r5,0(r3)
	stw		r6,4(r3)
	stw		r7,8(r3)
	stw		r8,12(r3)
	subi		r16,r16,1
	cmpwi		r16,0		/* last round early kick out	*/
	bt		eq,ppc_expand_256_end
	stw		r9,16(r3)
	stw		r10,20(r3)
	stw		r11,24(r3)
	stw		r12,28(r3)
	GF8_MUL(r0, r0, r4, r14)
	b		ppc_expand_256_loop
ppc_expand_256_end:
	FINALIZE_KEY
	blr

/*
 * ppc_generate_decrypt_key: derive decryption key from encryption key
 * number of bytes to handle are calculated from length of key (16/24/32)
 *
 */
_GLOBAL(ppc_generate_decrypt_key)
	addi		r6,r5,24
	slwi		r6,r6,2
	lwzx		r7,r4,r6	/* first/last 4 words are same	*/
	stw		r7,0(r3)
	lwz		r7,0(r4)
	stwx		r7,r3,r6
	addi		r6,r6,4
	lwzx		r7,r4,r6
	stw		r7,4(r3)
	lwz		r7,4(r4)
	stwx		r7,r3,r6
	addi		r6,r6,4
	lwzx		r7,r4,r6
	stw		r7,8(r3)
	lwz		r7,8(r4)
	stwx		r7,r3,r6
	addi		r6,r6,4
	lwzx		r7,r4,r6
	stw		r7,12(r3)
	lwz		r7,12(r4)
	stwx		r7,r3,r6
	addi		r3,r3,16
	add		r4,r4,r6
	subi		r4,r4,28
	addi		r5,r5,20
	srwi		r5,r5,2
ppc_generate_decrypt_block:
	li	r6,4
	mtctr	r6
ppc_generate_decrypt_word:
	lwz		r6,0(r4)
	GF8_MUL(r7, r6, r0, r7)
	GF8_MUL(r8, r7, r0, r8)
	GF8_MUL(r9, r8, r0, r9)
	xor		r10,r9,r6
	xor		r11,r7,r8
	xor		r11,r11,r9
	xor		r12,r7,r10
	rotrwi		r12,r12,24
	xor		r11,r11,r12
	xor		r12,r8,r10
	rotrwi		r12,r12,16
	xor		r11,r11,r12
	rotrwi		r12,r10,8
	xor		r11,r11,r12
	stw		r11,0(r3)
	addi		r3,r3,4
	addi		r4,r4,4
	bdnz		ppc_generate_decrypt_word
	subi		r4,r4,32
	subi		r5,r5,1
	cmpwi		r5,0
	bt		gt,ppc_generate_decrypt_block
	blr