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