1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 
8 
9 /************* Include Files ****************/
10 #include "mbedtls_cc_mng.h"
11 #include "mbedtls_cc_mng_error.h"
12 #include "mbedtls_cc_mng_int.h"
13 #include "cc_pal_types.h"
14 #include "cc_pal_mem.h"
15 #include "cc_otp_defs.h"
16 #include "dx_id_registers.h"
17 #include "dx_crys_kernel.h"
18 #include "driver_defs.h"
19 #include "cc_pal_abort.h"
20 #include "cc_pal_mutex.h"
21 #include "cc_util_pm.h"
22 #include "cc_util_apbc.h"
23 
24 
25 extern CC_PalMutex CCSymCryptoMutex;
26 extern CC_PalMutex CCAsymCryptoMutex;
27 extern CC_PalMutex CCRndCryptoMutex;
28 extern CC_PalMutex CCApbFilteringRegMutex;
29 
30 /************* Auxiliary API's *************/
31 
setHwKeyToShadowReg(mbedtls_mng_keytype keyType,uint32_t * pHwKey,size_t keySize)32 static CCError_t setHwKeyToShadowReg(mbedtls_mng_keytype keyType, uint32_t *pHwKey, size_t keySize)
33 {
34     CCError_t rc = CC_OK;
35     uint32_t  wordIdx;
36     uint32_t  regAddr = 0;
37     uint32_t  regVal = 0;
38     uint32_t  shft = 0;
39 
40     /* check input variables */
41     if (pHwKey == NULL) {
42         return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
43     }
44 
45         switch (keyType) {
46     case CC_MNG_HUK_KEY:
47         if (AES_256_BIT_KEY_SIZE != keySize) {
48             return CC_MNG_ILLEGAL_HUK_SIZE_ERR;
49         }
50         regAddr = DX_HOST_SHADOW_KDR_REG_REG_OFFSET;
51                 break;
52     case CC_MNG_PROV_KEY:
53         if (AES_128_BIT_KEY_SIZE != keySize) {
54             return CC_MNG_ILLEGAL_HW_KEY_SIZE_ERR;
55         }
56         shft    = CC_MNG_HOST_KCP_LOCK_BIT_SHFT;
57         regAddr = DX_HOST_SHADOW_KCP_REG_REG_OFFSET;
58                 break;
59     case CC_MNG_CE_KEY:
60         if (AES_128_BIT_KEY_SIZE != keySize) {
61             return CC_MNG_ILLEGAL_HW_KEY_SIZE_ERR;
62         }
63         shft    = CC_MNG_HOST_KCE_LOCK_BIT_SHFT;
64         regAddr = DX_HOST_SHADOW_KCE_REG_REG_OFFSET;
65                 break;
66     case CC_MNG_ICV_PROV_KEY:
67         if (AES_128_BIT_KEY_SIZE != keySize) {
68             return CC_MNG_ILLEGAL_HW_KEY_SIZE_ERR;
69         }
70         shft    = CC_MNG_HOST_KPICV_LOCK_BIT_SHFT;
71         regAddr = DX_HOST_SHADOW_KPICV_REG_REG_OFFSET;
72                 break;
73     case CC_MNG_ICV_CE_KEY:
74         if (AES_128_BIT_KEY_SIZE != keySize) {
75             return CC_MNG_ILLEGAL_HW_KEY_SIZE_ERR;
76         }
77         shft    = CC_MNG_HOST_KCEICV_LOCK_BIT_SHFT;
78         regAddr = DX_HOST_SHADOW_KCEICV_REG_REG_OFFSET;
79                 break;
80     default:
81         rc = CC_MNG_INVALID_KEY_TYPE_ERROR;
82                 break;
83         }
84 
85         if ((CC_OK == rc) && (CC_MNG_HUK_KEY != keyType)) {
86         /* read APB slave accesses control register */
87         regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));
88         /* check if relevant HW key is already locked */
89         if(CC_TRUE == ((regVal>>shft)&0x1)) {
90             rc = CC_MNG_HW_KEY_IS_LOCKED_ERR;
91         }
92         }
93 
94         /* Load HW key (HUK / KCP / KCE / KPICV / KCEICV) */
95     if (CC_OK == rc) {
96         /* Set HW Key Value in the Shadow register */
97         for (wordIdx = 0; wordIdx < (keySize>>2); wordIdx++) {
98             CC_HAL_WRITE_REGISTER(regAddr, pHwKey[wordIdx]);
99         }
100     }
101 
102         return rc;
103 }
104 
VerifyReadPidVal(uint32_t * pidReg,size_t pidSize)105 static int VerifyReadPidVal(uint32_t *pidReg, size_t pidSize)
106 {
107     uint32_t pidVal1[CC_MNG_PID_SIZE_WORDS] = {CC_MNG_PID_0_VAL, CC_MNG_PID_1_VAL, CC_MNG_PID_2_VAL, CC_MNG_PID_3_VAL, CC_MNG_PID_4_VAL};
108     uint32_t pidVal2[CC_MNG_PID_SIZE_WORDS] = {CC_MNG_PID_0_VAL, CC_MNG_PID_1_VAL, CC_MNG_PID_2_1_VAL, CC_MNG_PID_3_VAL, CC_MNG_PID_4_VAL};
109 
110     if (pidReg == NULL || pidSize != CC_MNG_PID_SIZE_WORDS) {
111         return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
112     }
113 
114     pidReg[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_0));
115     pidReg[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_1));
116     pidReg[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_2));
117     pidReg[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_3));
118     pidReg[4] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_4));
119 
120     if ((CC_PalMemCmp((uint8_t*)pidVal1, (uint8_t*)pidReg, sizeof(pidVal1)) != 0) &&
121             (CC_PalMemCmp((uint8_t*)pidVal2, (uint8_t*)pidReg, sizeof(pidVal2)) != 0)) {
122         return CC_MNG_ILLEGAL_PIDR_ERR;
123     }
124 
125     return CC_OK;
126 }
127 
VerifyCidVal(void)128 static int VerifyCidVal(void)
129 {
130     uint32_t cidReg[CC_BSV_CID_SIZE_WORDS] = {0};
131     uint32_t cidVal[CC_MNG_CID_SIZE_WORDS] = {CC_MNG_CID_0_VAL, CC_MNG_CID_1_VAL, CC_MNG_CID_2_VAL, CC_MNG_CID_3_VAL};
132 
133     cidReg[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_0));
134     cidReg[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_1));
135     cidReg[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_2));
136     cidReg[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_3));
137 
138     if (CC_PalMemCmp((uint8_t*)cidVal, (uint8_t*)cidReg, sizeof(cidVal)) != 0){
139         return CC_MNG_ILLEGAL_CIDR_ERR;
140     }
141 
142     return CC_OK;
143 }
144 
145 /***************** API's *******************/
146 
147 /* The function reads the OEM flags OTP word (see Table 41: OEM-Programmed Flags (word 0x21 in OTP memory))
148    and returns whether the RMA status is pending or not. */
149 
mbedtls_mng_pending_rma_status_get(uint32_t * isPendingRMA)150 int mbedtls_mng_pending_rma_status_get(uint32_t *isPendingRMA)
151 {
152     int       rc        = CC_OK;
153     uint32_t  regVal    = CC_MNG_INVALID_REG_VAL;
154     uint32_t  lcsVal    = 0;
155     uint32_t  isHbkFull = 0;
156     CCError_t error     = CC_OK;
157 
158     if (isPendingRMA == NULL) {
159         return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
160     }
161     *isPendingRMA = CC_FALSE;
162 
163     /* Read LCS Register */
164     rc = mbedtls_mng_lcsGet(&lcsVal);
165     if (CC_OK != rc) {
166         return rc;
167     }
168 
169     /* Check LCS value */
170     if ((CC_MNG_LCS_DM != lcsVal) && (CC_MNG_LCS_SEC_ENABLED != lcsVal)) {
171         return CC_MNG_ILLEGAL_OPERATION_ERR;
172     }
173 
174     /* Read OTP Word #21 */
175     rc = mbedtls_mng_otpWordRead(CC_OTP_OEM_FLAG_OFFSET, &regVal);
176     if (CC_OK != rc) {
177         return rc;
178     }
179 
180     /* get HBK configuration */
181     CC_IS_HBK_FULL(isHbkFull, error);
182     if (CC_OK != error) {
183         return error;
184     }
185 
186     /* if device supports full Hbk, return with error */
187     if (CC_TRUE == isHbkFull) {
188         return CC_MNG_ILLEGAL_OPERATION_ERR;
189     }
190 
191     regVal >>= CC_MNG_OEM_RMA_SHFT;
192     regVal &= CC_MNG_OEM_RMA_MSK;
193 
194     switch (regVal) {
195     case CC_MNG_NON_RMA:
196         *isPendingRMA = CC_FALSE;
197         break;
198     case CC_MNG_PENDING_RMA:
199         *isPendingRMA = CC_TRUE;
200         break;
201     case CC_MNG_ILLEGAL_STATE:
202         rc = CC_MNG_RMA_ILLEGAL_STATE_ERR;
203         *isPendingRMA = CC_FALSE;
204         break;
205     case CC_MNG_RMA:
206         *isPendingRMA = CC_FALSE;
207         break;
208     default:
209         break;
210     }
211 
212     return rc;
213 }
214 
mbedtls_mng_hw_version_get(uint32_t * partNumber,uint32_t * revision)215 int mbedtls_mng_hw_version_get(uint32_t *partNumber, uint32_t *revision)
216 {
217     uint32_t pidReg[CC_MNG_PID_SIZE_WORDS] = {0};
218 
219     if (partNumber == NULL || revision == NULL) {
220         return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
221     }
222 
223     /* verify peripheral ID (PIDR) */
224     if (0 != VerifyReadPidVal(pidReg, CC_MNG_PID_SIZE_WORDS) ) {
225         return CC_MNG_ILLEGAL_PIDR_ERR;
226     }
227 
228     /* verify component ID (CIDR) */
229     if (0 != VerifyCidVal() ) {
230         return CC_MNG_ILLEGAL_CIDR_ERR;
231     }
232 
233     *partNumber = (pidReg[0] & 0xFF) | ((pidReg[1] & 0x0F) << 8);
234     *revision   = (pidReg[2] >> 4) & 0x0F;
235 
236     return CC_OK;
237 }
238 
mbedtls_mng_cc_sec_mode_set(CCBool_t isSecAccessMode,CCBool_t isSecModeLock)239 int mbedtls_mng_cc_sec_mode_set(CCBool_t isSecAccessMode, CCBool_t isSecModeLock)
240 {
241     uint32_t rc     = CC_OK;
242     uint32_t regVal = 0, tempVal;
243 
244     /* verify input parameters */
245     if((CC_TRUE != isSecAccessMode) && (CC_FALSE != isSecAccessMode)) {
246         return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
247     }
248 
249     if((CC_TRUE != isSecModeLock) && (CC_FALSE != isSecModeLock)) {
250         return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
251     }
252 
253     /* Lock mutexes for all hw operation */
254     if (CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE) != 0) {
255         CC_PalAbort("Fail to acquire 'CCSymCryptoMutex'\n");
256     }
257 
258     if (CC_PalMutexLock(&CCAsymCryptoMutex, CC_INFINITE) != 0) {
259         CC_PalAbort("Fail to acquire 'CCAsymCryptoMutex'\n");
260     }
261 
262     if (CC_PalMutexLock(&CCRndCryptoMutex, CC_INFINITE) != 0) {
263         CC_PalAbort("Fail to acquire 'CCRndCryptoMutex'\n");
264     }
265 
266     if (CC_PalMutexLock(&CCApbFilteringRegMutex, CC_INFINITE) != 0) {
267         CC_PalAbort("Fail to acquire 'CCApbFilteringRegMutex'\n");
268     }
269 
270     /* read APB slave accesses control register */
271     regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
272 
273     /* check if security mode is already locked */
274     if(CC_TRUE == CC_REG_FLD_GET(0, AO_APB_FILTERING, ONLY_SEC_ACCESS_ALLOW_LOCK, regVal)) {
275         rc = CC_MNG_APB_SECURE_IS_LOCKED_ERR;
276         goto mbedtls_mng_setCCSecMode_END;
277     }
278 
279     /* set security mode */
280     CC_REG_FLD_SET(0, AO_APB_FILTERING, ONLY_SEC_ACCESS_ALLOW, regVal, isSecAccessMode);
281     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING), regVal);
282     tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
283     if(tempVal != regVal) {
284         rc = CC_MNG_AO_APB_WRITE_FAILED_ERR;
285         goto mbedtls_mng_setCCSecMode_END;
286     }
287 
288     /* set security lock */
289     CC_REG_FLD_SET(0, AO_APB_FILTERING, ONLY_SEC_ACCESS_ALLOW_LOCK, regVal, isSecModeLock);
290     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING), regVal);
291     tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
292     if(tempVal != regVal) {
293         rc = CC_MNG_AO_APB_WRITE_FAILED_ERR;
294         goto mbedtls_mng_setCCSecMode_END;
295     }
296 
297 mbedtls_mng_setCCSecMode_END:
298     /* Release mutexes */
299     if (CC_PalMutexUnlock(&CCApbFilteringRegMutex) != 0) {
300         CC_PalAbort("Fail to release 'CCApbFilteringRegMutex'\n");
301     }
302 
303     if (CC_PalMutexUnlock(&CCRndCryptoMutex) != 0) {
304         CC_PalAbort("Fail to release 'CCRndCryptoMutex'\n");
305     }
306 
307     if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != 0) {
308         CC_PalAbort("Fail to release 'CCAsymCryptoMutex'\n");
309     }
310 
311     if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
312         CC_PalAbort("Fail to release 'CCSymCryptoMutex'\n");
313     }
314 
315     return rc;
316 }
317 
mbedtls_mng_cc_priv_mode_set(CCBool_t isPrivAccessMode,CCBool_t isPrivModeLock)318 int mbedtls_mng_cc_priv_mode_set(CCBool_t isPrivAccessMode, CCBool_t isPrivModeLock)
319 {
320     uint32_t rc     = CC_OK;
321     uint32_t regVal = 0, tempVal = 0;
322 
323     /* verify input parameters */
324     if((CC_TRUE != isPrivAccessMode) && (CC_FALSE != isPrivAccessMode)) {
325         return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
326     }
327 
328     if((CC_TRUE != isPrivModeLock) && (CC_FALSE != isPrivModeLock)) {
329         return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
330     }
331 
332     /* Lock mutexes for all hw operation */
333     if (CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE) != 0) {
334         CC_PalAbort("Fail to acquire 'CCSymCryptoMutex'\n");
335     }
336 
337     if (CC_PalMutexLock(&CCAsymCryptoMutex, CC_INFINITE) != 0) {
338         CC_PalAbort("Fail to acquire 'CCAsymCryptoMutex'\n");
339     }
340 
341     if (CC_PalMutexLock(&CCRndCryptoMutex, CC_INFINITE) != 0) {
342         CC_PalAbort("Fail to acquire 'CCRndCryptoMutex'\n");
343     }
344 
345     if (CC_PalMutexLock(&CCApbFilteringRegMutex, CC_INFINITE) != 0) {
346         CC_PalAbort("Fail to acquire 'CCApbFilteringRegMutex'\n");
347     }
348 
349     /* read APB slave accesses control register */
350     regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
351 
352     /* check if privileged mode is already locked */
353     if( CC_REG_FLD_GET(0, AO_APB_FILTERING, ONLY_PRIV_ACCESS_ALLOW_LOCK, regVal) == CC_TRUE) {
354         rc = CC_MNG_APB_PRIVILEGE_IS_LOCKED_ERR;
355         goto mbedtls_mng_setCCPrivMode_END;
356     }
357 
358     /* set privileged mode */
359     CC_REG_FLD_SET(0, AO_APB_FILTERING, ONLY_PRIV_ACCESS_ALLOW, regVal, isPrivAccessMode);
360     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING), regVal);
361     tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
362     if(tempVal != regVal) {
363         rc = CC_MNG_AO_APB_WRITE_FAILED_ERR;
364         goto mbedtls_mng_setCCPrivMode_END;
365     }
366 
367     /* set privileged lock */
368     CC_REG_FLD_SET(0, AO_APB_FILTERING, ONLY_PRIV_ACCESS_ALLOW_LOCK, regVal, isPrivModeLock);
369     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING), regVal);
370     tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
371     if(tempVal != regVal) {
372         rc = CC_MNG_AO_APB_WRITE_FAILED_ERR;
373         goto mbedtls_mng_setCCPrivMode_END;
374     }
375 
376 mbedtls_mng_setCCPrivMode_END:
377     /* Release mutexes */
378     if (CC_PalMutexUnlock(&CCApbFilteringRegMutex) != 0) {
379         CC_PalAbort("Fail to release 'CCApbFilteringRegMutex'\n");
380     }
381 
382     if (CC_PalMutexUnlock(&CCRndCryptoMutex) != 0) {
383         CC_PalAbort("Fail to release 'CCRndCryptoMutex'\n");
384     }
385 
386     if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != 0) {
387         CC_PalAbort("Fail to release 'CCAsymCryptoMutex'\n");
388     }
389 
390     if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
391         CC_PalAbort("Fail to release 'CCSymCryptoMutex'\n");
392     }
393 
394     return rc;
395 }
396 
mbedtls_mng_debug_key_set(mbedtls_mng_keytype keyType,uint32_t * pHwKey,size_t keySize)397 int mbedtls_mng_debug_key_set(mbedtls_mng_keytype keyType, uint32_t *pHwKey, size_t keySize)
398 {
399     int      rc     = CC_OK;
400     uint32_t lcsVal = 0;
401 
402     /* Lock mutex for all hw operation */
403     if (CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE) != 0) {
404         CC_PalAbort("Fail to acquire mutex\n");
405     }
406 
407     /* Read LCS Register */
408     rc = mbedtls_mng_lcsGet(&lcsVal);
409     if (CC_OK != rc) {
410         goto mbedtls_mng_setDebugKey_END;
411     }
412 
413     /* Check LCS value */
414     if ((CC_MNG_LCS_DM != lcsVal) && (CC_MNG_LCS_CM != lcsVal)) {
415         rc = CC_MNG_ILLEGAL_OPERATION_ERR;
416         goto mbedtls_mng_setDebugKey_END;
417     }
418 
419     rc = setHwKeyToShadowReg(keyType, pHwKey, keySize);
420 
421 mbedtls_mng_setDebugKey_END:
422     /* Release mutex */
423     if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
424         CC_PalAbort("Fail to release mutex\n");
425     }
426 
427     return rc;
428 }
429 
mbedtls_mng_gen_config_get(uint32_t * pOtpWord)430 int mbedtls_mng_gen_config_get(uint32_t *pOtpWord)
431 {
432     int rc = 0;
433 
434     rc = mbedtls_mng_otpWordRead(CC_OTP_ICV_GENERAL_PURPOSE_FLAG_OFFSET, pOtpWord);
435     if (CC_OK != rc) {
436         return rc;
437     }
438 
439     return CC_OK;
440 }
441 
mbedtls_mng_oem_key_lock(CCBool_t kcpLock,CCBool_t kceLock)442 int mbedtls_mng_oem_key_lock(CCBool_t kcpLock, CCBool_t kceLock)
443 {
444     int      rc     = CC_OK;
445     uint32_t lcsVal = 0;
446     uint32_t regVal = 0, tempVal = 0;
447 
448     /* Lock mutex for all hw operation */
449     if (CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE) != 0) {
450         CC_PalAbort("Fail to acquire mutex\n");
451     }
452 
453     /* Read LCS Register */
454     rc = mbedtls_mng_lcsGet(&lcsVal);
455     if (CC_OK != rc)
456     {
457         goto mbedtls_mng_lockOemKey_END;
458     }
459 
460     /* Check LCS value */
461     if ((CC_MNG_LCS_SEC_ENABLED != lcsVal) && (CC_MNG_LCS_RMA != lcsVal))
462     {
463         goto mbedtls_mng_lockOemKey_END;
464     }
465 
466     /* Verify input parameters */
467     if((CC_TRUE != kcpLock) && (CC_FALSE != kcpLock)) {
468         rc = CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
469         goto mbedtls_mng_lockOemKey_END;
470     }
471 
472     if((CC_TRUE != kceLock)  && (CC_FALSE != kceLock)) {
473         rc = CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
474         goto mbedtls_mng_lockOemKey_END;
475     }
476 
477     /* read AO Lock Bits register */
478     regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));
479 
480     /* check if Kcp is already locked and the user wants to lock it */
481     if((CC_TRUE == CC_REG_FLD_GET(0, HOST_AO_LOCK_BITS, HOST_KCP_LOCK, regVal)) &&
482        (CC_TRUE == kcpLock)) {
483         rc = CC_MNG_KCP_IS_LOCKED_ERR;
484         goto mbedtls_mng_lockOemKey_END;
485     }
486 
487     /* check if Kce is already locked and the user wants to lock it */
488     if((CC_TRUE == CC_REG_FLD_GET(0, HOST_AO_LOCK_BITS, HOST_KCE_LOCK, regVal)) &&
489        (CC_TRUE == kceLock)) {
490         rc = CC_MNG_KCE_IS_LOCKED_ERR;
491         goto mbedtls_mng_lockOemKey_END;
492     }
493 
494     /* Set lock only - do not unlock */
495     if (CC_TRUE == kcpLock) {
496         /* set Kcp lock */
497         CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_KCP_LOCK, regVal, kcpLock);
498     }
499 
500     /* Set lock only - do not unlock */
501     if (CC_TRUE == kceLock) {
502         /* set Kce lock */
503         CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_KCE_LOCK, regVal, kceLock);
504     }
505 
506     /* write APB slave accesses control register */
507     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS), regVal);
508     tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));
509     if(tempVal != regVal) {
510         rc = CC_MNG_AO_APB_WRITE_FAILED_ERR;
511         goto mbedtls_mng_lockOemKey_END;
512     }
513 
514 mbedtls_mng_lockOemKey_END:
515     /* Release mutex */
516     if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
517         CC_PalAbort("Fail to release mutex\n");
518     }
519 
520     return rc;
521 }
522 
mbedtls_mng_apbc_part_config(mbedtls_mng_apbcconfig * apbcConfig,uint32_t partId,uint32_t partCfg)523 static int mbedtls_mng_apbc_part_config(mbedtls_mng_apbcconfig *apbcConfig, uint32_t partId, uint32_t partCfg)
524 {
525     if (partCfg >= CC_MNG_APBC_TOTAL_PARTS_CONFIG)
526     {
527             return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
528     }
529 
530     switch (partCfg) {
531     case CC_MNG_APBC_NO_CHANGE:
532         apbcConfig->apbcPart[partId].apbcPartBits.accessAllow = 0;
533         apbcConfig->apbcPart[partId].apbcPartBits.accessAllowLock = 0;
534         apbcConfig->apbcPart[partId].apbcPartBits.accessModify = 0;
535     break;
536     case CC_MNG_APBC_ALLOW_0_ALLOWLOCK_0:
537         apbcConfig->apbcPart[partId].apbcPartBits.accessAllow = 0;
538         apbcConfig->apbcPart[partId].apbcPartBits.accessAllowLock = 0;
539         apbcConfig->apbcPart[partId].apbcPartBits.accessModify = 1;
540     break;
541     case CC_MNG_APBC_ALLOW_0_ALLOWLOCK_1:
542         apbcConfig->apbcPart[partId].apbcPartBits.accessAllow = 0;
543         apbcConfig->apbcPart[partId].apbcPartBits.accessAllowLock = 1;
544         apbcConfig->apbcPart[partId].apbcPartBits.accessModify = 1;
545     break;
546     case CC_MNG_APBC_ALLOW_1_ALLOWLOCK_0:
547         apbcConfig->apbcPart[partId].apbcPartBits.accessAllow = 1;
548         apbcConfig->apbcPart[partId].apbcPartBits.accessAllowLock = 0;
549         apbcConfig->apbcPart[partId].apbcPartBits.accessModify = 1;
550     break;
551     case CC_MNG_APBC_ALLOW_1_ALLOWLOCK_1:
552         apbcConfig->apbcPart[partId].apbcPartBits.accessAllow = 1;
553         apbcConfig->apbcPart[partId].apbcPartBits.accessAllowLock = 1;
554         apbcConfig->apbcPart[partId].apbcPartBits.accessModify = 1;
555     break;
556     default:
557         return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
558     }
559 
560     return 0;
561 }
562 
mbedtls_mng_apbc_config_set(mbedtls_mng_apbc_parts_config securePartCfg,mbedtls_mng_apbc_parts_config privPartCfg,mbedtls_mng_apbc_parts_config instPartCfg)563 int mbedtls_mng_apbc_config_set(mbedtls_mng_apbc_parts_config securePartCfg,
564                                 mbedtls_mng_apbc_parts_config privPartCfg,
565                                 mbedtls_mng_apbc_parts_config instPartCfg)
566 {
567     uint32_t rc = CC_OK;
568     uint32_t regVal = 0, tempVal = 0;
569     mbedtls_mng_apbcconfig apbcConfig = {0};
570 
571     /* Lock mutex for all hw operation */
572     if (CC_PalMutexLock(&CCApbFilteringRegMutex, CC_INFINITE) != 0)
573     {
574         CC_PalAbort("Fail to acquire 'CCApbFilteringRegMutex'\n");
575     }
576 
577     /* Check that there is no access */
578     if (0 != CC_APBC_CNTR_GET)
579     {
580         rc = CC_MNG_APBC_ACCESS_IS_ON_ERR;
581         goto mbedtls_mng_setApbcConfig_END;
582     }
583 
584     /* Set each part attributes according to the user inputs */
585     rc = mbedtls_mng_apbc_part_config(&apbcConfig, CC_MNG_APBC_SEC_ID, securePartCfg);
586     if (rc != 0)
587     {
588         goto mbedtls_mng_setApbcConfig_END;
589     }
590     rc = mbedtls_mng_apbc_part_config(&apbcConfig, CC_MNG_APBC_PRIV_ID, privPartCfg);
591     if (rc != 0)
592     {
593         goto mbedtls_mng_setApbcConfig_END;
594     }
595     rc = mbedtls_mng_apbc_part_config(&apbcConfig, CC_MNG_APBC_INST_ID, instPartCfg);
596     if (rc != 0)
597     {
598         goto mbedtls_mng_setApbcConfig_END;
599     }
600 
601     /* read APB slave accesses control register */
602     regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
603 
604     // Secure part
605     if(apbcConfig.apbcPart[CC_MNG_APBC_SEC_ID].apbcPartBits.accessModify)
606     {
607             /* check if APBC security mode is already locked */
608             if(CC_TRUE == CC_REG_FLD_GET(0, AO_APB_FILTERING, APBC_ONLY_SEC_ACCESS_ALLOW_LOCK, regVal))
609             {
610                 rc = CC_MNG_APBC_SECURE_IS_LOCKED_ERR;
611                 goto mbedtls_mng_setApbcConfig_END;
612             }
613             else
614             {
615                 /* set APBC security mode */
616                 CC_REG_FLD_SET(0, AO_APB_FILTERING, APBC_ONLY_SEC_ACCESS_ALLOW, regVal, apbcConfig.apbcPart[CC_MNG_APBC_SEC_ID].apbcPartBits.accessAllow);
617                 CC_REG_FLD_SET(0, AO_APB_FILTERING, APBC_ONLY_SEC_ACCESS_ALLOW_LOCK, regVal, apbcConfig.apbcPart[CC_MNG_APBC_SEC_ID].apbcPartBits.accessAllowLock);
618             }
619     }
620 
621     // Privileged part
622     if(apbcConfig.apbcPart[CC_MNG_APBC_PRIV_ID].apbcPartBits.accessModify)
623     {
624             /* check if APBC privilege mode is already locked */
625             if(CC_TRUE == CC_REG_FLD_GET(0, AO_APB_FILTERING, APBC_ONLY_PRIV_ACCESS_ALLOW_LOCK, regVal))
626             {
627                 rc = CC_MNG_APBC_PRIVILEGE_IS_LOCKED_ERR;
628                 goto mbedtls_mng_setApbcConfig_END;
629             }
630             else
631             {
632                 /* set APBC security mode */
633                 CC_REG_FLD_SET(0, AO_APB_FILTERING, APBC_ONLY_PRIV_ACCESS_ALLOW, regVal, apbcConfig.apbcPart[CC_MNG_APBC_PRIV_ID].apbcPartBits.accessAllow);
634                 CC_REG_FLD_SET(0, AO_APB_FILTERING, APBC_ONLY_PRIV_ACCESS_ALLOW_LOCK, regVal, apbcConfig.apbcPart[CC_MNG_APBC_PRIV_ID].apbcPartBits.accessAllowLock);
635             }
636     }
637 
638     // Instruction part
639     if(apbcConfig.apbcPart[CC_MNG_APBC_INST_ID].apbcPartBits.accessModify)
640     {
641             /* check if APBC Instruction mode is already locked */
642             if(CC_TRUE == CC_REG_FLD_GET(0, AO_APB_FILTERING, APBC_ONLY_INST_ACCESS_ALLOW_LOCK, regVal))
643             {
644                 rc = CC_MNG_APBC_INSTRUCTION_IS_LOCKED_ERR;
645                 goto mbedtls_mng_setApbcConfig_END;
646             }
647             else
648             {
649                 /* set APBC security mode */
650                 CC_REG_FLD_SET(0, AO_APB_FILTERING, APBC_ONLY_INST_ACCESS_ALLOW, regVal, apbcConfig.apbcPart[CC_MNG_APBC_INST_ID].apbcPartBits.accessAllow);
651                 CC_REG_FLD_SET(0, AO_APB_FILTERING, APBC_ONLY_INST_ACCESS_ALLOW_LOCK, regVal, apbcConfig.apbcPart[CC_MNG_APBC_INST_ID].apbcPartBits.accessAllowLock);
652             }
653     }
654 
655     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING), regVal);
656     tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
657     if(tempVal != regVal) {
658         rc = CC_MNG_AO_APB_WRITE_FAILED_ERR;
659         goto mbedtls_mng_setApbcConfig_END;
660     }
661 
662 mbedtls_mng_setApbcConfig_END:
663     /* Release mutex */
664     if (CC_PalMutexUnlock(&CCApbFilteringRegMutex) != 0)
665     {
666         CC_PalAbort("Fail to release 'CCApbFilteringRegMutex'\n");
667     }
668 
669     return rc;
670 }
671 
mbedtls_mng_apbc_access(CCBool_t isApbcAccessUsed)672 int mbedtls_mng_apbc_access(CCBool_t isApbcAccessUsed)
673 {
674     int rc = CC_OK;
675 
676     if ((isApbcAccessUsed != CC_TRUE) && (isApbcAccessUsed != CC_FALSE)) {
677         return CC_MNG_APBC_ACCESS_FAILED_ERR;
678     }
679 
680     /* Lock mutex for all hw operation */
681     if (CC_PalMutexLock(&CCApbFilteringRegMutex, CC_INFINITE) != 0)
682     {
683         CC_PalAbort("Fail to acquire 'CCApbFilteringRegMutex'\n");
684     }
685 
686     if ((CC_FALSE == isApbcAccessUsed) && (0 == CC_APBC_CNTR_GET))
687     {
688         rc = CC_MNG_APBC_ACCESS_ALREADY_OFF_ERR;
689         goto mbedtls_mng_apbcAccess_END;
690     }
691 
692     if (CC_TRUE == isApbcAccessUsed) {
693         /* increase APBC Access counter */
694         rc = CC_APBC_ACCESS_INC;
695         if (rc != CC_OK) {
696             CC_PalAbort("Fail to increase APBC Access counter\n");
697         }
698         if (1 == CC_APBC_CNTR_GET) {
699             /* increase PM counter at the beginning of first access */
700             rc = CC_IS_WAKE;
701             if (rc != CC_OK) {
702                 CC_PalAbort("Fail to increase PM counter\n");
703             }
704         }
705     } else {
706         /* decrease APBC Access counter */
707         rc = CC_APBC_ACCESS_DEC;
708         if (rc != CC_OK) {
709             CC_PalAbort("Fail to decrease APBC Access counter\n");
710         }
711 
712         if (0 == CC_APBC_CNTR_GET) {
713             /* decrease PM counter at the end of last access */
714             rc = CC_IS_IDLE;
715             if (rc != CC_OK) {
716                 CC_PalAbort("Fail to decrease PM counter\n");
717             }
718         }
719     }
720 
721 mbedtls_mng_apbcAccess_END:
722     /* Release mutex */
723     if (CC_PalMutexUnlock(&CCApbFilteringRegMutex) != 0)
724     {
725         CC_PalAbort("Fail to release 'CCApbFilteringRegMutex'\n");
726     }
727 
728     return rc;
729 }
730 
mbedtls_mng_suspend(uint8_t * pBackupBuffer,size_t backupSize)731 int mbedtls_mng_suspend(uint8_t *pBackupBuffer, size_t backupSize)
732 {
733     int rc = CC_OK;
734     uint32_t regVal = 0;
735 
736     /* check input parameters */
737     if ((pBackupBuffer != NULL) &&
738          ((backupSize <= 0) || (backupSize < CC_MNG_MIN_BACKUP_SIZE_IN_BYTES)) ){
739         return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
740     }
741     /* lock mutexes for all HW operation */
742     if (CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE) != 0) {
743         CC_PalAbort("Fail to acquire 'CCSymCryptoMutex'\n");
744     }
745 
746     if (CC_PalMutexLock(&CCAsymCryptoMutex, CC_INFINITE) != 0) {
747         CC_PalAbort("Fail to acquire 'CCAsymCryptoMutex'\n");
748     }
749 
750     if (CC_PalMutexLock(&CCRndCryptoMutex, CC_INFINITE) != 0) {
751         CC_PalAbort("Fail to acquire 'CCRndCryptoMutex'\n");
752     }
753 
754     if (CC_PalMutexLock(&CCApbFilteringRegMutex, CC_INFINITE) != 0) {
755         CC_PalAbort("Fail to acquire 'CCApbFilteringRegMutex'\n");
756     }
757 
758     /* verify that the FW has no pending tasks */
759     if(CC_STATUS_GET != 0){
760         rc = CC_MNG_PM_SUSPEND_RESUME_FAILED_ERR;
761         goto mbedtls_mng_suspend_END;
762     }
763 
764     /* verify HW is idle */
765     regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_CC_IS_IDLE));
766     if(CC_TRUE != CC_REG_FLD_GET(0, HOST_CC_IS_IDLE, HOST_CC_IS_IDLE, regVal)) {
767         rc = CC_MNG_PM_SUSPEND_RESUME_FAILED_ERR;
768         goto mbedtls_mng_suspend_END;
769     }
770 
771     /* set HW register to notify about the coming event */
772     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_POWERDOWN), CC_TRUE);
773 
774     return CC_OK;
775 
776 mbedtls_mng_suspend_END:
777     /* release mutexes */
778     if (CC_PalMutexUnlock(&CCApbFilteringRegMutex) != 0) {
779         CC_PalAbort("Fail to release 'CCApbFilteringRegMutex'\n");
780     }
781 
782     if (CC_PalMutexUnlock(&CCRndCryptoMutex) != 0) {
783         CC_PalAbort("Fail to release 'CCRndCryptoMutex'\n");
784     }
785 
786     if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != 0) {
787         CC_PalAbort("Fail to release 'CCAsymCryptoMutex'\n");
788     }
789 
790     if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
791         CC_PalAbort("Fail to release 'CCSymCryptoMutex'\n");
792     }
793 
794     return rc;
795 }
796 
mbedtls_mng_resume(uint8_t * pBackupBuffer,size_t backupSize)797 int mbedtls_mng_resume(uint8_t *pBackupBuffer, size_t backupSize)
798 {
799     int rc = CC_OK;
800 
801     /* check input parameters */
802     if ((pBackupBuffer != NULL) &&
803             ((backupSize <= 0) || (backupSize < CC_MNG_MIN_BACKUP_SIZE_IN_BYTES)) ){
804         return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
805     }
806 
807     /* set DMA endianess */
808 #ifdef BIG__ENDIAN
809     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
810 #else
811     CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
812 #endif
813 
814     /* release mutexes */
815     if (CC_PalMutexUnlock(&CCApbFilteringRegMutex) != 0) {
816         CC_PalAbort("Fail to release 'CCApbFilteringRegMutex'\n");
817     }
818 
819     if (CC_PalMutexUnlock(&CCRndCryptoMutex) != 0) {
820         CC_PalAbort("Fail to release 'CCRndCryptoMutex'\n");
821     }
822 
823     if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != 0) {
824         CC_PalAbort("Fail to release 'CCAsymCryptoMutex'\n");
825     }
826 
827     if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
828         CC_PalAbort("Fail to release 'CCSymCryptoMutex'\n");
829     }
830 
831     return rc;
832 }
833 
834 
835