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