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 "cc_pal_mutex.h"
8 #include "cc_pal_abort.h"
9 #include "aes_driver.h"
10 #include "driver_defs.h"
11 #include "cc_hal.h"
12 #include "cc_hal_plat.h"
13 #include "cc_regs.h"
14 #include "dx_crys_kernel.h"
15 #include "aes_driver_ext_dma.h"
16 #include "cc_util_pm.h"
17 
18 extern CC_PalMutex CCSymCryptoMutex;
19 
20 
21 
22 
23 /******************************************************************************
24 *       PUBLIC FUNCTIONS
25 ******************************************************************************/
AesExtDmaInit(cryptoDirection_t encryptDecryptFlag,aesMode_t operationMode,keySizeId_t keySizeId)26 drvError_t AesExtDmaInit(cryptoDirection_t   encryptDecryptFlag,
27         aesMode_t operationMode,
28         keySizeId_t          keySizeId)
29 {
30         uint32_t aesCtrl = 0;
31         uint32_t irrVal = 0;
32         cryptoDirection_t dir;
33         drvError_t rc = AES_DRV_OK;
34         uint32_t pIv[AES_BLOCK_SIZE_WORDS] = {0};
35 
36         /* verify aes valid mode */
37         switch (operationMode) {
38         case CIPHER_ECB:
39         case CIPHER_CBC:
40         case CIPHER_CTR:
41         case CIPHER_CBC_MAC:
42         case CIPHER_CMAC:
43         case CIPHER_OFB:
44                 break;
45         default:
46                 return AES_DRV_ILLEGAL_OPERATION_MODE_ERROR;
47         }
48 
49         /* verify aes valid dir */
50         if ( (encryptDecryptFlag != CRYPTO_DIRECTION_ENCRYPT) &&
51              (encryptDecryptFlag != CRYPTO_DIRECTION_DECRYPT) ) {
52                 return AES_DRV_ILLEGAL_OPERATION_DIRECTION_ERROR;
53         }
54 
55 
56         /* lock mutex for more aes hw operation */
57         rc = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
58         if (rc != 0) {
59             CC_PalAbort("Fail to acquire mutex\n");
60         }
61 
62         /* increase CC counter at the beginning of each operation */
63         rc = CC_IS_WAKE;
64         if (rc != 0) {
65             CC_PalAbort("Fail to increase PM counter\n");
66         }
67 
68         /* enable clock */
69         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE) ,SET_CLOCK_ENABLE);
70         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
71 
72         /* make sure sym engines are ready to use */
73         CC_HAL_WAIT_ON_CRYPTO_BUSY();
74 
75         /* clear all interrupts before starting the engine */
76         CC_HalClearInterruptBit(0xFFFFFFFFUL);
77 
78         /* mask dma interrupts which are not required */
79         irrVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
80         CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, irrVal, 1);
81         CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, irrVal, 1);
82         CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
83         CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
84         CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, irrVal, 1);
85         CC_HalMaskInterrupt(irrVal);
86 
87         /* configure DIN-AES-DOUT */
88         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL), CONFIG_DIN_AES_DOUT_VAL);
89 
90         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_REMAINING_BYTES), 0);
91 
92         /* configure AES direction (in case of CMAC - force only encrypt) */
93         if ((operationMode == CIPHER_CBC_MAC) || (operationMode == CIPHER_CMAC)){
94             dir = CRYPTO_DIRECTION_ENCRYPT;
95         }
96         else {
97             dir = encryptDecryptFlag;
98         }
99         CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, aesCtrl, dir);
100 
101         /* configure AES mode */
102         CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, aesCtrl, operationMode);
103         switch (keySizeId) {
104         case KEY_SIZE_128_BIT:
105         case KEY_SIZE_192_BIT:
106         case KEY_SIZE_256_BIT:
107             /* NK_KEY0 and NK_KEY1 are configured, only NK_KEY0 is in use (no tunneling in cc3x)*/
108             CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, NK_KEY0, aesCtrl, keySizeId);
109             break;
110         default:
111             goto end;
112         }
113 
114         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CONTROL) ,aesCtrl);
115 
116         /* zeroize IV in CMAC */
117         if (operationMode == CIPHER_CMAC) {
118             rc = AesExtDmaSetIv(operationMode, pIv);
119             if (rc != 0) {
120                 goto end;
121             }
122         }
123 
124         return AES_DRV_OK;
125 
126 end:
127         rc = terminateAesExtDma();
128         if (rc != 0) {
129             CC_PalAbort("Failed to terminateAesExtDma \n");
130         }
131         return AES_DRV_ILLEGAL_KEY_SIZE_ERROR;
132 }
133 
134 
AesExtDmaSetDataSize(uint32_t dataSize)135 void AesExtDmaSetDataSize(uint32_t dataSize)
136 {
137     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_REMAINING_BYTES), dataSize);
138     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DIN_CPU_DATA_SIZE) , dataSize);
139 }
140 
AesExtDmaSetIv(aesMode_t mode,uint32_t * pIv)141 drvError_t AesExtDmaSetIv(aesMode_t mode, uint32_t *pIv)
142 {
143     drvError_t rc = AES_DRV_OK;
144     /* write the initial counter value according to mode */
145     switch (mode) {
146     case(CIPHER_CTR):
147     case(CIPHER_OFB):
148         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_0) ,pIv[0]);
149         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_1) ,pIv[1]);
150         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_2) ,pIv[2]);
151         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_3) ,pIv[3]);
152         break;
153     case(CIPHER_CMAC):
154     case(CIPHER_CBC):
155     case(CIPHER_CBC_MAC):
156         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_0) ,pIv[0]);
157         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_1) ,pIv[1]);
158         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_2) ,pIv[2]);
159         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_3) ,pIv[3]);
160         break;
161     case(CIPHER_ECB):
162         break;
163     default:
164         rc = AES_DRV_ILLEGAL_OPERATION_MODE_ERROR;
165     }
166 
167     return rc;
168 }
169 
170 
AesExtDmaStoreIv(aesMode_t mode,uint32_t * pIv)171 drvError_t AesExtDmaStoreIv(aesMode_t mode, uint32_t *pIv)
172 {
173     drvError_t rc = AES_DRV_OK;
174     /* write the initial counter value according to mode */
175     switch (mode) {
176 
177     case(CIPHER_CMAC):
178     case(CIPHER_CBC_MAC):
179         pIv[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_0));
180         pIv[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_1));
181         pIv[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_2));
182         pIv[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_3));
183         break;
184     default:
185         rc = AES_DRV_ILLEGAL_OPERATION_MODE_ERROR;
186     }
187     return rc;
188 }
189 
190 
191 
AesExtDmaSetKey(aesMode_t mode,uint32_t * keyBuf,keySizeId_t keySizeId)192 drvError_t AesExtDmaSetKey(aesMode_t mode, uint32_t *keyBuf, keySizeId_t keySizeId)
193 {
194     /* verify user context pointer */
195     if ( keyBuf == NULL ) {
196         return AES_DRV_ILLEGAL_KEY_SIZE_ERROR;
197     }
198     if ((keySizeId != KEY_SIZE_256_BIT) && (keySizeId != KEY_SIZE_192_BIT) && (keySizeId != KEY_SIZE_128_BIT)) {
199         return AES_DRV_ILLEGAL_KEY_SIZE_ERROR;
200     }
201 
202     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_0) ,keyBuf[0]);
203     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_1) ,keyBuf[1]);
204     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_2) ,keyBuf[2]);
205     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_3) ,keyBuf[3]);
206 
207     if (keySizeId == KEY_SIZE_192_BIT || keySizeId == KEY_SIZE_256_BIT) {
208         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_4) ,keyBuf[4]);
209         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_5) ,keyBuf[5]);
210     }
211     if (keySizeId == KEY_SIZE_256_BIT) {
212         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_6) ,keyBuf[6]);
213         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_7) ,keyBuf[7]);
214     }
215 
216     /* initiate CMAC sub-keys calculation */
217     if (mode == CIPHER_CMAC) {
218         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CMAC_INIT) ,0x1);
219     }
220 
221     return AES_DRV_OK;
222 }
223 
224 
finalizeAesExtDma(aesMode_t mode,uint32_t * pIv)225 drvError_t finalizeAesExtDma(aesMode_t mode, uint32_t *pIv)
226 {
227         drvError_t drvRc = AES_DRV_OK;
228 
229         if (mode == CIPHER_CMAC || mode== CIPHER_CBC_MAC)
230         {
231             drvRc = AesExtDmaStoreIv(mode, pIv);
232         }
233 
234         return drvRc;
235 }
236 
terminateAesExtDma(void)237 drvError_t terminateAesExtDma(void)
238 {
239         drvError_t rc = AES_DRV_OK;
240 
241         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE) ,SET_CLOCK_DISABLE);
242         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
243 
244         /* decrease CC counter at the end of each operation */
245         rc = CC_IS_IDLE;
246         if (rc != 0) {
247             CC_PalAbort("Fail to decrease PM counter\n");
248         }
249 
250         /* unlock mutex for more aes hw operation */
251         rc = CC_PalMutexUnlock(&CCSymCryptoMutex);
252         if (rc != 0) {
253             CC_PalAbort("Fail to unlock mutex\n");
254         }
255         return rc;
256 }
257 
258