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