1 /*
2  * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "cc3xx_aes.h"
9 
10 #include "cc3xx_reg_defs.h"
11 #include "cc3xx_dma.h"
12 #include "cc3xx_lcs.h"
13 #include "cc3xx_engine_state.h"
14 #include "device_definition.h"
15 
cc3xx_aes_dumpiv(cc3xx_aes_mode_t mode,uint8_t * iv)16 static cc3xx_err_t cc3xx_aes_dumpiv(cc3xx_aes_mode_t mode, uint8_t *iv) {
17     switch (mode) {
18     case CC3XX_AES_MODE_CTR:
19         ((uint32_t*)iv)[3] = *CC3XX_REG_AES_AES_CTR_0_3;
20         ((uint32_t*)iv)[2] = *CC3XX_REG_AES_AES_CTR_0_2;
21         ((uint32_t*)iv)[1] = *CC3XX_REG_AES_AES_CTR_0_1;
22         ((uint32_t*)iv)[0] = *CC3XX_REG_AES_AES_CTR_0_0;
23         break;
24     case CC3XX_AES_MODE_ECB:
25         return CC3XX_ERR_SUCCESS;
26     default:
27         return CC3XX_ERR_NOT_IMPLEMENTED;
28     }
29 
30     return CC3XX_ERR_SUCCESS;
31 }
32 
cc3xx_aes_loadiv(cc3xx_aes_mode_t mode,const uint8_t * iv)33 static cc3xx_err_t cc3xx_aes_loadiv(cc3xx_aes_mode_t mode, const uint8_t *iv) {
34     switch (mode) {
35     case CC3XX_AES_MODE_CTR:
36         *CC3XX_REG_AES_AES_CTR_0_3 = ((uint32_t*)iv)[3];
37         *CC3XX_REG_AES_AES_CTR_0_2 = ((uint32_t*)iv)[2];
38         *CC3XX_REG_AES_AES_CTR_0_1 = ((uint32_t*)iv)[1];
39         *CC3XX_REG_AES_AES_CTR_0_0 = ((uint32_t*)iv)[0];
40         break;
41     case CC3XX_AES_MODE_ECB:
42         return CC3XX_ERR_SUCCESS;
43     default:
44         return CC3XX_ERR_NOT_IMPLEMENTED;
45     }
46 
47     return CC3XX_ERR_SUCCESS;
48 }
49 
50 #ifdef KMU_S
cc3xx_aes_setkey(cc3xx_aes_key_id_t key_id,const uint8_t * key,cc3xx_aes_keysize_t key_size)51 static cc3xx_err_t cc3xx_aes_setkey(cc3xx_aes_key_id_t key_id,
52                                     const uint8_t *key,
53                                     cc3xx_aes_keysize_t key_size)
54 {
55     enum kmu_error_t kmu_err;
56 
57     if (*CC3XX_REG_AO_HOST_AO_LOCK_BITS & 0x1U) {
58         return CC3XX_ERR_INVALID_STATE;
59     }
60 
61     if (key_id != CC3XX_AES_KEY_ID_USER_KEY) {
62         switch (key_id) {
63         case CC3XX_AES_KEY_ID_HUK:
64             kmu_err = kmu_export_key(&KMU_DEV_S, KMU_HW_SLOT_HUK);
65             break;
66         case CC3XX_AES_KEY_ID_KRTL:
67             kmu_err = kmu_export_key(&KMU_DEV_S, KMU_HW_SLOT_KRTL);
68             break;
69         case CC3XX_AES_KEY_ID_KCP:
70             kmu_err = kmu_export_key(&KMU_DEV_S, KMU_HW_SLOT_KP_CM);
71             break;
72         case CC3XX_AES_KEY_ID_KCE:
73             kmu_err = kmu_export_key(&KMU_DEV_S, KMU_HW_SLOT_KCE_CM);
74             break;
75         case CC3XX_AES_KEY_ID_KPICV:
76             kmu_err = kmu_export_key(&KMU_DEV_S, KMU_HW_SLOT_KP_DM);
77             break;
78         case CC3XX_AES_KEY_ID_KCEICV:
79             kmu_err = kmu_export_key(&KMU_DEV_S, KMU_HW_SLOT_KCE_DM);
80             break;
81         case CC3XX_AES_KEY_ID_GUK:
82             kmu_err = kmu_export_key(&KMU_DEV_S, KMU_HW_SLOT_GUK);
83             break;
84         default:
85             return CC3XX_ERR_NOT_IMPLEMENTED;
86         }
87         if (kmu_err != KMU_ERROR_NONE) {
88             return CC3XX_ERR_KEY_IMPORT_FAILED;
89         }
90     } else {
91         switch (key_size) {
92         case CC3XX_AES_KEYSIZE_256:
93             *CC3XX_REG_AES_AES_KEY_0_7 = ((uint32_t*)key)[7];
94             *CC3XX_REG_AES_AES_KEY_0_6 = ((uint32_t*)key)[6];
95         case CC3XX_AES_KEYSIZE_192:
96             *CC3XX_REG_AES_AES_KEY_0_5 = ((uint32_t*)key)[5];
97             *CC3XX_REG_AES_AES_KEY_0_4 = ((uint32_t*)key)[4];
98         case CC3XX_AES_KEYSIZE_128:
99             *CC3XX_REG_AES_AES_KEY_0_3 = ((uint32_t*)key)[3];
100             *CC3XX_REG_AES_AES_KEY_0_2 = ((uint32_t*)key)[2];
101             *CC3XX_REG_AES_AES_KEY_0_1 = ((uint32_t*)key)[1];
102             *CC3XX_REG_AES_AES_KEY_0_0 = ((uint32_t*)key)[0];
103             break;
104         default:
105             return CC3XX_ERR_NOT_IMPLEMENTED;
106         }
107     }
108 
109     /* Set key size */
110     *CC3XX_REG_AES_AES_CONTROL &= ~(0b11U << 12);
111     *CC3XX_REG_AES_AES_CONTROL |= (key_size & 0b11U) << 12;
112 
113     return CC3XX_ERR_SUCCESS;
114 }
115 #else
cc3xx_aes_check_key_lock(cc3xx_aes_key_id_t key_id)116 static cc3xx_err_t cc3xx_aes_check_key_lock(cc3xx_aes_key_id_t key_id)
117 {
118     cc3xx_err_t err = CC3XX_ERR_SUCCESS;
119     cc3xx_lcs_t lcs;
120 
121     switch (key_id) {
122     case CC3XX_AES_KEY_ID_HUK:
123         break;
124     case CC3XX_AES_KEY_ID_KRTL:
125         err = cc3xx_lcs_get(&lcs);
126         if (err != CC3XX_ERR_SUCCESS) {
127             return err;
128         }
129         /* The RTL key is only valid in certain states */
130         if (! (lcs == (cc3xx_lcs_cm | cc3xx_lcs_dm))) {
131             return CC3XX_ERR_INVALID_LCS;
132         }
133         break;
134     case CC3XX_AES_KEY_ID_KCP:
135         if (*CC3XX_REG_AO_HOST_AO_LOCK_BITS & (0x1U << 3)) {
136             return CC3XX_ERR_INVALID_STATE;
137         }
138         break;
139     case CC3XX_AES_KEY_ID_KCE:
140         if (*CC3XX_REG_AO_HOST_AO_LOCK_BITS & (0x1U << 4)) {
141             return CC3XX_ERR_INVALID_STATE;
142         }
143         break;
144     case CC3XX_AES_KEY_ID_KPICV:
145         if (*CC3XX_REG_AO_HOST_AO_LOCK_BITS & (0x1U << 1)) {
146             return CC3XX_ERR_INVALID_STATE;
147         }
148         break;
149     case CC3XX_AES_KEY_ID_KCEICV:
150         if (*CC3XX_REG_AO_HOST_AO_LOCK_BITS & (0x1U << 2)) {
151             return CC3XX_ERR_INVALID_STATE;
152         }
153         break;
154     case CC3XX_AES_KEY_ID_USER_KEY:
155         break;
156     default:
157         return CC3XX_ERR_SUCCESS;
158     }
159 
160     return CC3XX_ERR_SUCCESS;
161 }
162 
cc3xx_aes_setkey(cc3xx_aes_key_id_t key_id,const uint8_t * key,cc3xx_aes_keysize_t key_size)163 static cc3xx_err_t cc3xx_aes_setkey(cc3xx_aes_key_id_t key_id,
164                                     const uint8_t *key,
165                                     cc3xx_aes_keysize_t key_size)
166 {
167     cc3xx_err_t err = CC3XX_ERR_SUCCESS;
168 
169     if (key_id != CC3XX_AES_KEY_ID_USER_KEY) {
170         /* Check if the HOST_FATAL_ERROR mode is enabled */
171         if (*CC3XX_REG_AO_HOST_AO_LOCK_BITS & 0x1U) {
172             return CC3XX_ERR_INVALID_STATE;
173         }
174 
175         /* If the KMU is not integrated, there are limited keys */
176         if (key_id > CC3XX_AES_KEY_ID_KCEICV) {
177             return CC3XX_ERR_NOT_IMPLEMENTED;
178         }
179 
180         /* Check if the key is masked / locked */
181         err = cc3xx_aes_check_key_lock(key_id);
182         if (err != CC3XX_ERR_SUCCESS) {
183             return err;
184         }
185 
186         /* Select the required key */
187         *CC3XX_REG_HOST_RGF_HOST_CRYPTOKEY_SEL = key_id;
188 
189         /* Trigger the load into the key registers */
190         *CC3XX_REG_AES_AES_SK = 0b1U;
191     } else {
192         switch (key_size) {
193         case CC3XX_AES_KEYSIZE_256:
194             *CC3XX_REG_AES_AES_KEY_0_7 = ((uint32_t*)key)[7];
195             *CC3XX_REG_AES_AES_KEY_0_6 = ((uint32_t*)key)[6];
196         case CC3XX_AES_KEYSIZE_192:
197             *CC3XX_REG_AES_AES_KEY_0_5 = ((uint32_t*)key)[5];
198             *CC3XX_REG_AES_AES_KEY_0_4 = ((uint32_t*)key)[4];
199         case CC3XX_AES_KEYSIZE_128:
200             *CC3XX_REG_AES_AES_KEY_0_3 = ((uint32_t*)key)[3];
201             *CC3XX_REG_AES_AES_KEY_0_2 = ((uint32_t*)key)[2];
202             *CC3XX_REG_AES_AES_KEY_0_1 = ((uint32_t*)key)[1];
203             *CC3XX_REG_AES_AES_KEY_0_0 = ((uint32_t*)key)[0];
204             break;
205         default:
206             return CC3XX_ERR_NOT_IMPLEMENTED;
207         }
208     }
209 
210     /* Set key size */
211     *CC3XX_REG_AES_AES_CONTROL &= ~(0b11U << 12);
212     *CC3XX_REG_AES_AES_CONTROL |= (key_size & 0b11U) << 12;
213 
214     return CC3XX_ERR_SUCCESS;
215 }
216 #endif /* KMU_S */
217 
cc3xx_aes(cc3xx_aes_key_id_t key_id,const uint8_t * key,cc3xx_aes_keysize_t key_size,const uint8_t * in,size_t in_len,uint8_t * iv,uint8_t * out,cc3xx_aes_direction_t direction,cc3xx_aes_mode_t mode)218 cc3xx_err_t cc3xx_aes(cc3xx_aes_key_id_t key_id, const uint8_t *key,
219                       cc3xx_aes_keysize_t key_size, const uint8_t* in, size_t
220                       in_len, uint8_t* iv, uint8_t *out,
221                       cc3xx_aes_direction_t direction, cc3xx_aes_mode_t mode)
222 {
223     cc3xx_err_t err = CC3XX_ERR_SUCCESS;
224 
225     if (cc3xx_engine_in_use) {
226         /* Since the AES operation isn't restartable, just check that the engine
227          * isn't in use when we begin.
228          */
229         return CC3XX_ERR_ENGINE_IN_USE;
230     }
231 
232     /* Enable the aes engine clock */
233     *CC3XX_REG_MISC_AES_CLK_ENABLE = 0x1U;
234 
235     /* Enable the DMA clock */
236     *CC3XX_REG_MISC_DMA_CLK_ENABLE = 0x1U;
237 
238     /* Wait for the crypto engine to be ready */
239     while (*CC3XX_REG_CC_CTL_CRYPTO_BUSY) {}
240 
241     /* Set the crypto engine to the AES engine */
242     *CC3XX_REG_CC_CTL_CRYPTO_CTL = 0b00001U;
243 
244     /* Clear number of remaining bytes */
245     *CC3XX_REG_AES_AES_REMAINING_BYTES = 0x0U;
246 
247     /* Set direction field of AES control register */
248     *CC3XX_REG_AES_AES_CONTROL &= ~0b1U;
249     *CC3XX_REG_AES_AES_CONTROL |= (direction & 0b1U);
250 
251     /* Set mode field of AES control register */
252     *CC3XX_REG_AES_AES_CONTROL &= ~(0b111U << 2);
253     *CC3XX_REG_AES_AES_CONTROL |= (mode & 0b111U) << 2;
254 
255     /* Set up the key */
256     err = cc3xx_aes_setkey(key_id, key, key_size);
257     if (err != CC3XX_ERR_SUCCESS) {
258         goto out;
259     }
260 
261     /* Set up the IV */
262     err = cc3xx_aes_loadiv(mode, iv);
263     if (err != CC3XX_ERR_SUCCESS) {
264         goto out;
265     }
266 
267     /* Set up output */
268     cc3xx_dma_set_output(out, in_len);
269 
270     /* Use DMA to input the data. This completes the encryption */
271     err = cc3xx_dma_input_data(in, in_len);
272 
273     /* Dump the IV so multipart works */
274     err = cc3xx_aes_dumpiv(mode, iv);
275     if (err != CC3XX_ERR_SUCCESS) {
276         goto out;
277     }
278 
279 out:
280     /* Set the crypto engine back to the default PASSTHROUGH engine */
281     *CC3XX_REG_CC_CTL_CRYPTO_CTL = 0x0;
282 
283     /* Disable the hash engine clock */
284     *CC3XX_REG_MISC_AES_CLK_ENABLE = 0x0U;
285 
286     /* Disable the DMA clock */
287     *CC3XX_REG_MISC_DMA_CLK_ENABLE = 0x0U;
288 
289     return err;
290 }
291