4343 */
4444static cracen_prng_context_t prng ;
4545
46- NRF_SECURITY_MUTEX_DEFINE (cracen_prng_context_mutex );
46+ /* This mutex protects access to the TRNG and to the PRNG context as well. */
47+ NRF_SECURITY_MUTEX_DEFINE (cracen_prng_trng_mutex );
4748
4849/*
4950 * @brief Internal function to enable TRNG and get entropy for initial seed and
5051 * reseed
5152 *
5253 * @return 0 on success, nonzero on failure.
5354 */
54- static int trng_get_seed (char * dst , int num_trng_bytes )
55+ static int trng_get_entropy (char * dst , int num_trng_bytes )
5556{
56- int sx_err = SX_ERR_RESET_NEEDED ;
57+ int sx_err ;
5758 struct sx_trng trng ;
58-
59- while (true) {
60- switch (sx_err ) {
61- case SX_ERR_RESET_NEEDED :
62- sx_err = sx_trng_open (& trng , NULL );
63- if (sx_err != SX_OK ) {
64- return sx_err ;
65- }
66- /* fallthrough */
67- case SX_ERR_HW_PROCESSING :
68- /* Generate random numbers */
69- sx_err = sx_trng_get (& trng , dst , num_trng_bytes );
70- if (sx_err == SX_ERR_RESET_NEEDED ) {
71- (void )sx_trng_close (& trng );
59+ int trng_chunk_size ;
60+ bool loop_continue ;
61+
62+ while (num_trng_bytes ) {
63+ /* The sx_trng_get function suggests to return <= 32 bytes at a time */
64+ trng_chunk_size = MIN (num_trng_bytes , 32 );
65+
66+ sx_err = SX_ERR_RESET_NEEDED ;
67+ loop_continue = true;
68+ while (loop_continue ) {
69+ switch (sx_err ) {
70+ case SX_ERR_RESET_NEEDED :
71+ sx_err = sx_trng_open (& trng , NULL );
72+ if (sx_err != SX_OK ) {
73+ return sx_err ;
74+ }
75+ /* fallthrough */
76+ case SX_ERR_HW_PROCESSING :
77+ /* Generate random numbers */
78+ sx_err = sx_trng_get (& trng , dst , trng_chunk_size );
79+ if (sx_err == SX_ERR_RESET_NEEDED ) {
80+ (void )sx_trng_close (& trng );
81+ }
82+ break ;
83+ default :
84+ /* Exit the loop, either there is SX_OK or an error that cannot get
85+ * hanlded here.
86+ */
87+ loop_continue = false;
88+ break ;
7289 }
73- break ;
74- default :
75- (void )sx_trng_close (& trng );
90+ }
91+
92+ (void )sx_trng_close (& trng );
93+ if (sx_err != SX_OK ) {
7694 return sx_err ;
7795 }
96+
97+ num_trng_bytes -= trng_chunk_size ;
98+ dst += trng_chunk_size ;
7899 }
100+
101+ return SX_OK ;
79102}
80103
81104/**
@@ -134,11 +157,11 @@ psa_status_t cracen_init_random(cracen_prng_context_t *context)
134157 return PSA_SUCCESS ;
135158 }
136159
137- nrf_security_mutex_lock (cracen_prng_context_mutex );
160+ nrf_security_mutex_lock (cracen_prng_trng_mutex );
138161 safe_memset (& prng , sizeof (prng ), 0 , sizeof (prng ));
139162
140163 /* Get the entropy used to seed the DRBG */
141- sx_err = trng_get_seed (entropy , sizeof (entropy ));
164+ sx_err = trng_get_entropy (entropy , sizeof (entropy ));
142165
143166 if (sx_err != SX_OK ) {
144167 goto exit ;
@@ -158,7 +181,7 @@ psa_status_t cracen_init_random(cracen_prng_context_t *context)
158181 prng .initialized = CRACEN_PRNG_INITIALIZED ;
159182
160183exit :
161- nrf_security_mutex_unlock (cracen_prng_context_mutex );
184+ nrf_security_mutex_unlock (cracen_prng_trng_mutex );
162185
163186 return silex_statuscodes_to_psa (sx_err );
164187}
@@ -169,7 +192,7 @@ static psa_status_t cracen_reseed(void)
169192
170193 /* DRBG entropy + nonce buffer. */
171194 char entropy [CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE ];
172- int sx_err = trng_get_seed (entropy , sizeof (entropy ));
195+ int sx_err = trng_get_entropy (entropy , sizeof (entropy ));
173196
174197 if (sx_err ) {
175198 return PSA_ERROR_HARDWARE_FAILURE ;
@@ -199,7 +222,7 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
199222 return PSA_ERROR_INVALID_ARGUMENT ;
200223 }
201224
202- nrf_security_mutex_lock (cracen_prng_context_mutex );
225+ nrf_security_mutex_lock (cracen_prng_trng_mutex );
203226
204227 if (prng .reseed_counter == 0 ) {
205228 /* Zephyr mutexes allow the same thread to lock a
@@ -208,15 +231,15 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
208231 */
209232 status = cracen_init_random (context );
210233 if (status != PSA_SUCCESS ) {
211- nrf_security_mutex_unlock (cracen_prng_context_mutex );
234+ nrf_security_mutex_unlock (cracen_prng_trng_mutex );
212235 return status ;
213236 }
214237 }
215238
216239 if (prng .reseed_counter + number_of_blocks >= RESEED_INTERVAL ) {
217240 status = cracen_reseed ();
218241 if (status != PSA_SUCCESS ) {
219- nrf_security_mutex_unlock (cracen_prng_context_mutex );
242+ nrf_security_mutex_unlock (cracen_prng_trng_mutex );
220243 return status ;
221244 }
222245 }
@@ -236,7 +259,7 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
236259 temp , sizeof (temp ));
237260
238261 if (status != PSA_SUCCESS ) {
239- nrf_security_mutex_unlock (cracen_prng_context_mutex );
262+ nrf_security_mutex_unlock (cracen_prng_trng_mutex );
240263 return status ;
241264 }
242265
@@ -250,7 +273,7 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
250273 }
251274
252275 status = ctr_drbg_update (NULL );
253- nrf_security_mutex_unlock (cracen_prng_context_mutex );
276+ nrf_security_mutex_unlock (cracen_prng_trng_mutex );
254277 return status ;
255278}
256279
@@ -259,3 +282,19 @@ psa_status_t cracen_free_random(cracen_prng_context_t *context)
259282 (void )context ;
260283 return PSA_SUCCESS ;
261284}
285+
286+
287+ psa_status_t cracen_get_trng (uint8_t * output , size_t output_size )
288+ {
289+ int sx_err ;
290+
291+ if (output == NULL || output_size == 0 ) {
292+ return PSA_ERROR_INVALID_ARGUMENT ;
293+ }
294+
295+ nrf_security_mutex_lock (cracen_prng_trng_mutex );
296+ sx_err = trng_get_entropy ((char * )output , output_size );
297+ nrf_security_mutex_unlock (cracen_prng_trng_mutex );
298+
299+ return silex_statuscodes_to_psa (sx_err );
300+ }
0 commit comments