1 /*
2  * Copyright (c) 2001-2022, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 
8 #define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CCLIB
9 
10 #include "cc_pal_types.h"
11 #include "cc_pal_log.h"
12 #include "cc_pal_mem.h"
13 #include "cc_pal_abort.h"
14 #include "cc_lib.h"
15 #include "cc_hal.h"
16 #include "cc_pal_init.h"
17 #include "cc_pal_mutex.h"
18 #include "cc_pal_perf.h"
19 #include "cc_regs.h"
20 #include "dx_crys_kernel.h"
21 #include "dx_rng.h"
22 #include "dx_reg_common.h"
23 #include "llf_rnd_trng.h"
24 #include "cc_rng_plat.h"
25 #include "dx_id_registers.h"
26 #include "cc_util_pm.h"
27 #include "dx_nvm.h"
28 #include "mbedtls/ctr_drbg.h"
29 #include "mbedtls/entropy.h"
30 #include "mbedtls/threading.h"
31 #include "mbedtls_cc_mng_int.h"
32 #include "mbedtls_cc_mng.h"
33 #include "cc_rnd_common.h"
34 #include "cc_int_general_defs.h"
35 
36 CC_PalMutex CCSymCryptoMutex;
37 CC_PalMutex CCAsymCryptoMutex;
38 CC_PalMutex *pCCRndCryptoMutex;
39 CC_PalMutex CCApbFilteringRegMutex;
40 CC_PalMutex CCRndCryptoMutex;
41 
RndStartupTest(CCRndWorkBuff_t * workBuff_ptr)42 static CCError_t RndStartupTest(
43         CCRndWorkBuff_t  *workBuff_ptr/*in/out*/)
44 {
45         /* error identifier definition */
46         CCError_t error = CC_OK;
47         CCRndState_t   rndState;
48         CCRndParams_t  trngParams;
49 
50         error = RNG_PLAT_SetUserRngParameters(&trngParams);
51         if (error != CC_SUCCESS) {
52                 return error;
53         }
54 
55         error = CC_PalMutexLock(pCCRndCryptoMutex, CC_INFINITE);
56         if (error != CC_SUCCESS) {
57                 CC_PalAbort("Fail to acquire mutex\n");
58         }
59 
60         /* verify that the device is not in fatal error state before activating the PKA engine */
61         CC_IS_FATAL_ERR_ON(error);
62         if (error == CC_TRUE) {
63                 error = CC_LIB_RET_RND_INST_ERR;
64                 goto EndUnlockMutex;
65         }
66 
67         /* increase CC counter at the beginning of each operation */
68         error = CC_IS_WAKE;
69         if (error != CC_SUCCESS) {
70             CC_PalAbort("Fail to increase PM counter\n");
71         }
72 
73         /* call on Instantiation mode */
74         error = LLF_RND_RunTrngStartupTest(&rndState, &trngParams, (uint32_t*)workBuff_ptr);
75 
76         /* decrease CC counter at the end of each operation */
77         if (CC_IS_IDLE != CC_SUCCESS) {
78             CC_PalAbort("Fail to decrease PM counter\n");
79         }
80 
81 EndUnlockMutex:
82         if (CC_PalMutexUnlock(pCCRndCryptoMutex) != CC_SUCCESS) {
83                 CC_PalAbort("Fail to release mutex\n");
84         }
85         return error;
86 }
87 
InitHukRma(CCRndContext_t * rndContext_ptr)88 static CClibRetCode_t InitHukRma(CCRndContext_t *rndContext_ptr)
89 {
90     uint32_t lcsVal = 0;
91     uint32_t kdrValues[CC_AES_KDR_MAX_SIZE_WORDS];
92     CCError_t error = CC_OK;
93     uint32_t i = 0;
94     CCRndGenerateVectWorkFunc_t RndGenerateVectFunc = rndContext_ptr->rndGenerateVectFunc;
95 
96     mbedtls_mng_lcsGet( &lcsVal );
97 
98     if (lcsVal == CC_MNG_LCS_RMA){ /* in case lcs == RMA set the KDR*/
99         error = RndGenerateVectFunc((void *)rndContext_ptr->rndState,
100                         (unsigned char *)kdrValues, (size_t) CC_AES_KDR_MAX_SIZE_BYTES);
101         if (error != CC_OK){
102             return CC_LIB_RET_RND_INST_ERR;
103         }
104 
105         /* set the random value to the KDR register */
106         for (i = 0; i < CC_AES_KDR_MAX_SIZE_WORDS; i++){
107             CC_HAL_WRITE_REGISTER( DX_HOST_SHADOW_KDR_REG_REG_OFFSET, kdrValues[i] );
108         }
109     }
110 
111     return CC_LIB_RET_OK;
112 }
113 
114 
VerifyPidVal(void)115 static CClibRetCode_t VerifyPidVal(void)
116 {
117     uint32_t pidReg[CC_BSV_PID_SIZE_WORDS] = {0};
118     uint32_t pidVal1[CC_BSV_PID_SIZE_WORDS] = {CC_BSV_PID_0_VAL, CC_BSV_PID_1_VAL, CC_BSV_PID_2_VAL, CC_BSV_PID_3_VAL, CC_BSV_PID_4_VAL};
119     uint32_t pidVal2[CC_BSV_PID_SIZE_WORDS] = {CC_BSV_PID_0_VAL, CC_BSV_PID_1_VAL, CC_BSV_PID_2_1_VAL, CC_BSV_PID_3_VAL, CC_BSV_PID_4_VAL};
120     uint32_t pidVal3[CC_BSV_PID_SIZE_WORDS] = {CC_BSV_PID_0_VAL, CC_BSV_PID_1_VAL, CC_BSV_PID_2_2_VAL, CC_BSV_PID_3_VAL, CC_BSV_PID_4_VAL};
121     uint32_t pidVal4[CC_BSV_PID_SIZE_WORDS] = {CC_BSV_PID_0_1_VAL, CC_BSV_PID_1_VAL, CC_BSV_PID_2_VAL, CC_BSV_PID_3_VAL, CC_BSV_PID_4_VAL};
122 
123     pidReg[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_0));
124     pidReg[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_1));
125     pidReg[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_2));
126     pidReg[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_3));
127     pidReg[4] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_4));
128 
129     if ((CC_PalMemCmp((uint8_t*)pidVal1, (uint8_t*)pidReg, sizeof(pidVal1)) != 0) &&
130         (CC_PalMemCmp((uint8_t*)pidVal2, (uint8_t*)pidReg, sizeof(pidVal2)) != 0) &&
131         (CC_PalMemCmp((uint8_t*)pidVal3, (uint8_t*)pidReg, sizeof(pidVal3)) != 0) &&
132         (CC_PalMemCmp((uint8_t*)pidVal4, (uint8_t*)pidReg, sizeof(pidVal4)) != 0)) {
133         return CC_LIB_RET_EINVAL_PIDR;
134     }
135 
136     return CC_LIB_RET_OK;
137 }
138 
VerifyCidVal(void)139 static CClibRetCode_t VerifyCidVal(void)
140 {
141     uint32_t cidReg[CC_BSV_CID_SIZE_WORDS] = {0};
142     uint32_t cidVal[CC_BSV_CID_SIZE_WORDS] = {CC_BSV_CID_0_VAL, CC_BSV_CID_1_VAL, CC_BSV_CID_2_VAL, CC_BSV_CID_3_VAL};
143 
144     cidReg[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_0));
145     cidReg[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_1));
146     cidReg[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_2));
147     cidReg[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_3));
148 
149     if (CC_PalMemCmp((uint8_t*)cidVal, (uint8_t*)cidReg, sizeof(cidVal)) != 0){
150         return CC_LIB_RET_EINVAL_CIDR;
151     }
152 
153     return CC_LIB_RET_OK;
154 }
155 
156 
157 /*!
158  * TEE (Trusted Execution Environment) entry point.
159  * Init CryptoCell for TEE.
160  *
161  * @param[in/out] rndContext_ptr  - Pointer to the RND context buffer.
162  * @param[in/out] rndWorkBuff_ptr  - Pointer to the RND scratch buffer.
163  *
164  * \return CClibRetCode_t one of the error codes defined in cc_lib.h
165  */
CC_LibInit(CCRndContext_t * rndContext_ptr,CCRndWorkBuff_t * rndWorkBuff_ptr)166 CClibRetCode_t CC_LibInit(CCRndContext_t *rndContext_ptr, CCRndWorkBuff_t  *rndWorkBuff_ptr)
167 {
168     int rc = 0;
169     CClibRetCode_t retCode = CC_LIB_RET_OK;
170     CCError_t error = CC_OK;
171     uint32_t reg = 0;
172     uint32_t tempVal = 0;
173 
174     /* check parameters */
175     if (rndContext_ptr == NULL)
176         return CC_LIB_RET_EINVAL_CTX_PTR;
177     if (rndWorkBuff_ptr == NULL)
178         return CC_LIB_RET_EINVAL_WORK_BUF_PTR;
179     if (rndContext_ptr->rndState == NULL)
180         return CC_LIB_RET_EINVAL_CTX_PTR;
181     if (rndContext_ptr->entropyCtx == NULL)
182         return CC_LIB_RET_EINVAL_CTX_PTR;
183 
184     rc = CC_HalInit();
185     if (rc != CC_LIB_RET_OK) {
186         retCode = CC_LIB_RET_HAL;
187         goto InitErr1;
188     }
189 
190     rc = CC_PalInit();
191     if (rc != CC_LIB_RET_OK) {
192         retCode = CC_LIB_RET_PAL;
193         goto InitErr;
194     }
195 
196     /* verify peripheral ID (PIDR) */
197     rc = VerifyPidVal();
198     if (rc != CC_LIB_RET_OK) {
199         retCode = CC_LIB_RET_EINVAL_PIDR;
200         goto InitErr2;
201     }
202 
203     /* verify component ID (CIDR) */
204     rc = VerifyCidVal();
205     if (rc != CC_LIB_RET_OK) {
206         retCode = CC_LIB_RET_EINVAL_CIDR;
207         goto InitErr2;
208     }
209 
210     /* turn off the DFA since Cerberus doen't support it */
211     reg = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));
212     CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_FORCE_DFA_ENABLE, reg, 0x0);
213     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS)  ,reg );
214     tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF,HOST_AO_LOCK_BITS));
215     if(tempVal != reg) {
216         retCode = CC_LIB_AO_WRITE_FAILED_ERR;
217         goto InitErr2;
218     }
219 
220     CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_DFA_ENABLE_LOCK, reg, CC_TRUE);
221     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS)  ,reg );
222     tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF,HOST_AO_LOCK_BITS));
223     if(tempVal != reg) {
224         retCode = CC_LIB_AO_WRITE_FAILED_ERR;
225         goto InitErr2;
226     }
227 
228     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_DFA_IS_ON)  ,0x0UL );
229 
230 #ifdef BIG__ENDIAN
231 /* Set DMA endianess to big */
232     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
233 #else /* LITTLE__ENDIAN */
234     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
235 #endif
236 
237     CC_PAL_PERF_INIT();
238 
239     /* Initialize RND module */
240     error = RndStartupTest(rndWorkBuff_ptr);
241     if (error != 0) {
242         retCode = CC_LIB_RET_RND_INST_ERR;
243         goto InitErr2;
244     }
245 
246     /* Initialize mbedTLS random function*/
247     mbedtls_ctr_drbg_init(rndContext_ptr->rndState);
248     mbedtls_entropy_init( rndContext_ptr->entropyCtx );
249     error = mbedtls_ctr_drbg_seed(rndContext_ptr->rndState, mbedtls_entropy_func, rndContext_ptr->entropyCtx,
250             NULL, 0);
251     if (error != 0) {
252         retCode = CC_LIB_RET_RND_INST_ERR;
253         goto InitErr2;
254     }
255 
256     error = CC_RndSetGenerateVectorFunc(rndContext_ptr, mbedtls_ctr_drbg_random);
257     if (error != 0) {
258         retCode = CC_LIB_RET_RND_INST_ERR;
259         goto InitErr2;
260     }
261     error = InitHukRma(rndContext_ptr);
262     if (error != 0) {
263         retCode = CC_LIB_RET_RND_INST_ERR;
264         goto InitErr2;
265     }
266     return CC_LIB_RET_OK;
267     InitErr2:
268     CC_HalTerminate();
269 
270     InitErr1:
271     CC_PalTerminate();
272 
273     InitErr:
274     return retCode;
275 }
276 
277 
278 /*!
279  * TEE (Trusted Execution Environment) exit point.
280  * Finalize CryptoCell for TEE operation, release associated resources.
281  *                                                                    .
282  * @param[in/out] rndContext_ptr  - Pointer to the RND context buffer.
283  */
CC_LibFini(CCRndContext_t * rndContext_ptr)284 CClibRetCode_t CC_LibFini(CCRndContext_t *rndContext_ptr)
285 {
286     CCError_t rc = CC_OK;
287     CClibRetCode_t retCode = CC_LIB_RET_OK;
288 
289     /* check parameters */
290     if (rndContext_ptr == NULL)
291         return CC_LIB_RET_EINVAL_CTX_PTR;
292 
293     rc = CC_HalTerminate();
294     if (rc != 0){
295         retCode = CC_LIB_RET_HAL;
296     }
297     CC_PalTerminate();
298 
299     rndContext_ptr->rndGenerateVectFunc=NULL;
300     mbedtls_ctr_drbg_free( rndContext_ptr->rndState );
301     mbedtls_entropy_free( rndContext_ptr->entropyCtx );
302 
303     CC_PAL_PERF_FIN();
304 
305     return retCode;
306 
307 }
308 
__cyg_profile_func_enter(void * this_fn,void * call_site)309 void __cyg_profile_func_enter (void *this_fn, void *call_site) {
310     unsigned int i;
311     CC_UNUSED_PARAM(i);
312     CC_UNUSED_PARAM(this_fn);
313     CC_UNUSED_PARAM(call_site);
314 
315     CC_PAL_LOG_ERR("Entering: %p -> %p (stack: %p)\n",
316                     call_site, this_fn, &i );
317 }
318 
__cyg_profile_func_exit(void * this_fn,void * call_site)319 void __cyg_profile_func_exit (void *this_fn, void *call_site) {
320     unsigned int i;
321     CC_UNUSED_PARAM(i);
322     CC_UNUSED_PARAM(this_fn);
323     CC_UNUSED_PARAM(call_site);
324 
325     CC_PAL_LOG_ERR("Exiting: %p <- %p (stack: %p)\n",
326                      call_site, this_fn, &i );
327 }
328 
329