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
9 #include "dx_rng.h"
10 #include "cc_pal_mem.h"
11 #include "cc_pal_types.h"
12 #include "cc_rng_plat.h"
13 #include "dx_crys_kernel.h"
14 #include "cc_hal.h"
15 #include "cc_regs.h"
16 #include "dx_host.h"
17 #include "cc_rnd_local.h"
18 #include "cc_rnd_error.h"
19 #include "llf_rnd_hwdefs.h"
20 #include "llf_rnd.h"
21 #include "llf_rnd_error.h"
22 #include "cc_sram_map.h"
23 #include "cc_address_defs.h"
24 #include "llf_rnd_trng.h"
25 #include "cc_aes_defs.h"
26
27
28 /********************************* Defines ******************************/
29 #ifndef max
30 #define max(a,b) (a) > (b) ? (a) : (b)
31 #endif
32
33 /* definitions used in the Entropy Estimator functions */
34 #define S(a,n) ((uint32_t)((a) * (1<<(n)))) /* a scaled by n: a \times 2^n */
35 #define U(a,n) ((uint32_t)(a) >> (n)) /* unscale unsigned: a / 2^n */
36 #define SQR(x) (((x)&0xffff)*((x)&0xffff))
37
38 /* macros for updating histogram for any separate bit;
39 where x represents cw or e1 */
40 #define LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, x ) \
41 h_ptr[x & 0xff]++; \
42 ec_ptr[x & 0x7f] = ((ec_ptr[x & 0x7f] & 1) == ((x & 0xff) >> 7)) ? ec_ptr[x & 0x7f] + 2 : ec_ptr[x & 0x7f] ^ 1; \
43 x >>= 1;
44
45 /* Entropy estimation histogram width (prefix size + 1) */
46 #define LLF_RND_nb CC_RND_nb
47 #define LLF_RND_NB CC_RND_NB
48 #define halfNB (LLF_RND_NB / 2)
49 #define ROSC_INIT_START_BIT 0x80000000
50
51
52 /*********************************** Enums ******************************/
53 /*********************************Typedefs ******************************/
54
55 /**************** Global Data to be read by RNG function ****************/
56
57
58 /* test variables */
59 #ifdef RND_TEST_TRNG_WITH_ESTIMATOR
60 uint32_t gEntrSize[4];
61 #endif
62
63
64 /******************************************************************************/
65 /*************** Prototypes and Private functions ************************/
66 /******************************************************************************/
67 /****************************************************************************/
68 /*********** Functions used for Entropy estimation *************/
69 /****************************************************************************/
70 /**
71 * The function calculates low half of 32*32 bits multiplication result
72 *
73 * @param a
74 * @param b
75 *
76 * @return uint64_t
77 */
Mult32x32(uint32_t a,uint32_t b)78 uint64_t Mult32x32(uint32_t a, uint32_t b)
79 {
80 uint64_t res=0;
81
82 res = (((a>>16)*(b>>16)) + (((a>>16)*(b&0xffff))>>16) + (((b>>16)*(a&0xffff))>>16));
83 res <<= 32;
84 res += (uint64_t)((a&0xffff)*(b&0xffff)) + (((a>>16)*(b&0xffff))<<16) + (((b>>16)*(a&0xffff))<<16);
85
86 return res;
87 }
88
89 /* Calculate 48*16 bits multiple using 16*16 bit multiplier */
90 /* Code ASM takes 62 bytes */
Mult48x16(uint64_t a,uint32_t b)91 uint64_t Mult48x16(uint64_t a, uint32_t b)
92 {
93 uint32_t a3 = (a >> 32), a2 = (a >> 16) & 0xffff, a1 = a & 0xffff;
94 uint32_t b1 = (b & 0xffff);
95 uint32_t r31 = a3*b1, r21 = a2*b1, r11 = a1*b1;
96 return(((uint64_t)r31) << 32) +
97 (((uint64_t)r21) << 16) +
98 ((uint64_t)r11);
99 }
100
101
102 /* approximation of entropy */
103 /**
104 * @brief The function approximates the entropy for separate prefix
105 * ae = n * log2(n/m).
106 *
107 * Implementation according A.Klimov algorithm uses approximation by
108 * polynomial: ae = (n-m)*(A1 + A2*x + A3*x^2), where x = (n-m)/n <= 0.5 .
109 * The coefficients are defined above in this file.
110 *
111 * @param[in] n - The summ of 0-bits and 1-bits in the test.
112 * @param[in] m - The maximal from the two above named counts.
113 *
114 * @return - result value of entropy ae.
115 */
ae(uint32_t n,uint32_t m)116 static uint32_t ae(uint32_t n, uint32_t m)
117 {
118 /* logarithm calculation constants */
119 #define A1 1.4471280
120 #define A2 0.6073851
121 #define A3 0.9790318
122
123
124 uint32_t d = n-m,
125 x = S(d,16) / n, /* x; 16 */
126 a = S(A3,14) * x, /* x*A3; 30 */
127 b = U(S(A2,30) + a, 16) * x, /* x*(A2 + x*A3); 30 */
128 c = (S(A1,30) + b), /* (A1 + x*(A2 + x*A3)); 30 */
129 r = d * U(c,14); /* result: 16 bits scaled */
130
131 return r;
132
133 }
134
135 /*****************************************************************************/
136 /**
137 * @brief The function calculates a histogram of 0-s and 1-s distribution
138 * depending on forgouing bits combination - prefix.
139 *
140 * Implementation according A.Klimov algorithm modified by A.Ziv
141 *
142 * @param[in] h_ptr - The pointer to the histogramm h buffer.
143 * @param[in] ec_ptr - The pointer to the histogramm equality counter (ec) buffer.
144 * @param[in] r_ptr - The pointer to Entropy source.
145 * @param[in] nr - The size of Entropy source in words.
146 * @param[in/out] pref_ptr - The pointer to last saved prefix.
147 * @param[in] snp_ptr - The pointer to the flag defining whether the new prefix should be set.
148 *
149 * @return CCError_t - no return value
150 */
LLF_RND_HistogramUpdate(uint32_t * h_ptr,uint32_t * ec_ptr,uint32_t * r_ptr,uint32_t nr)151 static void LLF_RND_HistogramUpdate(
152 uint32_t *h_ptr, /* in/out */
153 uint32_t *ec_ptr, /* in/out */
154 uint32_t *r_ptr, /* in - input sequence */
155 uint32_t nr) /* in - input sequence size in words */
156 {
157 int32_t i;
158 uint32_t j = 0;
159 uint32_t cW; /*current word of sequence*/
160 uint32_t pref;
161
162 /* FUNCTION LOGIC */
163
164 /*------------------------------------------------------*/
165 /* update for first word of sequence: begin new prefix */
166 /*------------------------------------------------------*/
167 cW = r_ptr[0];
168 /* 25 sequences are purely from new bits */
169 for (i = 0; i < 5; i++) {
170 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
171 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
172 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
173 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
174 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
175 }
176
177 pref = cW;
178 j = 1;
179
180 /*-----------------------------------------------------------------------*/
181 /* update for remaining words of sequence: continue with previous prefix */
182 /*-----------------------------------------------------------------------*/
183 for (; j < nr; j++) {
184 uint32_t e1;
185
186 /*current word of random sequence*/
187 cW = r_ptr[j];
188 /* concatenation of previous saved prefix and new bits */
189 e1 = (cW << 7) | pref;
190
191 /* first 7 sequences are combined from previous prefix and new bits */
192 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, e1 );
193 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, e1 );
194 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, e1 );
195 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, e1 );
196 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, e1 );
197 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, e1 );
198 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, e1 );
199
200 /* next 25 sequences are purely from new bits */
201 for (i = 0; i < 5; i++) {
202 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
203 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
204 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
205 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
206 LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
207 }
208
209 pref = cW;
210 }
211
212 } /* End of LLF_RND_HistogramUpdate() */
213
214
215 /*****************************************************************************/
216 /**
217 * @brief The function calculates estimation of entropy, generated by TRNG and
218 * used for control the TRNG work.
219 *
220 * Implementation based on algorithm developed by A.Klimov.
221 *
222 * @param[in] h - The pointer to the h-buffer (counts of 0-s and 1-s for each prefix).
223 * @param[in] ec - The pointer to the ec-buffer (equality counters).
224 * @param[out] e_ptr - The pointer to count of accumulated Entropy (bits multiplied by 2^16).
225 *
226 * @return CCError_t - according to module definitions
227 */
LLF_RND_EntropyEstimate(uint32_t * h,uint32_t * ec,uint32_t * e_ptr)228 static CCError_t LLF_RND_EntropyEstimate(
229 uint32_t *h, /*in/out*/
230 uint32_t *ec,
231 uint32_t *e_ptr ) /* out - result Entropy size */
232 {
233
234 uint64_t t = 0; /* total entropy */
235 uint32_t i, ac = 0; /* number of active prefixes */
236
237
238 /*------------- calculate entropy -----------------*/
239
240 for (i = 0; i < halfNB; ++i) {
241
242 uint32_t n = h[i] + h[i+halfNB], m = max(h[i], h[i+halfNB]);
243
244 /* check that n < 2^16, else return overflow error */
245 if (n >= (1UL<<16))
246 return LLF_RND_TRNG_ENTR_ESTIM_SIZE_EXCEED_ERROR;
247
248 if (n != m) { /* if active prefix */
249 uint32_t n2, pp, od;
250 uint64_t od2, od2n, var;
251
252 /* increment count of active prefixes */
253 ++ac;
254
255 pp = SQR(m) + SQR(n-m); /* related to theoretical "autocorrelation" probability */
256 n2 = Mult16x16((ec[i]>>1),n); /* n2 used as temp */
257
258 /* value, related to observed deviation of autocorrelation */
259 if (n2 > pp)
260 od = n2 - pp;
261 else
262 od = pp - n2;
263
264 /* theoretical variance of B(n, pp): always > 0 */
265 n2 = SQR(n);
266 var = Mult32x32(pp,(n2-pp));
267
268 /* if n*od^2 < var then accumulate entropy, else return Error;
269 Note: that this condition is True only if od < 2^32 */
270 if (od != CC_MAX_UINT32_VAL) {
271 od2 = Mult32x32(od, od);
272
273 /* scale variables */
274 if (od2 > ((uint64_t)1ULL << 48)) {
275 od2 /= (1UL<<16);
276 var /= (1UL<<16);
277 }
278
279 od2n = Mult48x16(od2, n);
280
281 if (od2n < var)
282 t += ae(n, m);
283 }
284 }
285 }
286
287 /* output entropy size value in bits (rescaled) */
288
289 *e_ptr = ac > 3 ? (t / (1UL << 16)) : 0;
290
291 return CC_OK;
292
293 } /* End of LLF_RND_EntropyEstimate */
294
295 /*****************************************************************************/
296 /**
297 * @brief The function calculates estimation of entropy, generated by 4 ROSCs
298 *
299 * @param[in] ramAddr - The pointer to random source.
300 * @param[in] blockSizeWords - The size of each block of random source in words.
301 * @param[in] countBlocks - The blocks count (according to given ROSCS).
302 * @param[in] h_ptr - The pointer to the h-buffer (counts of 0-s and 1-s for each prefix).
303 * @param[in] ec_ptr - The pointer to the ec-buffer (equality counters).
304 * @param[out] entrSize_ptr - The pointer to count of accumulated Entropy in bits.
305 * @param[in] rndContext_ptr - The pointer to random State.
306 *
307 * @return CCError_t - according to module definitions
308 */
LLF_RND_EntropyEstimateFull(uint32_t * ramAddr,uint32_t blockSizeWords,uint32_t countBlocks,uint32_t * entrSize_ptr,uint32_t * rndWorkBuff_ptr)309 CCError_t LLF_RND_EntropyEstimateFull(
310 uint32_t *ramAddr, /*in*/
311 uint32_t blockSizeWords, /*in*/
312 uint32_t countBlocks, /*in*/
313 uint32_t *entrSize_ptr, /*out*/
314 uint32_t *rndWorkBuff_ptr) /*in*/
315 {
316
317 CCError_t error = 0;
318 uint32_t i, totalEntr = 0, currEntr;
319 uint32_t *h_ptr, *ec_ptr;
320 uint32_t *eachRoscEntr_ptr = rndWorkBuff_ptr + CC_RND_WORK_BUFF_TMP2_OFFSET;
321
322
323 /* Initialization */
324
325 h_ptr = rndWorkBuff_ptr + CC_RND_H_BUFF_OFFSET;
326 ec_ptr = rndWorkBuff_ptr + CC_RND_EC_BUFF_OFFSET;
327
328 /* estimate entropy for given blocks (ROSCs) */
329 for (i = 0; i < countBlocks; i++) {
330
331 /* Zeroe working buffer for entr. estimator */
332 CC_PalMemSetZero(h_ptr, H_BUFF_SIZE_WORDS*4);
333 CC_PalMemSetZero(ec_ptr, EC_BUFF_SIZE_WORDS*4);
334
335 LLF_RND_HistogramUpdate(
336 h_ptr, ec_ptr,
337 ramAddr + i*blockSizeWords,
338 blockSizeWords);
339
340 error = LLF_RND_EntropyEstimate(
341 h_ptr, ec_ptr,
342 &currEntr); /* out - result Entropy size */
343
344 if (error)
345 goto End;
346
347 /*total entropy and separate ROSCs entropy*/
348 totalEntr += currEntr;
349 eachRoscEntr_ptr[i] = currEntr;
350 }
351
352 /* entropy correction: down ~1.5% */
353 totalEntr -= totalEntr >> 6;
354
355 *entrSize_ptr = totalEntr;
356
357 End:
358 return error;
359 }
360
361 /****************************************************************************************/
362 /*********************** Auxiliary Functions **************************/
363 /****************************************************************************************/
364
365
366 /************************************************************************************/
367 /*!
368 * Busy wait upon RNG Interrupt signals.
369 *
370 * This function waits RNG interrupt and then disables RNG source.
371 * It uses CC_HalWaitInterrupt function
372 * to receive common RNG interrupt and then reads and
373 * outputs the RNG ISR (status) register.
374 *
375 *
376 * \return uint32_t RNG Interrupt status.
377 */
LLF_RND_WaitRngInterrupt(uint32_t * isr_ptr)378 CCError_t LLF_RND_WaitRngInterrupt(uint32_t *isr_ptr)
379 {
380 uint32_t tmp = 0;
381 CCError_t error = CC_OK;
382 /* busy wait upon RNG IRR signals */
383 CC_REG_FLD_SET(HOST_RGF, HOST_IRR, RNG_INT, tmp, 1);
384 /* wait for watermark signal */
385 error = CC_HalWaitInterruptRND(tmp);
386 if (error != CC_OK){
387 /* stop DMA and the RNG source */
388 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG,RNG_DMA_ENABLE), 0);
389 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RND_SOURCE_ENABLE), 0);
390 return error;
391 }
392 /* stop DMA and the RNG source */
393 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG,RNG_DMA_ENABLE), 0);
394 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RND_SOURCE_ENABLE), 0);
395
396 /* read specific RNG interrupt status */
397 *isr_ptr = CC_HAL_READ_REGISTER(CC_REG_OFFSET(RNG, RNG_ISR));
398
399 /* clear RNG interrupt status besides HW errors */
400 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_ICR), *isr_ptr);
401 /* clear again HOST_IRR, since it must be cleared after RNG_ISR */
402 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ICR), tmp);
403 return error;
404 }
405
406 /*****************************************************************/
407
LLF_RND_GetRoscSampleCnt(uint32_t rosc,CCRndParams_t * pTrngParams)408 CCError_t LLF_RND_GetRoscSampleCnt(uint32_t rosc, CCRndParams_t *pTrngParams)
409 {
410 switch (rosc) {
411 case 0x1:
412 pTrngParams->SubSamplingRatio = pTrngParams->userParams.SubSamplingRatio1;
413 break;
414 case 0x2:
415 pTrngParams->SubSamplingRatio = pTrngParams->userParams.SubSamplingRatio2;
416 break;
417 case 0x4:
418 pTrngParams->SubSamplingRatio = pTrngParams->userParams.SubSamplingRatio3;
419 break;
420 case 0x8:
421 pTrngParams->SubSamplingRatio = pTrngParams->userParams.SubSamplingRatio4;
422 break;
423 default:
424 return LLF_RND_TRNG_REQUIRED_ROSCS_NOT_ALLOWED_ERROR;
425 }
426
427 return CC_OK;
428 }
429
430 /**
431 * The function gets next allowed rosc
432 *
433 * @author reuvenl (9/12/2012)
434 *
435 * @param trngParams_ptr - a pointer to params structure.
436 * @param rosc_ptr - a pointer to previous rosc /in/, and
437 * to next rosc /out/.
438 * @param isNext - defines is increment of rosc ID needed or not.
439 * if isNext = TRUE - the function shifts rosc by one bit; Then
440 * the function checks is this rosc allowed, if yes - updates
441 * the rosc, else repeats previous steps. If no roscs allowed -
442 * returns an error.
443 *
444 *
445 * @return CCError_t
446 */
LLF_RND_GetFastestRosc(CCRndParams_t * trngParams_ptr,uint32_t * rosc_ptr)447 CCError_t LLF_RND_GetFastestRosc(
448 CCRndParams_t *trngParams_ptr,
449 uint32_t *rosc_ptr /*in/out*/)
450 {
451 /* setting rosc */
452 do {
453
454 if (*rosc_ptr & trngParams_ptr->RoscsAllowed) {
455 return CC_OK;
456 } else {
457 *rosc_ptr <<= 1;
458 }
459
460 }while (*rosc_ptr <= 0x08);
461
462 return LLF_RND_TRNG_REQUIRED_ROSCS_NOT_ALLOWED_ERROR;
463
464 }
465
466
467 /**
468 * The macros calculates count ROSCs to start, as count of bits "1" in allowed
469 * roscToStart parameter.
470 *
471 * @author reuvenl (9/20/2012)
472 *
473 * @param roscsAllowed
474 * @param roscToStart
475 *
476 * @return uint32_t
477 */
LLF_RND_GetCountRoscs(uint32_t roscsAllowed,uint32_t roscToStart)478 uint32_t LLF_RND_GetCountRoscs(
479 uint32_t roscsAllowed,
480 uint32_t roscToStart)
481 {
482 uint32_t countRoscs = 0;
483
484 roscToStart &= roscsAllowed;
485 while (roscToStart) {
486 countRoscs += (roscToStart & 1UL);
487 roscToStart >>= 1;
488 }
489
490 return countRoscs;
491 }
492
493 /****************************************************************************************/
494 /***************************** Public Functions ******************************/
495 /****************************************************************************************/
496
497
498 /************************************************************************************/
499 /**
500 * @brief The LLF_RND_TurnOffTrng stops the hardware random bits collection
501 * closes RND clocks and releases HW semaphore.
502 *
503 *
504 *
505 * @return CCError_t - On success CC_OK is returned, on failure a
506 * value MODULE_* as defined in ...
507 */
LLF_RND_TurnOffTrng(void)508 void LLF_RND_TurnOffTrng(void)
509 {
510 /* LOCAL DECLARATIONS */
511
512 uint32_t temp = 0;
513
514
515 /* FUNCTION LOGIC */
516
517 /* disable the RND source */
518 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG,RND_SOURCE_ENABLE), LLF_RND_HW_RND_SRC_DISABLE_VAL);
519
520 /* close the Hardware clock */
521 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG,RNG_CLK_ENABLE), LLF_RND_HW_RND_CLK_DISABLE_VAL);
522
523 /* clear RNG interrupts */
524 CC_REG_FLD_SET(HOST_RGF, HOST_ICR, RNG_INT_CLEAR, temp, 1); \
525 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ICR), temp);
526 CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG,RNG_ICR), 0xFFFFFFFF);
527
528
529 return;
530
531 }/* END OF LLF_RND_TurnOffTrng*/
532
533
534 /**
535 * @brief: The function performs CPRNGT (Continued PRNG Test) according
536 * to NIST 900-80 and FIPS (if defined) standards.
537 *
538 * @param[in] prev_ptr - The pointer to previous saved generated random
539 * value of size 16 bytes.
540 * @param[in] buff_ptr - The pointer to generated random buffer.
541 * @param[in] last_ptr - The pointer to last generated random block
542 * of size 16 bytes used for output last bytes.
543 * @param[in] countBlocks - The count of generated random blocks, including
544 * the last block. Assumed countBlocks > 0.
545 *
546 * @return CCError_t - On success CC_OK is returned, on failure a
547 * value MODULE_* as defined in cc_error.h
548 */
LLF_RND_RndCprngt(uint8_t * prev_ptr,uint8_t * buff_ptr,uint8_t * last_ptr,int32_t countBlocks)549 CCError_t LLF_RND_RndCprngt(uint8_t *prev_ptr, /*in*/
550 uint8_t *buff_ptr, /*in*/
551 uint8_t *last_ptr, /*in*/
552 int32_t countBlocks) /*in*/
553 {
554 /* LOCAL DECLARATIONS */
555
556 CCError_t error = CC_OK;
557 int32_t i;
558
559 /* FUNCTION LOGIC */
560
561 /* compare the previous Value and last block */
562 if (countBlocks == 1) {
563 if (CC_PalMemCmp(prev_ptr, /*prev*/
564 last_ptr,/*last block*/
565 CC_AES_BLOCK_SIZE_IN_BYTES) == 0) {
566 error = CC_RND_CPRNG_TEST_FAIL_ERROR;
567 goto End;
568 }
569 } else { /* countBlocks > 1, compare first and last blocks */
570 if (CC_PalMemCmp(prev_ptr, /*prev*/
571 buff_ptr, /*first block*/
572 CC_AES_BLOCK_SIZE_IN_BYTES) == 0) {
573 error = CC_RND_CPRNG_TEST_FAIL_ERROR;
574 goto End;
575 }
576
577 if (CC_PalMemCmp(buff_ptr + (countBlocks-2)*CC_AES_BLOCK_SIZE_IN_BYTES, /*prev*/
578 last_ptr,/*last block*/
579 CC_AES_BLOCK_SIZE_IN_BYTES) == 0) {
580 error = CC_RND_CPRNG_TEST_FAIL_ERROR;
581 goto End;
582 }
583 }
584 /* compare intermediate blocks */
585 if (countBlocks > 2 && error == CC_OK) {
586 for (i = 0; i < countBlocks-2; i++) {
587 /* compare all current with previous blocks */
588 if (CC_PalMemCmp(buff_ptr + i*CC_AES_BLOCK_SIZE_IN_BYTES,
589 buff_ptr + (i+1)*CC_AES_BLOCK_SIZE_IN_BYTES,
590 CC_AES_BLOCK_SIZE_IN_BYTES) == 0) {
591 error = CC_RND_CPRNG_TEST_FAIL_ERROR;
592 goto End;
593 }
594 }
595 }
596
597 End:
598
599
600 return error;
601 }
602
603
604