1 #include "bflb_sec_aes.h"
2 #include "hardware/sec_eng_reg.h"
3
4 #define CONFIG_BFLB_AES_USE_BE
5
6 #define BFLB_PUT_LE32(p) ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0]))
7 #define BFLB_PUT_BE32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]))
8
9 volatile uint8_t hw_key_sel = 1;
10
bflb_aes_init(struct bflb_device_s * dev)11 void bflb_aes_init(struct bflb_device_s *dev)
12 {
13 uint32_t regval;
14 uint32_t reg_base;
15
16 reg_base = dev->reg_base;
17
18 #ifdef CONFIG_BFLB_AES_USE_BE
19 putreg32(0x1f, reg_base + SEC_ENG_SE_AES_0_ENDIAN_OFFSET);
20 #else
21 putreg32(0x10, reg_base + SEC_ENG_SE_AES_0_ENDIAN_OFFSET);
22 #endif
23
24 regval = getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
25 regval |= SEC_ENG_SE_AES_0_EN;
26 putreg32(regval, reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
27 }
28
bflb_aes_deinit(struct bflb_device_s * dev)29 void bflb_aes_deinit(struct bflb_device_s *dev)
30 {
31 uint32_t regval;
32 uint32_t reg_base;
33
34 reg_base = dev->reg_base;
35
36 regval = getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
37 regval &= ~SEC_ENG_SE_AES_0_EN;
38 putreg32(regval, reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
39 }
40
bflb_aes_set_hwkey(uint8_t keysel)41 void bflb_aes_set_hwkey(uint8_t keysel)
42 {
43 hw_key_sel = keysel;
44 }
45
bflb_aes_set_mode(struct bflb_device_s * dev,uint8_t mode)46 void bflb_aes_set_mode(struct bflb_device_s *dev, uint8_t mode)
47 {
48 uint32_t regval;
49 uint32_t reg_base;
50
51 reg_base = dev->reg_base;
52
53 regval = getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
54 regval &= ~SEC_ENG_SE_AES_0_BLOCK_MODE_MASK;
55 regval |= (mode << SEC_ENG_SE_AES_0_BLOCK_MODE_SHIFT);
56
57 if (mode == AES_MODE_CTR) {
58 regval |= SEC_ENG_SE_AES_0_DEC_KEY_SEL;
59 } else {
60 regval &= ~SEC_ENG_SE_AES_0_DEC_KEY_SEL; /* clear key to set new key */
61 }
62
63 putreg32(regval, reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
64 }
65
bflb_aes_setkey(struct bflb_device_s * dev,const uint8_t * key,uint16_t keybits)66 void bflb_aes_setkey(struct bflb_device_s *dev, const uint8_t *key, uint16_t keybits)
67 {
68 uint32_t regval;
69 uint32_t reg_base;
70 uint8_t mode;
71 uint8_t *temp_key = (uint8_t *)key;
72
73 reg_base = dev->reg_base;
74
75 regval = getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
76 mode = (regval & SEC_ENG_SE_AES_0_BLOCK_MODE_MASK) >> SEC_ENG_SE_AES_0_BLOCK_MODE_SHIFT;
77
78 regval &= ~SEC_ENG_SE_AES_0_MODE_MASK;
79 regval &= ~SEC_ENG_SE_AES_0_HW_KEY_EN;
80 if (key == NULL) {
81 regval |= SEC_ENG_SE_AES_0_HW_KEY_EN;
82 }
83
84 if (keybits == 128) {
85 regval |= (0 << SEC_ENG_SE_AES_0_MODE_SHIFT);
86 } else if (keybits == 192) {
87 regval |= (2 << SEC_ENG_SE_AES_0_MODE_SHIFT);
88 } else if (keybits == 256) {
89 regval |= (1 << SEC_ENG_SE_AES_0_MODE_SHIFT);
90 } else {
91 regval |= (3 << SEC_ENG_SE_AES_0_MODE_SHIFT);
92 }
93 putreg32(regval, reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
94
95 if (key == NULL) {
96 regval = getreg32(reg_base + SEC_ENG_SE_AES_0_KEY_SEL_OFFSET);
97 regval &= ~SEC_ENG_SE_AES_0_KEY_SEL_MASK;
98 regval |= (hw_key_sel << SEC_ENG_SE_AES_0_KEY_SEL_SHIFT);
99 putreg32(regval, reg_base + SEC_ENG_SE_AES_0_KEY_SEL_OFFSET);
100
101 regval = getreg32(reg_base + SEC_ENG_SE_AES_1_KEY_SEL_OFFSET);
102 regval &= ~SEC_ENG_SE_AES_1_KEY_SEL_MASK;
103 regval |= (hw_key_sel << SEC_ENG_SE_AES_1_KEY_SEL_SHIFT);
104 putreg32(regval, reg_base + SEC_ENG_SE_AES_1_KEY_SEL_OFFSET);
105 } else {
106 putreg32(BFLB_PUT_LE32(temp_key), reg_base + SEC_ENG_SE_AES_0_KEY_0_OFFSET);
107 temp_key += 4;
108 putreg32(BFLB_PUT_LE32(temp_key), reg_base + SEC_ENG_SE_AES_0_KEY_1_OFFSET);
109 temp_key += 4;
110 putreg32(BFLB_PUT_LE32(temp_key), reg_base + SEC_ENG_SE_AES_0_KEY_2_OFFSET);
111 temp_key += 4;
112 putreg32(BFLB_PUT_LE32(temp_key), reg_base + SEC_ENG_SE_AES_0_KEY_3_OFFSET);
113 temp_key += 4;
114
115 if (keybits == 192) {
116 putreg32(BFLB_PUT_LE32(temp_key), reg_base + SEC_ENG_SE_AES_0_KEY_4_OFFSET);
117 temp_key += 4;
118 putreg32(BFLB_PUT_LE32(temp_key), reg_base + SEC_ENG_SE_AES_0_KEY_5_OFFSET);
119 temp_key += 4;
120 } else if ((keybits == 256) || (mode == AES_MODE_XTS)) {
121 putreg32(BFLB_PUT_LE32(temp_key), reg_base + SEC_ENG_SE_AES_0_KEY_4_OFFSET);
122 temp_key += 4;
123 putreg32(BFLB_PUT_LE32(temp_key), reg_base + SEC_ENG_SE_AES_0_KEY_5_OFFSET);
124 temp_key += 4;
125 putreg32(BFLB_PUT_LE32(temp_key), reg_base + SEC_ENG_SE_AES_0_KEY_6_OFFSET);
126 temp_key += 4;
127 putreg32(BFLB_PUT_LE32(temp_key), reg_base + SEC_ENG_SE_AES_0_KEY_7_OFFSET);
128 temp_key += 4;
129 }
130 }
131 }
132
bflb_aes_encrypt(struct bflb_device_s * dev,const uint8_t * input,const uint8_t * iv,uint8_t * output,uint32_t len)133 int bflb_aes_encrypt(struct bflb_device_s *dev,
134 const uint8_t *input,
135 const uint8_t *iv,
136 uint8_t *output,
137 uint32_t len)
138 {
139 uint32_t regval;
140 uint32_t reg_base;
141 uint64_t start_time;
142 uint8_t mode;
143 uint8_t *temp_iv = (uint8_t *)iv;
144
145 reg_base = dev->reg_base;
146
147 if (len % 16) {
148 return -EINVAL;
149 }
150
151 regval = getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
152 regval &= ~SEC_ENG_SE_AES_0_TRIG_1T;
153 if (temp_iv) {
154 regval &= ~SEC_ENG_SE_AES_0_IV_SEL; /* Clear aes iv sel to select new iv */
155 } else {
156 regval |= SEC_ENG_SE_AES_0_IV_SEL; /* Clear aes iv sel to select last iv */
157 }
158 regval &= ~SEC_ENG_SE_AES_0_DEC_EN; /* Set AES encryption */
159 regval &= ~SEC_ENG_SE_AES_0_MSG_LEN_MASK;
160 regval |= SEC_ENG_SE_AES_0_INT_CLR_1T;
161 regval |= ((len / 16) << SEC_ENG_SE_AES_0_MSG_LEN_SHIFT);
162 putreg32(regval, reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
163
164 mode = (regval & SEC_ENG_SE_AES_0_BLOCK_MODE_MASK) >> SEC_ENG_SE_AES_0_BLOCK_MODE_SHIFT;
165
166 if (temp_iv) {
167 if (mode == AES_MODE_XTS) {
168 putreg32(BFLB_PUT_BE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_3_OFFSET);
169 temp_iv += 4;
170 putreg32(BFLB_PUT_BE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_2_OFFSET);
171 temp_iv += 4;
172 putreg32(BFLB_PUT_BE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_1_OFFSET);
173 temp_iv += 4;
174 putreg32(BFLB_PUT_BE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_0_OFFSET);
175 temp_iv += 4;
176 } else {
177 putreg32(BFLB_PUT_LE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_0_OFFSET);
178 temp_iv += 4;
179 putreg32(BFLB_PUT_LE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_1_OFFSET);
180 temp_iv += 4;
181 putreg32(BFLB_PUT_LE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_2_OFFSET);
182 temp_iv += 4;
183 putreg32(BFLB_PUT_LE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_3_OFFSET);
184 temp_iv += 4;
185 }
186 }
187
188 /* Set input and output address */
189 putreg32((uint32_t)input, reg_base + SEC_ENG_SE_AES_0_MSA_OFFSET);
190 putreg32((uint32_t)output, reg_base + SEC_ENG_SE_AES_0_MDA_OFFSET);
191
192 regval = getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
193 regval |= SEC_ENG_SE_AES_0_TRIG_1T;
194 putreg32(regval, reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
195
196 start_time = bflb_mtimer_get_time_ms();
197 while (getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET) & SEC_ENG_SE_AES_0_BUSY) {
198 if ((bflb_mtimer_get_time_ms() - start_time) > 100) {
199 return -ETIMEDOUT;
200 }
201 }
202 return 0;
203 }
204
bflb_aes_decrypt(struct bflb_device_s * dev,const uint8_t * input,const uint8_t * iv,uint8_t * output,uint32_t len)205 int bflb_aes_decrypt(struct bflb_device_s *dev,
206 const uint8_t *input,
207 const uint8_t *iv,
208 uint8_t *output,
209 uint32_t len)
210 {
211 uint32_t regval;
212 uint32_t reg_base;
213 uint64_t start_time;
214 uint8_t mode;
215 uint8_t *temp_iv = (uint8_t *)iv;
216
217 reg_base = dev->reg_base;
218
219 if (len % 16) {
220 return -EINVAL;
221 }
222
223 regval = getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
224 regval &= ~SEC_ENG_SE_AES_0_TRIG_1T;
225 if (temp_iv) {
226 regval &= ~SEC_ENG_SE_AES_0_IV_SEL; /* Clear aes iv sel to select new iv */
227 } else {
228 regval |= SEC_ENG_SE_AES_0_IV_SEL; /* Clear aes iv sel to select last iv */
229 }
230 regval |= SEC_ENG_SE_AES_0_DEC_EN; /* Set AES decryption */
231 regval |= SEC_ENG_SE_AES_0_INT_CLR_1T;
232 regval &= ~SEC_ENG_SE_AES_0_MSG_LEN_MASK;
233 regval |= ((len / 16) << SEC_ENG_SE_AES_0_MSG_LEN_SHIFT);
234 putreg32(regval, reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
235
236 mode = (regval & SEC_ENG_SE_AES_0_BLOCK_MODE_MASK) >> SEC_ENG_SE_AES_0_BLOCK_MODE_SHIFT;
237
238 if (temp_iv) {
239 if (mode == AES_MODE_XTS) {
240 putreg32(BFLB_PUT_BE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_3_OFFSET);
241 temp_iv += 4;
242 putreg32(BFLB_PUT_BE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_2_OFFSET);
243 temp_iv += 4;
244 putreg32(BFLB_PUT_BE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_1_OFFSET);
245 temp_iv += 4;
246 putreg32(BFLB_PUT_BE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_0_OFFSET);
247 temp_iv += 4;
248 } else {
249 putreg32(BFLB_PUT_LE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_0_OFFSET);
250 temp_iv += 4;
251 putreg32(BFLB_PUT_LE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_1_OFFSET);
252 temp_iv += 4;
253 putreg32(BFLB_PUT_LE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_2_OFFSET);
254 temp_iv += 4;
255 putreg32(BFLB_PUT_LE32(temp_iv), reg_base + SEC_ENG_SE_AES_0_IV_3_OFFSET);
256 temp_iv += 4;
257 }
258 }
259
260 /* Set input and output address */
261 putreg32((uint32_t)input, reg_base + SEC_ENG_SE_AES_0_MSA_OFFSET);
262 putreg32((uint32_t)output, reg_base + SEC_ENG_SE_AES_0_MDA_OFFSET);
263
264 regval = getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
265 regval |= SEC_ENG_SE_AES_0_TRIG_1T;
266 putreg32(regval, reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
267
268 start_time = bflb_mtimer_get_time_ms();
269 while (getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET) & SEC_ENG_SE_AES_0_BUSY) {
270 if ((bflb_mtimer_get_time_ms() - start_time) > 100) {
271 return -ETIMEDOUT;
272 }
273 }
274 return 0;
275 }
276
bflb_aes_link_init(struct bflb_device_s * dev)277 void bflb_aes_link_init(struct bflb_device_s *dev)
278 {
279 uint32_t regval;
280 uint32_t reg_base;
281
282 reg_base = dev->reg_base;
283
284 #ifdef CONFIG_BFLB_AES_USE_BE
285 putreg32(0x1f, reg_base + SEC_ENG_SE_AES_0_ENDIAN_OFFSET);
286 #else
287 putreg32(0x10, reg_base + SEC_ENG_SE_AES_0_ENDIAN_OFFSET);
288 #endif
289
290 regval = getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
291 regval |= SEC_ENG_SE_AES_0_LINK_MODE;
292 regval |= SEC_ENG_SE_AES_0_EN;
293 putreg32(regval, reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
294 }
295
bflb_aes_link_deinit(struct bflb_device_s * dev)296 void bflb_aes_link_deinit(struct bflb_device_s *dev)
297 {
298 uint32_t regval;
299 uint32_t reg_base;
300
301 reg_base = dev->reg_base;
302
303 regval = getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
304 regval &= ~SEC_ENG_SE_AES_0_LINK_MODE;
305 regval &= ~SEC_ENG_SE_AES_0_EN;
306 putreg32(regval, reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
307 }
308
bflb_aes_link_update(struct bflb_device_s * dev,uint32_t link_addr,const uint8_t * input,uint8_t * output,uint32_t len)309 int bflb_aes_link_update(struct bflb_device_s *dev,
310 uint32_t link_addr,
311 const uint8_t *input,
312 uint8_t *output,
313 uint32_t len)
314 {
315 uint32_t regval;
316 uint32_t reg_base;
317 uint64_t start_time;
318
319 reg_base = dev->reg_base;
320
321 if ((len % 16) || ((link_addr & 0x03))) {
322 return -EINVAL;
323 }
324
325 regval = getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
326 regval &= ~SEC_ENG_SE_AES_0_TRIG_1T;
327 putreg32(regval, reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
328
329 /* Set link address */
330 putreg32(link_addr, reg_base + SEC_ENG_SE_AES_0_LINK_OFFSET);
331
332 /* Change source buffer address and destination buffer address */
333 *(uint32_t *)(uintptr_t)(link_addr + 4) = (uint32_t)(uintptr_t)input;
334 *(uint32_t *)(uintptr_t)(link_addr + 8) = (uint32_t)(uintptr_t)output;
335
336 /* Set data length */
337 *((uint16_t *)(uintptr_t)link_addr + 1) = len / 16;
338
339 regval = getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
340 regval |= SEC_ENG_SE_AES_0_TRIG_1T;
341 putreg32(regval, reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET);
342
343 __asm volatile("nop");
344 __asm volatile("nop");
345
346 start_time = bflb_mtimer_get_time_ms();
347 while (getreg32(reg_base + SEC_ENG_SE_AES_0_CTRL_OFFSET) & SEC_ENG_SE_AES_0_BUSY) {
348 if ((bflb_mtimer_get_time_ms() - start_time) > 100) {
349 return -ETIMEDOUT;
350 }
351 }
352
353 return 0;
354 }
355
bflb_group0_request_aes_access(struct bflb_device_s * dev)356 void bflb_group0_request_aes_access(struct bflb_device_s *dev)
357 {
358 uint32_t regval;
359 uint32_t reg_base;
360
361 reg_base = dev->reg_base;
362
363 regval = getreg32(reg_base + SEC_ENG_SE_CTRL_PROT_RD_OFFSET);
364 if (((regval >> 2) & 0x03) == 0x03) {
365 putreg32(0x02, reg_base + SEC_ENG_SE_AES_0_CTRL_PROT_OFFSET);
366
367 regval = getreg32(reg_base + SEC_ENG_SE_CTRL_PROT_RD_OFFSET);
368 if (((regval >> 2) & 0x03) == 0x01) {
369 }
370 }
371 }
372
bflb_group0_release_aes_access(struct bflb_device_s * dev)373 void bflb_group0_release_aes_access(struct bflb_device_s *dev)
374 {
375 uint32_t reg_base;
376
377 reg_base = dev->reg_base;
378
379 putreg32(0x06, reg_base + SEC_ENG_SE_AES_0_CTRL_PROT_OFFSET);
380 }
381
bflb_aes_set_hwkey_source(struct bflb_device_s * dev,uint8_t source)382 void bflb_aes_set_hwkey_source(struct bflb_device_s *dev, uint8_t source)
383 {
384 uint32_t regval;
385 uint32_t reg_base;
386
387 reg_base = dev->reg_base;
388
389 regval = getreg32(reg_base + SEC_ENG_SE_AES_0_SBOOT_OFFSET);
390 regval |= (source << 0);
391 putreg32(0x02, reg_base + SEC_ENG_SE_AES_0_SBOOT_OFFSET);
392 }
393