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

source code of linux/arch/powerpc/crypto/aes-spe-keys.S