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