Skip to content

Commit 2286514

Browse files
Vge0rgeanangl
authored andcommitted
nrf_security: Add get TRNG function to Cracen driver
Adds a function to get TRNG from the Cracen driver at the same file that we have the PRNG driver so that we can reuse the same mutex for PRNG and TRNG. Ref: NCSDK-34036 Signed-off-by: Georgios Vasilakis <[email protected]>
1 parent 5ad4eea commit 2286514

File tree

2 files changed

+70
-29
lines changed

2 files changed

+70
-29
lines changed

subsys/nrf_security/src/drivers/cracen/cracenpsa/include/cracen_psa.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,4 +365,6 @@ psa_status_t cracen_derive_key(const psa_key_attributes_t *attributes, const uin
365365
size_t input_length, uint8_t *key, size_t key_size,
366366
size_t *key_length);
367367

368+
psa_status_t cracen_get_trng(uint8_t *output, size_t output_size);
369+
368370
#endif /* CRACEN_PSA_H */

subsys/nrf_security/src/drivers/cracen/cracenpsa/src/ctr_drbg.c

Lines changed: 68 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,39 +43,62 @@
4343
*/
4444
static 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

160183
exit:
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

Comments
 (0)