1 /*
2 * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <stdint.h>
8 #include <stdio.h>
9 #include <stddef.h>
10
11 #include "cc_pal_mutex.h"
12 #include "cc_pal_abort.h"
13 #include "driver_defs.h"
14 #include "cc_hal.h"
15 #include "cc_hal_plat.h"
16 #include "cc_sram_map.h"
17 #include "cc_regs.h"
18 #include "dx_crys_kernel.h"
19 #include "aesccm_driver.h"
20 #include "cc_util_pm.h"
21
22 extern CC_PalMutex CCSymCryptoMutex;
23
24
25 /******************************************************************************
26 * PRIVATE FUNCTIONS
27 ******************************************************************************/
28
InitAesCcm(AesCcmContext_t * pAesCcmCtx)29 static drvError_t InitAesCcm(AesCcmContext_t *pAesCcmCtx)
30 {
31 uint32_t aesControl = 0;
32 uint32_t irrVal = 0;
33
34 /* verify user context pointer */
35 if ( pAesCcmCtx == NULL ) {
36 return AES_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
37 }
38
39 /* verify valid dir */
40 if ( (pAesCcmCtx->dir != CRYPTO_DIRECTION_ENCRYPT) &&
41 (pAesCcmCtx->dir != CRYPTO_DIRECTION_DECRYPT) ) {
42 return AES_DRV_ILLEGAL_OPERATION_DIRECTION_ERROR;
43 }
44
45 /* veriy mode and set aes control */
46 switch (pAesCcmCtx->mode) {
47 case CIPHER_CBC_MAC:
48 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, aesControl, CRYPTO_DIRECTION_ENCRYPT);
49 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, aesControl, CIPHER_CBC_MAC);
50 break;
51 case CIPHER_CTR:
52 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, aesControl, pAesCcmCtx->dir);
53 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, aesControl, CIPHER_CTR);
54 break;
55 case CIPHER_CCMPE:
56 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, aesControl, pAesCcmCtx->dir);
57 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, aesControl, CIPHER_CTR);
58 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY1, aesControl, CIPHER_CBC_MAC);
59 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, AES_TUNNEL_IS_ON, aesControl, 1);
60 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, AES_TUN_B1_USES_PADDED_DATA_IN, aesControl, 1);
61 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, AES_TUNNEL0_ENCRYPT, aesControl, 1);
62 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, AES_OUTPUT_MID_TUNNEL_DATA, aesControl, 1);
63 break;
64 case CIPHER_CCMPD:
65 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, aesControl, pAesCcmCtx->dir);
66 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, aesControl, CIPHER_CTR);
67 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY1, aesControl, CIPHER_CBC_MAC);
68 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, AES_TUNNEL_IS_ON, aesControl, 1);
69 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, AES_OUTPUT_MID_TUNNEL_DATA, aesControl, 1);
70 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, AES_TUNNEL_B1_PAD_EN, aesControl, 1);
71 break;
72 default:
73 return AES_DRV_ILLEGAL_OPERATION_MODE_ERROR;
74 }
75
76 /* verify keySizeID */
77 switch (pAesCcmCtx->keySizeId) {
78 case KEY_SIZE_128_BIT:
79 case KEY_SIZE_192_BIT:
80 case KEY_SIZE_256_BIT:
81 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, NK_KEY0, aesControl, pAesCcmCtx->keySizeId);
82 CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, NK_KEY1, aesControl, pAesCcmCtx->keySizeId);
83 break;
84 default:
85 return AES_DRV_ILLEGAL_KEY_SIZE_ERROR;
86 }
87
88 /* make sure sym engines are ready to use */
89 CC_HAL_WAIT_ON_CRYPTO_BUSY();
90
91 /* clear all interrupts before starting the engine */
92 CC_HalClearInterruptBit(0xFFFFFFFFUL);
93
94 /* mask dma interrupts which are not required */
95 irrVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
96 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, irrVal, 1);
97 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, irrVal, 1);
98 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
99 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
100 CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, irrVal, 0);
101 CC_HalMaskInterrupt(irrVal);
102
103 /* configure DIN-AES-DOUT */
104 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL) ,CONFIG_DIN_AES_DOUT_VAL);
105
106 /* Zero AES_REMAINING_BYTES */
107 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_REMAINING_BYTES) ,0);
108
109 /* configure AES control */
110 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CONTROL) ,aesControl);
111
112 return AES_DRV_OK;
113 }
114
LoadAesCcmdKey(AesCcmContext_t * pAesCcmCtx)115 static void LoadAesCcmdKey(AesCcmContext_t *pAesCcmCtx)
116 {
117 /* load key0 [127:0]*/
118 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_0) ,pAesCcmCtx->keyBuf[0]);
119 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_1) ,pAesCcmCtx->keyBuf[1]);
120 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_2) ,pAesCcmCtx->keyBuf[2]);
121 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_3) ,pAesCcmCtx->keyBuf[3]);
122
123 /* load key1 [127:0]*/
124 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_0) ,pAesCcmCtx->keyBuf[0]);
125 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_1) ,pAesCcmCtx->keyBuf[1]);
126 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_2) ,pAesCcmCtx->keyBuf[2]);
127 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_3) ,pAesCcmCtx->keyBuf[3]);
128
129 if (pAesCcmCtx->keySizeId >= KEY_SIZE_192_BIT) {
130 /* load key0 [191:128]*/
131 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_4) ,pAesCcmCtx->keyBuf[4]);
132 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_5) ,pAesCcmCtx->keyBuf[5]);
133 /* load key1 [191:128]*/
134 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_4) ,pAesCcmCtx->keyBuf[4]);
135 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_5) ,pAesCcmCtx->keyBuf[5]);
136 }
137
138 if (pAesCcmCtx->keySizeId == KEY_SIZE_256_BIT) {
139 /* load key0 [255:191]*/
140 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_6) ,pAesCcmCtx->keyBuf[6]);
141 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_7) ,pAesCcmCtx->keyBuf[7]);
142 /* load key1 [255:191]*/
143 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_6) ,pAesCcmCtx->keyBuf[6]);
144 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_7) ,pAesCcmCtx->keyBuf[7]);
145 }
146
147 return;
148 }
149
LoadAesCcmIvState(AesCcmContext_t * pAesCcmCtx)150 static void LoadAesCcmIvState(AesCcmContext_t *pAesCcmCtx)
151 {
152 if (pAesCcmCtx->mode == CIPHER_CBC_MAC) {
153 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_0) ,pAesCcmCtx->ivBuf[0]);
154 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_1) ,pAesCcmCtx->ivBuf[1]);
155 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_2) ,pAesCcmCtx->ivBuf[2]);
156 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_3) ,pAesCcmCtx->ivBuf[3]);
157 } else {
158 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_0) ,pAesCcmCtx->ivBuf[0]);
159 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_1) ,pAesCcmCtx->ivBuf[1]);
160 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_2) ,pAesCcmCtx->ivBuf[2]);
161 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_3) ,pAesCcmCtx->ivBuf[3]);
162 }
163
164 return;
165 }
166
LoadAesCcmCtrState(AesCcmContext_t * pAesCcmCtx)167 static void LoadAesCcmCtrState(AesCcmContext_t *pAesCcmCtx)
168 {
169 /* write the initial counter value according to mode */
170 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_0) ,pAesCcmCtx->ctrStateBuf[0]);
171 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_1) ,pAesCcmCtx->ctrStateBuf[1]);
172 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_2) ,pAesCcmCtx->ctrStateBuf[2]);
173 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_3) ,pAesCcmCtx->ctrStateBuf[3]);
174
175 return;
176 }
177
178
StoreAesCcmIvState(AesCcmContext_t * pAesCcmCtx)179 static void StoreAesCcmIvState(AesCcmContext_t *pAesCcmCtx)
180 {
181 if (pAesCcmCtx->mode == CIPHER_CBC_MAC) {
182 pAesCcmCtx->ivBuf[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_0));
183 pAesCcmCtx->ivBuf[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_1));
184 pAesCcmCtx->ivBuf[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_2));
185 pAesCcmCtx->ivBuf[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_3));
186 } else {
187 pAesCcmCtx->ivBuf[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_0));
188 pAesCcmCtx->ivBuf[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_1));
189 pAesCcmCtx->ivBuf[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_2));
190 pAesCcmCtx->ivBuf[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_3));
191 }
192
193 return;
194 }
195
196
StoreAesCcmCtrState(AesCcmContext_t * pAesCcmCtx)197 static void StoreAesCcmCtrState(AesCcmContext_t *pAesCcmCtx)
198 {
199 /* write the initial counter value according to mode */
200 pAesCcmCtx->ctrStateBuf[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_0));
201 pAesCcmCtx->ctrStateBuf[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_1));
202 pAesCcmCtx->ctrStateBuf[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_2));
203 pAesCcmCtx->ctrStateBuf[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_3));
204
205 return;
206 }
207
208
209 /******************************************************************************
210 * PUBLIC FUNCTIONS
211 ******************************************************************************/
212
ProcessAesCcmDrv(AesCcmContext_t * pAesCcmCtx,CCBuffInfo_t * pInputBuffInfo,CCBuffInfo_t * pOutputBuffInfo,uint32_t blockSize)213 drvError_t ProcessAesCcmDrv(AesCcmContext_t *pAesCcmCtx, CCBuffInfo_t *pInputBuffInfo, CCBuffInfo_t *pOutputBuffInfo, uint32_t blockSize)
214 {
215 uint32_t irrVal = 0;
216 drvError_t drvRc = AES_DRV_OK;
217 uint32_t regVal = 0;
218 uint32_t inputDataAddr, outputDataAddr;
219
220 /* check input parameters */
221 if ( (pInputBuffInfo == NULL) || (pOutputBuffInfo == NULL)) {
222 return AES_DRV_INVALID_USER_DATA_BUFF_POINTER_ERROR;
223 }
224
225 /* verify user context pointer */
226 if ( pAesCcmCtx == NULL ) {
227 return AES_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
228 }
229
230 /* verify valid block size */
231 if (blockSize >= DLLI_MAX_BUFF_SIZE) {
232 return AES_DRV_ILLEGAL_MEM_SIZE_ERROR;
233 }
234
235 /* lock mutex for more aes hw operation */
236 drvRc = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
237 if (drvRc != 0) {
238 CC_PalAbort("Fail to acquire mutex\n");
239 }
240
241 /* increase CC counter at the beginning of each operation */
242 drvRc = CC_IS_WAKE;
243 if (drvRc != 0) {
244 CC_PalAbort("Fail to increase PM counter\n");
245 }
246
247 /* enable clock */
248 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE) ,SET_CLOCK_ENABLE);
249 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
250
251 drvRc = InitAesCcm(pAesCcmCtx);
252 if (drvRc != AES_DRV_OK) {
253 goto ProcessExit;
254 }
255
256 /* load key0 and key1 */
257 LoadAesCcmdKey(pAesCcmCtx);
258
259 inputDataAddr = pInputBuffInfo->dataBuffAddr;
260 outputDataAddr = pOutputBuffInfo->dataBuffAddr;
261
262 /* configure the HW with the correct data buffer attributes (secure/non-secure) */
263 CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_READ_HNONSEC, regVal, pInputBuffInfo->dataBuffNs);
264 CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_WRITE_HNONSEC, regVal, pOutputBuffInfo->dataBuffNs);
265 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AHBM_HNONSEC) ,regVal);
266
267 /* load CTR in case of CTR / CCMPE / CCMPD */
268 if (pAesCcmCtx->mode != CIPHER_CBC_MAC) {
269 /* write the initial counter value according to mode */
270 LoadAesCcmCtrState(pAesCcmCtx);
271
272 /* configure destination address and size in case of ctr */
273 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DST_LLI_WORD0) ,outputDataAddr);
274 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DST_LLI_WORD1) ,blockSize);
275 }
276
277 /* load IV in case of CBC_MAC / CCMPE / CCMPD */
278 if (pAesCcmCtx->mode != CIPHER_CTR) {
279 /* write the initial counter value according to mode */
280 LoadAesCcmIvState(pAesCcmCtx);
281
282 /* initiate CMAC sub-keys calculation */
283 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CMAC_INIT) ,0x1);
284 /* set the remaining bytes */
285 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_REMAINING_BYTES) ,blockSize);
286
287 }
288
289 /* configure source address and size */
290 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD0) ,inputDataAddr);
291 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD1) ,blockSize);
292
293 /* set dma completion bit in irr */
294 CC_REG_FLD_SET(HOST_RGF, HOST_IRR, SYM_DMA_COMPLETED, irrVal, 1);
295 drvRc = CC_HalWaitInterrupt(irrVal);
296 if (drvRc != AES_DRV_OK) {
297 goto ProcessExit;
298 }
299
300 /* get CTR state in case of CTR / CCMPE / CCMPD */
301 if (pAesCcmCtx->mode != CIPHER_CBC_MAC) {
302 StoreAesCcmCtrState(pAesCcmCtx);
303 }
304
305 /* get IV state in case of CBC_MAC / CCMPE / CCMPD */
306 if (pAesCcmCtx->mode != CIPHER_CTR) {
307 StoreAesCcmIvState(pAesCcmCtx);
308 }
309
310 ProcessExit:
311 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE) ,SET_CLOCK_DISABLE);
312 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
313
314 /* decrease CC counter at the end of each operation */
315 if (CC_IS_IDLE != 0) {
316 CC_PalAbort("Fail to decrease PM counter\n");
317 }
318
319 /* release mutex */
320 if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
321 CC_PalAbort("Fail to release mutex\n");
322 }
323
324 return drvRc;
325 }
326
327
328
329
330
331
332
333
334
335
336