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 Files ****************/
8 #include "dx_rng.h"
9 #include "cc_pal_mem.h"
10 #include "cc_rng_plat.h"
11 #include "dx_crys_kernel.h"
12 #include "cc_hal.h"
13 #include "cc_regs.h"
14 #include "dx_host.h"
15 #include "cc_rnd_local.h"
16 #include "cc_rnd_error.h"
17 #include "llf_rnd_hwdefs.h"
18 #include "llf_rnd.h"
19 #include "llf_rnd_error.h"
20 #include "cc_sram_map.h"
21 #include "cc_plat.h"
22 #include "llf_rnd_trng.h"
23 #include "cc_int_general_defs.h"
24 #ifndef CMPU_UTIL
25 #include "cc_pal_mutex.h"
26 #include "cc_pal_abort.h"
27 #include "cc_util_pm.h"
28 #endif
29 #define ROSC_INIT_START_BIT   0x80000000
30 
31 #if !defined(CMPU_UTIL) && !defined(SC_TEST_MODE)
32 extern CC_PalMutex *pCCRndCryptoMutex;
33 
34 #define MUTEX_LOCK_AND_RETURN_UPON_ERROR(pmutex) \
35         if (CC_PalMutexLock(pmutex, CC_INFINITE) != CC_SUCCESS) { \
36             CC_PalAbort("Fail to acquire mutex\n"); \
37         }
38 
39 #define MUTEX_UNLOCK(pmutex) \
40         if (CC_PalMutexUnlock(pmutex) != CC_SUCCESS) { \
41             CC_PalAbort("Fail to release mutex\n"); \
42         }
43 
44 #define DECREASE_CC_COUNTER \
45         if (CC_IS_IDLE != CC_SUCCESS) { \
46             CC_PalAbort("Fail to decrease PM counter\n"); \
47         }
48 
49 #define INCREASE_CC_COUNTER \
50         if (CC_IS_WAKE != CC_SUCCESS) { \
51             CC_PalAbort("Fail to increase PM counter\n"); \
52         }
53 
54 #else
55 #define MUTEX_LOCK_AND_RETURN_UPON_ERROR(mutex)
56 #define MUTEX_UNLOCK(mutex)
57 #define DECREASE_CC_COUNTER
58 #define INCREASE_CC_COUNTER
59 #endif
60 
61 
62 /*********************************** Enums ******************************/
63 /*********************************Typedefs ******************************/
64 
65 /**************** Global Data to be read by RNG function ****************/
66 
67 /* test variables */
68 #ifdef RND_TEST_TRNG_WITH_ESTIMATOR
69 uint32_t  gEntrSize[4];
70 #endif
71 
72 
73 /************************************************************************************/
74 /**
75  * The function checks that parameters, loaded in the TRNG HW
76  * are match to parameters, required by trngParams_ptr structures.
77  *
78  * @author reuvenl (6/25/2012)
79  *
80  * @param trngParams_ptr
81  *
82  * @return CCError_t
83  */
LLF_RND_TRNG_CheckHwParams(CCRndParams_t * trngParams_ptr)84 static CCError_t LLF_RND_TRNG_CheckHwParams(CCRndParams_t *trngParams_ptr)
85 {
86     uint32_t temp;
87     CCBool_t isTrue = CC_TRUE;
88 
89     /* check Debug control - masked TRNG tests according to mode */
90     temp = CC_HAL_READ_REGISTER(CC_REG_OFFSET(RNG, TRNG_DEBUG_CONTROL));
91     isTrue &= (temp == LLF_RND_HW_DEBUG_CONTROL_VALUE_ON_FE_MODE);
92     /* check samplesCount */
93     temp = CC_HAL_READ_REGISTER(CC_REG_OFFSET(RNG,SAMPLE_CNT1));
94     isTrue &= (temp == trngParams_ptr->SubSamplingRatio);
95 
96     /* if any parameters are not match return an Error */
97         if (isTrue == CC_FALSE) {
98                 return LLF_RND_TRNG_PREVIOUS_PARAMS_NOT_MATCH_ERROR;
99         }
100         else {
101                 return CC_OK;
102         }
103 }
104 
LLF_RND_TRNG_RoscMaskToNum(uint32_t mask)105 static uint32_t LLF_RND_TRNG_RoscMaskToNum(uint32_t mask)
106 {
107         return (mask == LLF_RND_HW_TRNG_ROSC3_BIT) ? LLF_RND_HW_TRNG_ROSC3_NUM :
108                 (mask == LLF_RND_HW_TRNG_ROSC2_BIT) ? LLF_RND_HW_TRNG_ROSC2_NUM :
109                 (mask == LLF_RND_HW_TRNG_ROSC1_BIT) ? LLF_RND_HW_TRNG_ROSC1_NUM :
110                 LLF_RND_HW_TRNG_ROSC0_NUM;
111 }
112 
LLF_RND_TRNG_EnableRngSourceAndWatchdog(CCRndParams_t * trngParams_ptr)113 static void LLF_RND_TRNG_EnableRngSourceAndWatchdog(CCRndParams_t *trngParams_ptr)
114 {
115         uint32_t maxCycles;
116         uint32_t ehrSamples;
117 
118         /* set EHR samples = 2 /384 bit/ for both AES128 and AES256 */
119         ehrSamples = LLF_RND_HW_DMA_EHR_SAMPLES_NUM_ON_FE_MODE;
120 
121         /* Set watchdog threshold to maximal allowed time (in CPU cycles) */
122         maxCycles = LLF_RND_CalcMaxTrngTime(ehrSamples, trngParams_ptr->SubSamplingRatio);
123         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_WATCHDOG_VAL), maxCycles);
124 
125         /* enable the RND source */
126         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RND_SOURCE_ENABLE), LLF_RND_HW_RND_SRC_ENABLE_VAL);
127 }
128 
LLF_RND_TRNG_ReadEhrData(uint32_t * pSourceOut,bool isFipsSupported)129 static CCError_t LLF_RND_TRNG_ReadEhrData(uint32_t *pSourceOut, bool isFipsSupported)
130 {
131         CCError_t error = CC_OK;
132         uint32_t isr = 0;
133         uint32_t i;
134 
135 
136 
137         /* wait RNG interrupt: isr signals error bits */
138         error = LLF_RND_WaitRngInterrupt(&isr);
139         if (error != CC_OK){
140                 return error;
141         }
142 
143         error = LLF_RND_TRNG_REQUIRED_ROSCS_NOT_ALLOWED_ERROR;
144         if (CC_REG_FLD_GET(0, RNG_ISR, EHR_VALID, isr)) {
145                 error = CC_OK;
146         }
147         if (CC_REG_FLD_GET(0, RNG_ISR, CRNGT_ERR, isr) && isFipsSupported) {
148                 /* CRNGT requirements for FIPS 140-2. Should not try the next ROSC in FIPS mode. */
149                 error = LLF_RND_CRNGT_TEST_FAIL_ERROR;
150         }
151 
152         /* in case of AUTOCORR_ERR or RNG_WATCHDOG, keep the default error value. will try the next ROSC. */
153 
154         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_ICR), 0xFFFFFFFF);
155 
156         if (error == CC_OK) {
157                 for (i = 0; i < LLF_RND_HW_TRNG_EHR_WIDTH_IN_WORDS; i++)
158                 {
159                         /* load the current random data to the output buffer */
160                         *(pSourceOut++) = CC_HAL_READ_REGISTER(DX_EHR_DATA_0_REG_OFFSET + (i*sizeof(uint32_t)));
161                 }
162                 CC_HAL_READ_REGISTER(CC_REG_OFFSET(RNG, RNG_ISR));
163         }
164 
165         return error;
166 }
167 
168 /****************************************************************************************/
169 /*****************************       Public Functions      ******************************/
170 /****************************************************************************************/
171 
172 
LLF_RND_StartTrngHW(CCRndState_t * rndState_ptr,CCRndParams_t * trngParams_ptr,CCBool_t isRestart,uint32_t * roscsToStart_ptr)173 CCError_t LLF_RND_StartTrngHW(
174         CCRndState_t  *rndState_ptr,
175         CCRndParams_t *trngParams_ptr,
176         CCBool_t           isRestart,
177         uint32_t         *roscsToStart_ptr)
178 {
179         /* LOCAL DECLARATIONS */
180 
181         CCError_t error = CC_OK;
182         uint32_t tmpSamplCnt = 0;
183         uint32_t roscNum = 0;
184 #ifdef CC_IOT
185         uint32_t mask = 0;
186 #endif
187         /* FUNCTION LOGIC */
188 
189         /* Check pointers */
190         if ((rndState_ptr == NULL) || (trngParams_ptr == NULL) ||
191                 (roscsToStart_ptr == NULL))
192                 return LLF_RND_TRNG_ILLEGAL_PTR_ERROR;
193 
194 
195         /*--------------------------------------------------------------*/
196         /* 1. If full restart, get semaphore and set initial ROSCs      */
197         /*--------------------------------------------------------------*/
198         if (isRestart) {
199                 /* set ROSC to 1 (fastest)  */
200                 *roscsToStart_ptr = 1UL;
201 
202                 /* init rndState flags to zero */
203                 rndState_ptr->TrngProcesState = 0;
204         }
205 
206 
207         if (*roscsToStart_ptr == 0)
208                 return LLF_RND_TRNG_REQUIRED_ROSCS_NOT_ALLOWED_ERROR;
209 
210         /* FE mode  */
211         /* Get fastest allowed ROSC */
212         error = LLF_RND_GetFastestRosc(
213                 trngParams_ptr,
214                 roscsToStart_ptr     /*in/out*/);
215         if (error)
216                 return error;
217 
218         error = LLF_RND_GetRoscSampleCnt(*roscsToStart_ptr, trngParams_ptr);
219         if (error)
220                 return error;
221 
222         roscNum = LLF_RND_TRNG_RoscMaskToNum(*roscsToStart_ptr);
223 
224         /*--------------------------------------------------------------*/
225         /* 2. Restart the TRNG and set parameters                   */
226         /*--------------------------------------------------------------*/
227         /* RNG Block HW Specification (10 Programming Reference)        */
228 
229         /* enable the HW RND clock   */
230         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_CLK_ENABLE), LLF_RND_HW_RND_CLK_ENABLE_VAL);
231 
232         /* do software reset */
233         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_SW_RESET), 0x1);
234         /* in order to verify that the reset has completed the sample count need to be verified */
235         do {
236                 /* enable the HW RND clock   */
237                 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_CLK_ENABLE), LLF_RND_HW_RND_CLK_ENABLE_VAL);
238 
239                 /* set sampling ratio (rng_clocks) between consecutive bits */
240                 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, SAMPLE_CNT1), trngParams_ptr->SubSamplingRatio);
241 
242                 /* read the sampling ratio  */
243                 tmpSamplCnt = CC_HAL_READ_REGISTER(CC_REG_OFFSET(RNG, SAMPLE_CNT1));
244 
245         } while (tmpSamplCnt != trngParams_ptr->SubSamplingRatio);
246 
247 
248         /* disable the RND source for setting new parameters in HW */
249         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RND_SOURCE_ENABLE), LLF_RND_HW_RND_SRC_DISABLE_VAL);
250 
251         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_ICR), 0xFFFFFFFF);
252 
253         /* set interrupt mask */
254         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_IMR), LLF_RNG_INT_MASK_ON_FETRNG_MODE);
255 
256         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, TRNG_CONFIG), roscNum);
257 
258 #ifdef CC_IOT
259         /* mask RNG_INT - this interrupt should be polled upon,
260          * and not handled by the operating system's interrupt handler. */
261         mask = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
262         CC_REG_FLD_SET(HOST_RGF, HOST_IMR, RNG_INT_MASK, mask, 1);
263         CC_HalMaskInterrupt(mask);
264 #endif
265         /* Debug Control register: set to 0 - no bypasses */
266         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, TRNG_DEBUG_CONTROL), LLF_RND_HW_DEBUG_CONTROL_VALUE_ON_FE_MODE);
267 
268         LLF_RND_TRNG_EnableRngSourceAndWatchdog(trngParams_ptr);
269 
270         /* set indication about current started ROSCs:  */
271         /*new started*/
272         rndState_ptr->TrngProcesState = (rndState_ptr->TrngProcesState & 0x00ffffff) | (*roscsToStart_ptr << 24);
273         /*total started*/
274         rndState_ptr->TrngProcesState |= (*roscsToStart_ptr << 8);
275 
276         return error;
277 }
278 
279 
LLF_RND_GetTrngSource(CCRndState_t * rndState_ptr,CCRndParams_t * trngParams_ptr,CCBool_t isContinued,uint32_t * entropySize_ptr,uint32_t ** sourceOut_ptr_ptr,uint32_t * sourceOutSize_ptr,uint32_t * rndWorkBuff_ptr,bool isFipsSupported)280 CCError_t LLF_RND_GetTrngSource(
281         CCRndState_t  *rndState_ptr,        /*in/out*/
282         CCRndParams_t  *trngParams_ptr,     /*in/out*/
283         CCBool_t            isContinued,    /*in*/
284         uint32_t         *entropySize_ptr,      /*in/out*/
285         uint32_t        **sourceOut_ptr_ptr,    /*out*/
286         uint32_t         *sourceOutSize_ptr,    /*in/out*/
287         uint32_t         *rndWorkBuff_ptr,      /*in*/
288         bool              isFipsSupported)      /*in*/
289 {
290         /* LOCAL DECLARATIONS */
291 
292         /* The return error identifier */
293         CCError_t error = 0;
294         int32_t  i;
295 #ifndef USE_MBEDTLS_CRYPTOCELL
296         uint32_t tmp;
297 #endif
298         uint32_t roscToStart;
299         uint32_t *ramAddr;
300         uint32_t trngBuff[LLF_RND_HW_DMA_EHR_SAMPLES_NUM_ON_FE_MODE * LLF_RND_HW_TRNG_EHR_WIDTH_IN_WORDS] = { 0 }; /* 2 EHR required */
301         CC_UNUSED_PARAM(entropySize_ptr);
302 
303         /* Lock mutex, check fatal err, and increase cc counter*/
304         MUTEX_LOCK_AND_RETURN_UPON_ERROR(pCCRndCryptoMutex);
305 
306         CC_IS_FATAL_ERR_ON(error);
307         if (error == CC_TRUE) {
308                 error = LLF_RND_TRNG_GENERATION_NOT_COMPLETED_ERROR;
309                 goto EndUnlockMutex;
310         }
311 
312         INCREASE_CC_COUNTER
313         /* FUNCTION LOGIC */
314 
315         /* ............... local initializations .............................. */
316         /* -------------------------------------------------------------------- */
317 
318         /* initializing the Error to O.K */
319         error = CC_OK;
320 
321         /* Set source RAM address with offset 8 bytes from sourceOut address in
322           order to remain empty bytes for CC operations */
323         *sourceOut_ptr_ptr = rndWorkBuff_ptr;
324         ramAddr = *sourceOut_ptr_ptr + CC_RND_TRNG_SRC_INNER_OFFSET_WORDS;
325         /* init to 0 for FE mode */
326         *sourceOutSize_ptr = 0;
327 #ifndef USE_MBEDTLS_CRYPTOCELL
328         /* Case of RND KAT or TRNG KAT testing  */
329         if ((rndState_ptr->StateFlag & CC_RND_KAT_DRBG_Mode) ||
330                 (rndState_ptr->StateFlag & CC_RND_KAT_TRNG_Mode)) {
331                 /* set source sizes given by the user in KAT test and placed
332                    in the rndWorkBuff with offset CC_RND_SRC_BUFF_OFFSET_WORDS */
333                 *sourceOutSize_ptr = (*sourceOut_ptr_ptr)[0];
334                 if (*sourceOutSize_ptr == 0) {
335                         error = CC_RND_KAT_DATA_PARAMS_ERROR;
336                         goto End;
337                 }
338 
339                 /* Go to Estimator */
340                 if (rndState_ptr->StateFlag & CC_RND_KAT_TRNG_Mode) {
341                         /* Assumed, that KAT data is set in the rnd Work      *
342                            buffer as follows:                     *
343                            - full source size set in buffer[0],           *
344                            - count blocks set in buffer[1],               *
345                            *  - KAT source begins from buffer[2].         */
346                         tmp = (*sourceOut_ptr_ptr)[1]; /*count blocks for estimation*/
347                         if (tmp == 0) {
348                                 error = CC_RND_KAT_DATA_PARAMS_ERROR;
349                                 goto End;
350                         }
351                         error = CC_RND_TRNG_KAT_NOT_SUPPORTED_ERROR;
352                         goto End;
353                         //goto Estimator;
354                 }
355                 else {
356                         goto End;
357                 }
358         }
359 #endif
360         /* If not continued mode, set TRNG parameters and restart TRNG  */
361         /*--------------------------------------------------------------*/
362         if (isContinued == CC_FALSE) {
363 #ifndef USE_MBEDTLS_CRYPTOCELL
364                 /* Set instantiation, TRNG errors and time   *
365                 * exceeding bits of State to 0           */
366                 rndState_ptr->StateFlag &= ~(CC_RND_INSTANTIATED |
367                         CC_RND_INSTANTRESEED_AUTOCORR_ERRORS |
368                         CC_RND_INSTANTRESEED_TIME_EXCEED |
369                         CC_RND_INSTANTRESEED_LESS_ENTROPY);
370 #endif
371                 /* Full restart TRNG */
372                 error = LLF_RND_StartTrngHW(
373                         rndState_ptr,
374                         trngParams_ptr,
375                         CC_TRUE/*isRestart*/,
376                         &roscToStart);
377 
378                 /*Note: in case of error the TRNG HW is still not started*/
379                 if (error) {
380                         goto End;
381                 }
382         }
383         /* On continued mode check HW TRNG */
384         else {
385                 /* check TRNG parameters */
386                 error = LLF_RND_TRNG_CheckHwParams(trngParams_ptr);
387                 if (error != CC_OK)
388                         goto End;
389 
390                 /* previously started ROSCs */
391                 roscToStart = (rndState_ptr->TrngProcesState & 0xff000000) >> 24;
392         }
393 
394         /*====================================================*/
395         /*====================================================*/
396         /*         Processing after previous start            */
397         /*====================================================*/
398         /*====================================================*/
399 
400         /*====================================================*/
401         /* FE mode processing: start Roscs sequentially -   *
402         * from fast to slow Rosc                  */
403         /*====================================================*/
404 
405         for (i = 0; i < LLF_RND_NUM_OF_ROSCS; ++i) {
406 
407                 /* read the first EHR */
408                 error = LLF_RND_TRNG_ReadEhrData(trngBuff, isFipsSupported);
409                 if (error == CC_OK) {
410                         /* read the second EHR */
411                         LLF_RND_TRNG_EnableRngSourceAndWatchdog(trngParams_ptr);
412                         error = LLF_RND_TRNG_ReadEhrData(trngBuff + LLF_RND_HW_TRNG_EHR_WIDTH_IN_WORDS, isFipsSupported);
413                         if (error == CC_OK) {
414                                 break;
415                         }
416                 }
417                 if (error == LLF_RND_CRNGT_TEST_FAIL_ERROR) {
418                         /* LLF_RND_CRNGT_TEST_FAIL_ERROR is set only in FIPS mode. do not continue to the next rosc. */
419                         break;
420                 }
421                 if (error != CC_OK) {/* try next rosc */
422                         /*  if no remain roscs to start, return error */
423                         if (roscToStart == 0x8) {
424                                 error = LLF_RND_TRNG_GENERATION_NOT_COMPLETED_ERROR;
425                                 break;
426                         }
427                         else {
428                                 /* Call StartTrng, with next ROSC */
429                                 roscToStart <<= 1;
430                                 error = LLF_RND_StartTrngHW(
431                                         rndState_ptr,
432                                         trngParams_ptr,
433                                         CC_FALSE/*isRestart*/,
434                                         &roscToStart);
435 
436                                 /* if no remain valid roscs, return error */
437                                 if (error == LLF_RND_TRNG_REQUIRED_ROSCS_NOT_ALLOWED_ERROR && (trngParams_ptr->RoscsAllowed != 0)) {
438 
439                                         error = LLF_RND_TRNG_GENERATION_NOT_COMPLETED_ERROR;
440                                 }
441 
442                                 if (error != CC_OK) {
443                                         goto End;
444                                 }
445                         }
446                 }
447 
448 
449                 /* update total processed ROSCs */
450                 rndState_ptr->TrngProcesState |= ((rndState_ptr->TrngProcesState >> 8) & 0x00FF0000);
451                 /*clean started & not processed*/
452                 rndState_ptr->TrngProcesState &= 0x00FFFFFF;
453 
454         }
455 
456         if (error == CC_OK) {
457                 CC_PalMemCopy(ramAddr, trngBuff, LLF_RND_HW_DMA_EHR_SAMPLES_NUM_ON_FE_MODE * LLF_RND_HW_TRNG_EHR_WIDTH_IN_BYTES);
458                 *sourceOutSize_ptr = LLF_RND_HW_DMA_EHR_SAMPLES_NUM_ON_FE_MODE * LLF_RND_HW_TRNG_EHR_WIDTH_IN_BYTES;
459         }
460 
461         /* end FE mode */
462 
463         /* ................. end of function ..................................... */
464         /* ----------------------------------------------------------------------- */
465 End:
466 
467         /* turn the RNG off    */
468 #ifndef USE_MBEDTLS_CRYPTOCELL
469 
470         if ((rndState_ptr->StateFlag & CC_RND_KAT_TRNG_Mode) == 0) {
471                 LLF_RND_TurnOffTrng();
472         }
473 #else
474         LLF_RND_TurnOffTrng();
475 
476 #endif
477 
478         /* release mutex and decrease CC counter */
479         DECREASE_CC_COUNTER
480 
481 EndUnlockMutex:
482         MUTEX_UNLOCK(pCCRndCryptoMutex);
483 
484 
485         return error;
486 
487 
488 }/* END of LLF_RND_GetTrngSource */
489 
LLF_RND_RunTrngStartupTest(CCRndState_t * rndState_ptr,CCRndParams_t * trngParams_ptr,uint32_t * rndWorkBuff_ptr)490 CCError_t LLF_RND_RunTrngStartupTest(
491         CCRndState_t        *rndState_ptr,
492         CCRndParams_t       *trngParams_ptr,
493         uint32_t                *rndWorkBuff_ptr)
494 {
495     CCError_t error = CC_OK;
496     CC_UNUSED_PARAM(rndState_ptr);
497         CC_UNUSED_PARAM(trngParams_ptr);
498         CC_UNUSED_PARAM(rndWorkBuff_ptr);
499 
500     return error;
501 }
502 
503 
504 
505