Skip to content

Commit ffa68f5

Browse files
degjorvanordicjm
authored andcommitted
nrf_security: cracen: add support for l09/l20 to ctr_drbg
l09/l20 only supports a 16 bit ctr counter. As such we must reseed before this counter overflows, to avoid repeating blocks. Limited the max output for cracen lite boards and changed the reseed counter to depend on the amount of blocks given as input to support this Signed-off-by: Dag Erik Gjørvad <[email protected]>
1 parent 733f6fb commit ffa68f5

File tree

1 file changed

+39
-32
lines changed
  • subsys/nrf_security/src/drivers/cracen/cracenpsa/src

1 file changed

+39
-32
lines changed

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

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,17 @@
2020
#include <sxsymcrypt/trng.h>
2121
#include <sxsymcrypt/aes.h>
2222
#include <sxsymcrypt/keyref.h>
23-
2423
#include <zephyr/kernel.h>
2524
#include <nrf_security_mutexes.h>
2625

27-
#define MAX_BITS_PER_REQUEST (1 << 19) /* NIST.SP.800-90Ar1:Table 3 */
28-
#define RESEED_INTERVAL ((uint64_t)1 << 48) /* 2^48 as per NIST spec */
26+
#ifdef CONFIG_CRACEN_HW_VERSION_LITE
27+
#define MAX_BITS_PER_REQUEST (1 << 16) /* Cracen Lite only supports 2^16 ctr size */
28+
/* Cracen Lite only supports 2^16 ctr size so will need to reseed before it overflows */
29+
#define RESEED_INTERVAL ((uint64_t)1 << 16)
30+
#else
31+
#define MAX_BITS_PER_REQUEST (1 << 19) /* NIST.SP.800-90Ar1:Table 3 */
32+
#define RESEED_INTERVAL ((uint64_t)1 << 48) /* 2^48 as per NIST spec */
33+
#endif
2934

3035
/** @brief Magic number to signal that PRNG context is initialized */
3136
#define CRACEN_PRNG_INITIALIZED (0xA5B4A5B4)
@@ -103,6 +108,7 @@ static psa_status_t ctr_drbg_update(uint8_t *data)
103108
return status;
104109
}
105110
temp_length += SX_BLKCIPHER_AES_BLK_SZ;
111+
prng.reseed_counter++;
106112
}
107113

108114
if (data) {
@@ -158,12 +164,33 @@ psa_status_t cracen_init_random(cracen_prng_context_t *context)
158164
return silex_statuscodes_to_psa(sx_err);
159165
}
160166

167+
static psa_status_t cracen_reseed(void)
168+
{
169+
psa_status_t status;
170+
171+
/* DRBG entropy + nonce buffer. */
172+
char entropy[CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE];
173+
int sx_err = trng_get_seed(entropy, sizeof(entropy));
174+
175+
if (sx_err) {
176+
return PSA_ERROR_HARDWARE_FAILURE;
177+
}
178+
status = ctr_drbg_update(entropy);
179+
if (status != PSA_SUCCESS) {
180+
return status;
181+
}
182+
safe_memset(entropy, sizeof(entropy), 0, CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE);
183+
prng.reseed_counter = 0;
184+
return PSA_SUCCESS;
185+
}
186+
161187
psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output, size_t output_size)
162188
{
163189
(void)context;
164190

165191
psa_status_t status = PSA_SUCCESS;
166192
size_t len_left = output_size;
193+
size_t number_of_blocks = DIV_ROUND_UP(output_size, SX_BLKCIPHER_AES_BLK_SZ);
167194

168195
if (output_size > 0 && output == NULL) {
169196
return PSA_ERROR_INVALID_ARGUMENT;
@@ -181,29 +208,18 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
181208
* here even though we hold the mutex.
182209
*/
183210
status = cracen_init_random(context);
184-
185211
if (status != PSA_SUCCESS) {
186-
goto exit;
212+
nrf_security_mutex_unlock(cracen_prng_context_mutex);
213+
return status;
187214
}
188215
}
189216

190-
if (prng.reseed_counter >= RESEED_INTERVAL) {
191-
char entropy[CRACEN_PRNG_ENTROPY_SIZE +
192-
CRACEN_PRNG_NONCE_SIZE]; /* DRBG entropy + nonce buffer. */
193-
int sx_err = trng_get_seed(entropy, sizeof(entropy));
194-
195-
if (sx_err) {
196-
status = PSA_ERROR_HARDWARE_FAILURE;
197-
goto exit;
198-
}
199-
status = ctr_drbg_update(entropy);
217+
if (prng.reseed_counter + number_of_blocks >= RESEED_INTERVAL) {
218+
status = cracen_reseed();
200219
if (status != PSA_SUCCESS) {
201-
goto exit;
220+
nrf_security_mutex_unlock(cracen_prng_context_mutex);
221+
return status;
202222
}
203-
safe_memset(entropy, sizeof(entropy), 0,
204-
CRACEN_PRNG_ENTROPY_SIZE + CRACEN_PRNG_NONCE_SIZE);
205-
206-
prng.reseed_counter = 0;
207223
}
208224

209225
psa_key_attributes_t attr = PSA_KEY_ATTRIBUTES_INIT;
@@ -212,10 +228,6 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
212228
psa_set_key_bits(&attr, PSA_BYTES_TO_BITS(sizeof(prng.key)));
213229
psa_set_key_usage_flags(&attr, PSA_KEY_USAGE_ENCRYPT);
214230

215-
if (status != PSA_SUCCESS) {
216-
return status;
217-
}
218-
219231
while (len_left > 0) {
220232
size_t cur_len = MIN(len_left, SX_BLKCIPHER_AES_BLK_SZ);
221233
char temp[SX_BLKCIPHER_AES_BLK_SZ] __aligned(CONFIG_DCACHE_LINE_SIZE);
@@ -225,7 +237,8 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
225237
temp, sizeof(temp));
226238

227239
if (status != PSA_SUCCESS) {
228-
goto exit;
240+
nrf_security_mutex_unlock(cracen_prng_context_mutex);
241+
return status;
229242
}
230243

231244
for (int i = 0; i < cur_len; i++) {
@@ -234,16 +247,10 @@ psa_status_t cracen_get_random(cracen_prng_context_t *context, uint8_t *output,
234247

235248
len_left -= cur_len;
236249
output += cur_len;
250+
prng.reseed_counter++;
237251
}
238252

239253
status = ctr_drbg_update(NULL);
240-
if (status != PSA_SUCCESS) {
241-
goto exit;
242-
}
243-
244-
prng.reseed_counter += 1;
245-
246-
exit:
247254
nrf_security_mutex_unlock(cracen_prng_context_mutex);
248255
return status;
249256
}

0 commit comments

Comments
 (0)