43
43
*/
44
44
static cracen_prng_context_t prng ;
45
45
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 );
47
48
48
49
/*
49
50
* @brief Internal function to enable TRNG and get entropy for initial seed and
50
51
* reseed
51
52
*
52
53
* @return 0 on success, nonzero on failure.
53
54
*/
54
- static int trng_get_seed (char * dst , int num_trng_bytes )
55
+ static int trng_get_entropy (char * dst , int num_trng_bytes )
55
56
{
56
- int sx_err = SX_ERR_RESET_NEEDED ;
57
+ int sx_err ;
57
58
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 ;
72
89
}
73
- break ;
74
- default :
75
- (void )sx_trng_close (& trng );
90
+ }
91
+
92
+ (void )sx_trng_close (& trng );
93
+ if (sx_err != SX_OK ) {
76
94
return sx_err ;
77
95
}
96
+
97
+ num_trng_bytes -= trng_chunk_size ;
98
+ dst += trng_chunk_size ;
78
99
}
100
+
101
+ return SX_OK ;
79
102
}
80
103
81
104
/**
@@ -134,11 +157,11 @@ psa_status_t cracen_init_random(cracen_prng_context_t *context)
134
157
return PSA_SUCCESS ;
135
158
}
136
159
137
- nrf_security_mutex_lock (cracen_prng_context_mutex );
160
+ nrf_security_mutex_lock (cracen_prng_trng_mutex );
138
161
safe_memset (& prng , sizeof (prng ), 0 , sizeof (prng ));
139
162
140
163
/* 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 ));
142
165
143
166
if (sx_err != SX_OK ) {
144
167
goto exit ;
@@ -158,7 +181,7 @@ psa_status_t cracen_init_random(cracen_prng_context_t *context)
158
181
prng .initialized = CRACEN_PRNG_INITIALIZED ;
159
182
160
183
exit :
161
- nrf_security_mutex_unlock (cracen_prng_context_mutex );
184
+ nrf_security_mutex_unlock (cracen_prng_trng_mutex );
162
185
163
186
return silex_statuscodes_to_psa (sx_err );
164
187
}
@@ -169,7 +192,7 @@ static psa_status_t cracen_reseed(void)
169
192
170
193
/* DRBG entropy + nonce buffer. */
171
194
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 ));
173
196
174
197
if (sx_err ) {
175
198
return PSA_ERROR_HARDWARE_FAILURE ;
@@ -199,7 +222,7 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
199
222
return PSA_ERROR_INVALID_ARGUMENT ;
200
223
}
201
224
202
- nrf_security_mutex_lock (cracen_prng_context_mutex );
225
+ nrf_security_mutex_lock (cracen_prng_trng_mutex );
203
226
204
227
if (prng .reseed_counter == 0 ) {
205
228
/* 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,
208
231
*/
209
232
status = cracen_init_random (context );
210
233
if (status != PSA_SUCCESS ) {
211
- nrf_security_mutex_unlock (cracen_prng_context_mutex );
234
+ nrf_security_mutex_unlock (cracen_prng_trng_mutex );
212
235
return status ;
213
236
}
214
237
}
215
238
216
239
if (prng .reseed_counter + number_of_blocks >= RESEED_INTERVAL ) {
217
240
status = cracen_reseed ();
218
241
if (status != PSA_SUCCESS ) {
219
- nrf_security_mutex_unlock (cracen_prng_context_mutex );
242
+ nrf_security_mutex_unlock (cracen_prng_trng_mutex );
220
243
return status ;
221
244
}
222
245
}
@@ -236,7 +259,7 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
236
259
temp , sizeof (temp ));
237
260
238
261
if (status != PSA_SUCCESS ) {
239
- nrf_security_mutex_unlock (cracen_prng_context_mutex );
262
+ nrf_security_mutex_unlock (cracen_prng_trng_mutex );
240
263
return status ;
241
264
}
242
265
@@ -250,7 +273,7 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
250
273
}
251
274
252
275
status = ctr_drbg_update (NULL );
253
- nrf_security_mutex_unlock (cracen_prng_context_mutex );
276
+ nrf_security_mutex_unlock (cracen_prng_trng_mutex );
254
277
return status ;
255
278
}
256
279
@@ -259,3 +282,19 @@ psa_status_t cracen_free_random(cracen_prng_context_t *context)
259
282
(void )context ;
260
283
return PSA_SUCCESS ;
261
284
}
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