1 /*
2 * CTR_DRBG implementation based on AES-256 (NIST SP 800-90)
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 */
7 /*
8 * The NIST SP 800-90 DRBGs are described in the following publication.
9 *
10 * https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-90r.pdf
11 */
12
13 #include "common.h"
14
15 #if defined(MBEDTLS_CTR_DRBG_C)
16
17 #include "ctr.h"
18 #include "mbedtls/ctr_drbg.h"
19 #include "mbedtls/platform_util.h"
20 #include "mbedtls/error.h"
21
22 #include <string.h>
23
24 #if defined(MBEDTLS_FS_IO)
25 #include <stdio.h>
26 #endif
27
28 /* Using error translation functions from PSA to MbedTLS */
29 #if !defined(MBEDTLS_AES_C)
30 #include "psa_util_internal.h"
31 #endif
32
33 #include "mbedtls/platform.h"
34
35 #if !defined(MBEDTLS_AES_C)
ctr_drbg_setup_psa_context(mbedtls_ctr_drbg_psa_context * psa_ctx,unsigned char * key,size_t key_len)36 static psa_status_t ctr_drbg_setup_psa_context(mbedtls_ctr_drbg_psa_context *psa_ctx,
37 unsigned char *key, size_t key_len)
38 {
39 psa_key_attributes_t key_attr = PSA_KEY_ATTRIBUTES_INIT;
40 psa_status_t status;
41
42 psa_set_key_usage_flags(&key_attr, PSA_KEY_USAGE_ENCRYPT);
43 psa_set_key_algorithm(&key_attr, PSA_ALG_ECB_NO_PADDING);
44 psa_set_key_type(&key_attr, PSA_KEY_TYPE_AES);
45 status = psa_import_key(&key_attr, key, key_len, &psa_ctx->key_id);
46 if (status != PSA_SUCCESS) {
47 goto exit;
48 }
49
50 status = psa_cipher_encrypt_setup(&psa_ctx->operation, psa_ctx->key_id, PSA_ALG_ECB_NO_PADDING);
51 if (status != PSA_SUCCESS) {
52 goto exit;
53 }
54
55 exit:
56 psa_reset_key_attributes(&key_attr);
57 return status;
58 }
59
ctr_drbg_destroy_psa_contex(mbedtls_ctr_drbg_psa_context * psa_ctx)60 static void ctr_drbg_destroy_psa_contex(mbedtls_ctr_drbg_psa_context *psa_ctx)
61 {
62 psa_cipher_abort(&psa_ctx->operation);
63 psa_destroy_key(psa_ctx->key_id);
64
65 psa_ctx->operation = psa_cipher_operation_init();
66 psa_ctx->key_id = MBEDTLS_SVC_KEY_ID_INIT;
67 }
68 #endif
69
70 /*
71 * CTR_DRBG context initialization
72 */
mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context * ctx)73 void mbedtls_ctr_drbg_init(mbedtls_ctr_drbg_context *ctx)
74 {
75 memset(ctx, 0, sizeof(mbedtls_ctr_drbg_context));
76 #if defined(MBEDTLS_AES_C)
77 mbedtls_aes_init(&ctx->aes_ctx);
78 #else
79 ctx->psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT;
80 ctx->psa_ctx.operation = psa_cipher_operation_init();
81 #endif
82 /* Indicate that the entropy nonce length is not set explicitly.
83 * See mbedtls_ctr_drbg_set_nonce_len(). */
84 ctx->reseed_counter = -1;
85
86 ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
87 }
88
89 /*
90 * This function resets CTR_DRBG context to the state immediately
91 * after initial call of mbedtls_ctr_drbg_init().
92 */
mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context * ctx)93 void mbedtls_ctr_drbg_free(mbedtls_ctr_drbg_context *ctx)
94 {
95 if (ctx == NULL) {
96 return;
97 }
98
99 #if defined(MBEDTLS_THREADING_C)
100 /* The mutex is initialized iff f_entropy is set. */
101 if (ctx->f_entropy != NULL) {
102 mbedtls_mutex_free(&ctx->mutex);
103 }
104 #endif
105 #if defined(MBEDTLS_AES_C)
106 mbedtls_aes_free(&ctx->aes_ctx);
107 #else
108 ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
109 #endif
110 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ctr_drbg_context));
111 ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL;
112 ctx->reseed_counter = -1;
113 }
114
mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context * ctx,int resistance)115 void mbedtls_ctr_drbg_set_prediction_resistance(mbedtls_ctr_drbg_context *ctx,
116 int resistance)
117 {
118 ctx->prediction_resistance = resistance;
119 }
120
mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context * ctx,size_t len)121 void mbedtls_ctr_drbg_set_entropy_len(mbedtls_ctr_drbg_context *ctx,
122 size_t len)
123 {
124 ctx->entropy_len = len;
125 }
126
mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context * ctx,size_t len)127 int mbedtls_ctr_drbg_set_nonce_len(mbedtls_ctr_drbg_context *ctx,
128 size_t len)
129 {
130 /* If mbedtls_ctr_drbg_seed() has already been called, it's
131 * too late. Return the error code that's closest to making sense. */
132 if (ctx->f_entropy != NULL) {
133 return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
134 }
135
136 if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
137 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
138 }
139
140 /* This shouldn't be an issue because
141 * MBEDTLS_CTR_DRBG_MAX_SEED_INPUT < INT_MAX in any sensible
142 * configuration, but make sure anyway. */
143 if (len > INT_MAX) {
144 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
145 }
146
147 /* For backward compatibility with Mbed TLS <= 2.19, store the
148 * entropy nonce length in a field that already exists, but isn't
149 * used until after the initial seeding. */
150 /* Due to the capping of len above, the value fits in an int. */
151 ctx->reseed_counter = (int) len;
152 return 0;
153 }
154
mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context * ctx,int interval)155 void mbedtls_ctr_drbg_set_reseed_interval(mbedtls_ctr_drbg_context *ctx,
156 int interval)
157 {
158 ctx->reseed_interval = interval;
159 }
160
block_cipher_df(unsigned char * output,const unsigned char * data,size_t data_len)161 static int block_cipher_df(unsigned char *output,
162 const unsigned char *data, size_t data_len)
163 {
164 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
165 MBEDTLS_CTR_DRBG_BLOCKSIZE + 16];
166 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
167 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
168 unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE];
169 unsigned char *p, *iv;
170 int ret = 0;
171 #if defined(MBEDTLS_AES_C)
172 mbedtls_aes_context aes_ctx;
173 #else
174 psa_status_t status;
175 size_t tmp_len;
176 mbedtls_ctr_drbg_psa_context psa_ctx;
177
178 psa_ctx.key_id = MBEDTLS_SVC_KEY_ID_INIT;
179 psa_ctx.operation = psa_cipher_operation_init();
180 #endif
181
182 int i, j;
183 size_t buf_len, use_len;
184
185 if (data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
186 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
187 }
188
189 memset(buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT +
190 MBEDTLS_CTR_DRBG_BLOCKSIZE + 16);
191
192 /*
193 * Construct IV (16 bytes) and S in buffer
194 * IV = Counter (in 32-bits) padded to 16 with zeroes
195 * S = Length input string (in 32-bits) || Length of output (in 32-bits) ||
196 * data || 0x80
197 * (Total is padded to a multiple of 16-bytes with zeroes)
198 */
199 p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE;
200 MBEDTLS_PUT_UINT32_BE(data_len, p, 0);
201 p += 4 + 3;
202 *p++ = MBEDTLS_CTR_DRBG_SEEDLEN;
203 memcpy(p, data, data_len);
204 p[data_len] = 0x80;
205
206 buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1;
207
208 for (i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++) {
209 key[i] = i;
210 }
211
212 #if defined(MBEDTLS_AES_C)
213 mbedtls_aes_init(&aes_ctx);
214
215 if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, key,
216 MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
217 goto exit;
218 }
219 #else
220 status = ctr_drbg_setup_psa_context(&psa_ctx, key, sizeof(key));
221 if (status != PSA_SUCCESS) {
222 ret = psa_generic_status_to_mbedtls(status);
223 goto exit;
224 }
225 #endif
226
227 /*
228 * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data
229 */
230 for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
231 p = buf;
232 memset(chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE);
233 use_len = buf_len;
234
235 while (use_len > 0) {
236 mbedtls_xor(chain, chain, p, MBEDTLS_CTR_DRBG_BLOCKSIZE);
237 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
238 use_len -= (use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE) ?
239 MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len;
240
241 #if defined(MBEDTLS_AES_C)
242 if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
243 chain, chain)) != 0) {
244 goto exit;
245 }
246 #else
247 status = psa_cipher_update(&psa_ctx.operation, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE,
248 chain, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
249 if (status != PSA_SUCCESS) {
250 ret = psa_generic_status_to_mbedtls(status);
251 goto exit;
252 }
253 #endif
254 }
255
256 memcpy(tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE);
257
258 /*
259 * Update IV
260 */
261 buf[3]++;
262 }
263
264 /*
265 * Do final encryption with reduced data
266 */
267 #if defined(MBEDTLS_AES_C)
268 if ((ret = mbedtls_aes_setkey_enc(&aes_ctx, tmp,
269 MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
270 goto exit;
271 }
272 #else
273 ctr_drbg_destroy_psa_contex(&psa_ctx);
274
275 status = ctr_drbg_setup_psa_context(&psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE);
276 if (status != PSA_SUCCESS) {
277 ret = psa_generic_status_to_mbedtls(status);
278 goto exit;
279 }
280 #endif
281 iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE;
282 p = output;
283
284 for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
285 #if defined(MBEDTLS_AES_C)
286 if ((ret = mbedtls_aes_crypt_ecb(&aes_ctx, MBEDTLS_AES_ENCRYPT,
287 iv, iv)) != 0) {
288 goto exit;
289 }
290 #else
291 status = psa_cipher_update(&psa_ctx.operation, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE,
292 iv, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
293 if (status != PSA_SUCCESS) {
294 ret = psa_generic_status_to_mbedtls(status);
295 goto exit;
296 }
297 #endif
298 memcpy(p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE);
299 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
300 }
301 exit:
302 #if defined(MBEDTLS_AES_C)
303 mbedtls_aes_free(&aes_ctx);
304 #else
305 ctr_drbg_destroy_psa_contex(&psa_ctx);
306 #endif
307 /*
308 * tidy up the stack
309 */
310 mbedtls_platform_zeroize(buf, sizeof(buf));
311 mbedtls_platform_zeroize(tmp, sizeof(tmp));
312 mbedtls_platform_zeroize(key, sizeof(key));
313 mbedtls_platform_zeroize(chain, sizeof(chain));
314 if (0 != ret) {
315 /*
316 * wipe partial seed from memory
317 */
318 mbedtls_platform_zeroize(output, MBEDTLS_CTR_DRBG_SEEDLEN);
319 }
320
321 return ret;
322 }
323
324 /* CTR_DRBG_Update (SP 800-90A §10.2.1.2)
325 * ctr_drbg_update_internal(ctx, provided_data)
326 * implements
327 * CTR_DRBG_Update(provided_data, Key, V)
328 * with inputs and outputs
329 * ctx->aes_ctx = Key
330 * ctx->counter = V
331 */
ctr_drbg_update_internal(mbedtls_ctr_drbg_context * ctx,const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN])332 static int ctr_drbg_update_internal(mbedtls_ctr_drbg_context *ctx,
333 const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN])
334 {
335 unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN];
336 unsigned char *p = tmp;
337 int j;
338 int ret = 0;
339 #if !defined(MBEDTLS_AES_C)
340 psa_status_t status;
341 size_t tmp_len;
342 #endif
343
344 memset(tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
345
346 for (j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE) {
347 /*
348 * Increase counter
349 */
350 mbedtls_ctr_increment_counter(ctx->counter);
351
352 /*
353 * Crypt counter block
354 */
355 #if defined(MBEDTLS_AES_C)
356 if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
357 ctx->counter, p)) != 0) {
358 goto exit;
359 }
360 #else
361 status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter),
362 p, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
363 if (status != PSA_SUCCESS) {
364 ret = psa_generic_status_to_mbedtls(status);
365 goto exit;
366 }
367 #endif
368
369 p += MBEDTLS_CTR_DRBG_BLOCKSIZE;
370 }
371
372 mbedtls_xor(tmp, tmp, data, MBEDTLS_CTR_DRBG_SEEDLEN);
373
374 /*
375 * Update key and counter
376 */
377 #if defined(MBEDTLS_AES_C)
378 if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, tmp,
379 MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
380 goto exit;
381 }
382 #else
383 ctr_drbg_destroy_psa_contex(&ctx->psa_ctx);
384
385 status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, tmp, MBEDTLS_CTR_DRBG_KEYSIZE);
386 if (status != PSA_SUCCESS) {
387 ret = psa_generic_status_to_mbedtls(status);
388 goto exit;
389 }
390 #endif
391 memcpy(ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE,
392 MBEDTLS_CTR_DRBG_BLOCKSIZE);
393
394 exit:
395 mbedtls_platform_zeroize(tmp, sizeof(tmp));
396 return ret;
397 }
398
399 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2)
400 * mbedtls_ctr_drbg_update(ctx, additional, add_len)
401 * implements
402 * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
403 * security_strength) -> initial_working_state
404 * with inputs
405 * ctx->counter = all-bits-0
406 * ctx->aes_ctx = context from all-bits-0 key
407 * additional[:add_len] = entropy_input || nonce || personalization_string
408 * and with outputs
409 * ctx = initial_working_state
410 */
mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t add_len)411 int mbedtls_ctr_drbg_update(mbedtls_ctr_drbg_context *ctx,
412 const unsigned char *additional,
413 size_t add_len)
414 {
415 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
416 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
417
418 if (add_len == 0) {
419 return 0;
420 }
421
422 if ((ret = block_cipher_df(add_input, additional, add_len)) != 0) {
423 goto exit;
424 }
425 if ((ret = ctr_drbg_update_internal(ctx, add_input)) != 0) {
426 goto exit;
427 }
428
429 exit:
430 mbedtls_platform_zeroize(add_input, sizeof(add_input));
431 return ret;
432 }
433
434 /* CTR_DRBG_Reseed with derivation function (SP 800-90A §10.2.1.4.2)
435 * mbedtls_ctr_drbg_reseed(ctx, additional, len, nonce_len)
436 * implements
437 * CTR_DRBG_Reseed(working_state, entropy_input, additional_input)
438 * -> new_working_state
439 * with inputs
440 * ctx contains working_state
441 * additional[:len] = additional_input
442 * and entropy_input comes from calling ctx->f_entropy
443 * for (ctx->entropy_len + nonce_len) bytes
444 * and with output
445 * ctx contains new_working_state
446 */
mbedtls_ctr_drbg_reseed_internal(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t len,size_t nonce_len)447 static int mbedtls_ctr_drbg_reseed_internal(mbedtls_ctr_drbg_context *ctx,
448 const unsigned char *additional,
449 size_t len,
450 size_t nonce_len)
451 {
452 unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
453 size_t seedlen = 0;
454 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
455
456 if (ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT) {
457 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
458 }
459 if (nonce_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len) {
460 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
461 }
462 if (len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len - nonce_len) {
463 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
464 }
465
466 memset(seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT);
467
468 /* Gather entropy_len bytes of entropy to seed state. */
469 if (0 != ctx->f_entropy(ctx->p_entropy, seed, ctx->entropy_len)) {
470 return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
471 }
472 seedlen += ctx->entropy_len;
473
474 /* Gather entropy for a nonce if requested. */
475 if (nonce_len != 0) {
476 if (0 != ctx->f_entropy(ctx->p_entropy, seed + seedlen, nonce_len)) {
477 return MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
478 }
479 seedlen += nonce_len;
480 }
481
482 /* Add additional data if provided. */
483 if (additional != NULL && len != 0) {
484 memcpy(seed + seedlen, additional, len);
485 seedlen += len;
486 }
487
488 /* Reduce to 384 bits. */
489 if ((ret = block_cipher_df(seed, seed, seedlen)) != 0) {
490 goto exit;
491 }
492
493 /* Update state. */
494 if ((ret = ctr_drbg_update_internal(ctx, seed)) != 0) {
495 goto exit;
496 }
497 ctx->reseed_counter = 1;
498
499 exit:
500 mbedtls_platform_zeroize(seed, sizeof(seed));
501 return ret;
502 }
503
mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context * ctx,const unsigned char * additional,size_t len)504 int mbedtls_ctr_drbg_reseed(mbedtls_ctr_drbg_context *ctx,
505 const unsigned char *additional, size_t len)
506 {
507 return mbedtls_ctr_drbg_reseed_internal(ctx, additional, len, 0);
508 }
509
510 /* Return a "good" nonce length for CTR_DRBG. The chosen nonce length
511 * is sufficient to achieve the maximum security strength given the key
512 * size and entropy length. If there is enough entropy in the initial
513 * call to the entropy function to serve as both the entropy input and
514 * the nonce, don't make a second call to get a nonce. */
good_nonce_len(size_t entropy_len)515 static size_t good_nonce_len(size_t entropy_len)
516 {
517 if (entropy_len >= MBEDTLS_CTR_DRBG_KEYSIZE * 3 / 2) {
518 return 0;
519 } else {
520 return (entropy_len + 1) / 2;
521 }
522 }
523
524 /* CTR_DRBG_Instantiate with derivation function (SP 800-90A §10.2.1.3.2)
525 * mbedtls_ctr_drbg_seed(ctx, f_entropy, p_entropy, custom, len)
526 * implements
527 * CTR_DRBG_Instantiate(entropy_input, nonce, personalization_string,
528 * security_strength) -> initial_working_state
529 * with inputs
530 * custom[:len] = nonce || personalization_string
531 * where entropy_input comes from f_entropy for ctx->entropy_len bytes
532 * and with outputs
533 * ctx = initial_working_state
534 */
mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context * ctx,int (* f_entropy)(void *,unsigned char *,size_t),void * p_entropy,const unsigned char * custom,size_t len)535 int mbedtls_ctr_drbg_seed(mbedtls_ctr_drbg_context *ctx,
536 int (*f_entropy)(void *, unsigned char *, size_t),
537 void *p_entropy,
538 const unsigned char *custom,
539 size_t len)
540 {
541 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
542 unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE];
543 size_t nonce_len;
544
545 memset(key, 0, MBEDTLS_CTR_DRBG_KEYSIZE);
546
547 /* The mutex is initialized iff f_entropy is set. */
548 #if defined(MBEDTLS_THREADING_C)
549 mbedtls_mutex_init(&ctx->mutex);
550 #endif
551
552 ctx->f_entropy = f_entropy;
553 ctx->p_entropy = p_entropy;
554
555 if (ctx->entropy_len == 0) {
556 ctx->entropy_len = MBEDTLS_CTR_DRBG_ENTROPY_LEN;
557 }
558 /* ctx->reseed_counter contains the desired amount of entropy to
559 * grab for a nonce (see mbedtls_ctr_drbg_set_nonce_len()).
560 * If it's -1, indicating that the entropy nonce length was not set
561 * explicitly, use a sufficiently large nonce for security. */
562 nonce_len = (ctx->reseed_counter >= 0 ?
563 (size_t) ctx->reseed_counter :
564 good_nonce_len(ctx->entropy_len));
565
566 /* Initialize with an empty key. */
567 #if defined(MBEDTLS_AES_C)
568 if ((ret = mbedtls_aes_setkey_enc(&ctx->aes_ctx, key,
569 MBEDTLS_CTR_DRBG_KEYBITS)) != 0) {
570 return ret;
571 }
572 #else
573 psa_status_t status;
574
575 status = ctr_drbg_setup_psa_context(&ctx->psa_ctx, key, MBEDTLS_CTR_DRBG_KEYSIZE);
576 if (status != PSA_SUCCESS) {
577 ret = psa_generic_status_to_mbedtls(status);
578 return status;
579 }
580 #endif
581
582 /* Do the initial seeding. */
583 if ((ret = mbedtls_ctr_drbg_reseed_internal(ctx, custom, len,
584 nonce_len)) != 0) {
585 return ret;
586 }
587 return 0;
588 }
589
590 /* CTR_DRBG_Generate with derivation function (SP 800-90A §10.2.1.5.2)
591 * mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, additional, add_len)
592 * implements
593 * CTR_DRBG_Reseed(working_state, entropy_input, additional[:add_len])
594 * -> working_state_after_reseed
595 * if required, then
596 * CTR_DRBG_Generate(working_state_after_reseed,
597 * requested_number_of_bits, additional_input)
598 * -> status, returned_bits, new_working_state
599 * with inputs
600 * ctx contains working_state
601 * requested_number_of_bits = 8 * output_len
602 * additional[:add_len] = additional_input
603 * and entropy_input comes from calling ctx->f_entropy
604 * and with outputs
605 * status = SUCCESS (this function does the reseed internally)
606 * returned_bits = output[:output_len]
607 * ctx contains new_working_state
608 */
mbedtls_ctr_drbg_random_with_add(void * p_rng,unsigned char * output,size_t output_len,const unsigned char * additional,size_t add_len)609 int mbedtls_ctr_drbg_random_with_add(void *p_rng,
610 unsigned char *output, size_t output_len,
611 const unsigned char *additional, size_t add_len)
612 {
613 int ret = 0;
614 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
615 unsigned char *p = output;
616 struct {
617 unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN];
618 unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE];
619 } locals;
620 size_t use_len;
621
622 if (output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST) {
623 return MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG;
624 }
625
626 if (add_len > MBEDTLS_CTR_DRBG_MAX_INPUT) {
627 return MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
628 }
629
630 memset(locals.add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN);
631
632 if (ctx->reseed_counter > ctx->reseed_interval ||
633 ctx->prediction_resistance) {
634 if ((ret = mbedtls_ctr_drbg_reseed(ctx, additional, add_len)) != 0) {
635 return ret;
636 }
637 add_len = 0;
638 }
639
640 if (add_len > 0) {
641 if ((ret = block_cipher_df(locals.add_input, additional, add_len)) != 0) {
642 goto exit;
643 }
644 if ((ret = ctr_drbg_update_internal(ctx, locals.add_input)) != 0) {
645 goto exit;
646 }
647 }
648
649 while (output_len > 0) {
650 /*
651 * Increase counter (treat it as a 128-bit big-endian integer).
652 */
653 mbedtls_ctr_increment_counter(ctx->counter);
654
655 /*
656 * Crypt counter block
657 */
658 #if defined(MBEDTLS_AES_C)
659 if ((ret = mbedtls_aes_crypt_ecb(&ctx->aes_ctx, MBEDTLS_AES_ENCRYPT,
660 ctx->counter, locals.tmp)) != 0) {
661 goto exit;
662 }
663 #else
664 psa_status_t status;
665 size_t tmp_len;
666
667 status = psa_cipher_update(&ctx->psa_ctx.operation, ctx->counter, sizeof(ctx->counter),
668 locals.tmp, MBEDTLS_CTR_DRBG_BLOCKSIZE, &tmp_len);
669 if (status != PSA_SUCCESS) {
670 ret = psa_generic_status_to_mbedtls(status);
671 goto exit;
672 }
673 #endif
674
675 use_len = (output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE)
676 ? MBEDTLS_CTR_DRBG_BLOCKSIZE : output_len;
677 /*
678 * Copy random block to destination
679 */
680 memcpy(p, locals.tmp, use_len);
681 p += use_len;
682 output_len -= use_len;
683 }
684
685 if ((ret = ctr_drbg_update_internal(ctx, locals.add_input)) != 0) {
686 goto exit;
687 }
688
689 ctx->reseed_counter++;
690
691 exit:
692 mbedtls_platform_zeroize(&locals, sizeof(locals));
693 return ret;
694 }
695
mbedtls_ctr_drbg_random(void * p_rng,unsigned char * output,size_t output_len)696 int mbedtls_ctr_drbg_random(void *p_rng, unsigned char *output,
697 size_t output_len)
698 {
699 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
700 mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng;
701
702 #if defined(MBEDTLS_THREADING_C)
703 if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
704 return ret;
705 }
706 #endif
707
708 ret = mbedtls_ctr_drbg_random_with_add(ctx, output, output_len, NULL, 0);
709
710 #if defined(MBEDTLS_THREADING_C)
711 if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
712 return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
713 }
714 #endif
715
716 return ret;
717 }
718
719 #if defined(MBEDTLS_FS_IO)
mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context * ctx,const char * path)720 int mbedtls_ctr_drbg_write_seed_file(mbedtls_ctr_drbg_context *ctx,
721 const char *path)
722 {
723 int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
724 FILE *f;
725 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT];
726
727 if ((f = fopen(path, "wb")) == NULL) {
728 return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
729 }
730
731 /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
732 mbedtls_setbuf(f, NULL);
733
734 if ((ret = mbedtls_ctr_drbg_random(ctx, buf,
735 MBEDTLS_CTR_DRBG_MAX_INPUT)) != 0) {
736 goto exit;
737 }
738
739 if (fwrite(buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f) !=
740 MBEDTLS_CTR_DRBG_MAX_INPUT) {
741 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
742 } else {
743 ret = 0;
744 }
745
746 exit:
747 mbedtls_platform_zeroize(buf, sizeof(buf));
748
749 fclose(f);
750 return ret;
751 }
752
mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context * ctx,const char * path)753 int mbedtls_ctr_drbg_update_seed_file(mbedtls_ctr_drbg_context *ctx,
754 const char *path)
755 {
756 int ret = 0;
757 FILE *f = NULL;
758 size_t n;
759 unsigned char buf[MBEDTLS_CTR_DRBG_MAX_INPUT];
760 unsigned char c;
761
762 if ((f = fopen(path, "rb")) == NULL) {
763 return MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
764 }
765
766 /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */
767 mbedtls_setbuf(f, NULL);
768
769 n = fread(buf, 1, sizeof(buf), f);
770 if (fread(&c, 1, 1, f) != 0) {
771 ret = MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG;
772 goto exit;
773 }
774 if (n == 0 || ferror(f)) {
775 ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR;
776 goto exit;
777 }
778 fclose(f);
779 f = NULL;
780
781 ret = mbedtls_ctr_drbg_update(ctx, buf, n);
782
783 exit:
784 mbedtls_platform_zeroize(buf, sizeof(buf));
785 if (f != NULL) {
786 fclose(f);
787 }
788 if (ret != 0) {
789 return ret;
790 }
791 return mbedtls_ctr_drbg_write_seed_file(ctx, path);
792 }
793 #endif /* MBEDTLS_FS_IO */
794
795 #if defined(MBEDTLS_SELF_TEST)
796
797 /* The CTR_DRBG NIST test vectors used here are available at
798 * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip
799 *
800 * The parameters used to derive the test data are:
801 *
802 * [AES-128 use df]
803 * [PredictionResistance = True/False]
804 * [EntropyInputLen = 128]
805 * [NonceLen = 64]
806 * [PersonalizationStringLen = 128]
807 * [AdditionalInputLen = 0]
808 * [ReturnedBitsLen = 512]
809 *
810 * [AES-256 use df]
811 * [PredictionResistance = True/False]
812 * [EntropyInputLen = 256]
813 * [NonceLen = 128]
814 * [PersonalizationStringLen = 256]
815 * [AdditionalInputLen = 0]
816 * [ReturnedBitsLen = 512]
817 *
818 */
819
820 #if defined(MBEDTLS_CTR_DRBG_USE_128_BIT_KEY)
821 static const unsigned char entropy_source_pr[] =
822 { 0x04, 0xd9, 0x49, 0xa6, 0xdc, 0xe8, 0x6e, 0xbb,
823 0xf1, 0x08, 0x77, 0x2b, 0x9e, 0x08, 0xca, 0x92,
824 0x65, 0x16, 0xda, 0x99, 0xa2, 0x59, 0xf3, 0xe8,
825 0x38, 0x7e, 0x3f, 0x6b, 0x51, 0x70, 0x7b, 0x20,
826 0xec, 0x53, 0xd0, 0x66, 0xc3, 0x0f, 0xe3, 0xb0,
827 0xe0, 0x86, 0xa6, 0xaa, 0x5f, 0x72, 0x2f, 0xad,
828 0xf7, 0xef, 0x06, 0xb8, 0xd6, 0x9c, 0x9d, 0xe8 };
829
830 static const unsigned char entropy_source_nopr[] =
831 { 0x07, 0x0d, 0x59, 0x63, 0x98, 0x73, 0xa5, 0x45,
832 0x27, 0x38, 0x22, 0x7b, 0x76, 0x85, 0xd1, 0xa9,
833 0x74, 0x18, 0x1f, 0x3c, 0x22, 0xf6, 0x49, 0x20,
834 0x4a, 0x47, 0xc2, 0xf3, 0x85, 0x16, 0xb4, 0x6f,
835 0x00, 0x2e, 0x71, 0xda, 0xed, 0x16, 0x9b, 0x5c };
836
837 static const unsigned char pers_pr[] =
838 { 0xbf, 0xa4, 0x9a, 0x8f, 0x7b, 0xd8, 0xb1, 0x7a,
839 0x9d, 0xfa, 0x45, 0xed, 0x21, 0x52, 0xb3, 0xad };
840
841 static const unsigned char pers_nopr[] =
842 { 0x4e, 0x61, 0x79, 0xd4, 0xc2, 0x72, 0xa1, 0x4c,
843 0xf1, 0x3d, 0xf6, 0x5e, 0xa3, 0xa6, 0xe5, 0x0f };
844
845 static const unsigned char result_pr[] =
846 { 0xc9, 0x0a, 0xaf, 0x85, 0x89, 0x71, 0x44, 0x66,
847 0x4f, 0x25, 0x0b, 0x2b, 0xde, 0xd8, 0xfa, 0xff,
848 0x52, 0x5a, 0x1b, 0x32, 0x5e, 0x41, 0x7a, 0x10,
849 0x1f, 0xef, 0x1e, 0x62, 0x23, 0xe9, 0x20, 0x30,
850 0xc9, 0x0d, 0xad, 0x69, 0xb4, 0x9c, 0x5b, 0xf4,
851 0x87, 0x42, 0xd5, 0xae, 0x5e, 0x5e, 0x43, 0xcc,
852 0xd9, 0xfd, 0x0b, 0x93, 0x4a, 0xe3, 0xd4, 0x06,
853 0x37, 0x36, 0x0f, 0x3f, 0x72, 0x82, 0x0c, 0xcf };
854
855 static const unsigned char result_nopr[] =
856 { 0x31, 0xc9, 0x91, 0x09, 0xf8, 0xc5, 0x10, 0x13,
857 0x3c, 0xd3, 0x96, 0xf9, 0xbc, 0x2c, 0x12, 0xc0,
858 0x7c, 0xc1, 0x61, 0x5f, 0xa3, 0x09, 0x99, 0xaf,
859 0xd7, 0xf2, 0x36, 0xfd, 0x40, 0x1a, 0x8b, 0xf2,
860 0x33, 0x38, 0xee, 0x1d, 0x03, 0x5f, 0x83, 0xb7,
861 0xa2, 0x53, 0xdc, 0xee, 0x18, 0xfc, 0xa7, 0xf2,
862 0xee, 0x96, 0xc6, 0xc2, 0xcd, 0x0c, 0xff, 0x02,
863 0x76, 0x70, 0x69, 0xaa, 0x69, 0xd1, 0x3b, 0xe8 };
864 #else /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
865
866 static const unsigned char entropy_source_pr[] =
867 { 0xca, 0x58, 0xfd, 0xf2, 0xb9, 0x77, 0xcb, 0x49,
868 0xd4, 0xe0, 0x5b, 0xe2, 0x39, 0x50, 0xd9, 0x8a,
869 0x6a, 0xb3, 0xc5, 0x2f, 0xdf, 0x74, 0xd5, 0x85,
870 0x8f, 0xd1, 0xba, 0x64, 0x54, 0x7b, 0xdb, 0x1e,
871 0xc5, 0xea, 0x24, 0xc0, 0xfa, 0x0c, 0x90, 0x15,
872 0x09, 0x20, 0x92, 0x42, 0x32, 0x36, 0x45, 0x45,
873 0x7d, 0x20, 0x76, 0x6b, 0xcf, 0xa2, 0x15, 0xc8,
874 0x2f, 0x9f, 0xbc, 0x88, 0x3f, 0x80, 0xd1, 0x2c,
875 0xb7, 0x16, 0xd1, 0x80, 0x9e, 0xe1, 0xc9, 0xb3,
876 0x88, 0x1b, 0x21, 0x45, 0xef, 0xa1, 0x7f, 0xce,
877 0xc8, 0x92, 0x35, 0x55, 0x2a, 0xd9, 0x1d, 0x8e,
878 0x12, 0x38, 0xac, 0x01, 0x4e, 0x38, 0x18, 0x76,
879 0x9c, 0xf2, 0xb6, 0xd4, 0x13, 0xb6, 0x2c, 0x77,
880 0xc0, 0xe7, 0xe6, 0x0c, 0x47, 0x44, 0x95, 0xbe };
881
882 static const unsigned char entropy_source_nopr[] =
883 { 0x4c, 0xfb, 0x21, 0x86, 0x73, 0x34, 0x6d, 0x9d,
884 0x50, 0xc9, 0x22, 0xe4, 0x9b, 0x0d, 0xfc, 0xd0,
885 0x90, 0xad, 0xf0, 0x4f, 0x5c, 0x3b, 0xa4, 0x73,
886 0x27, 0xdf, 0xcd, 0x6f, 0xa6, 0x3a, 0x78, 0x5c,
887 0x01, 0x69, 0x62, 0xa7, 0xfd, 0x27, 0x87, 0xa2,
888 0x4b, 0xf6, 0xbe, 0x47, 0xef, 0x37, 0x83, 0xf1,
889 0xb7, 0xec, 0x46, 0x07, 0x23, 0x63, 0x83, 0x4a,
890 0x1b, 0x01, 0x33, 0xf2, 0xc2, 0x38, 0x91, 0xdb,
891 0x4f, 0x11, 0xa6, 0x86, 0x51, 0xf2, 0x3e, 0x3a,
892 0x8b, 0x1f, 0xdc, 0x03, 0xb1, 0x92, 0xc7, 0xe7 };
893
894 static const unsigned char pers_pr[] =
895 { 0x5a, 0x70, 0x95, 0xe9, 0x81, 0x40, 0x52, 0x33,
896 0x91, 0x53, 0x7e, 0x75, 0xd6, 0x19, 0x9d, 0x1e,
897 0xad, 0x0d, 0xc6, 0xa7, 0xde, 0x6c, 0x1f, 0xe0,
898 0xea, 0x18, 0x33, 0xa8, 0x7e, 0x06, 0x20, 0xe9 };
899
900 static const unsigned char pers_nopr[] =
901 { 0x88, 0xee, 0xb8, 0xe0, 0xe8, 0x3b, 0xf3, 0x29,
902 0x4b, 0xda, 0xcd, 0x60, 0x99, 0xeb, 0xe4, 0xbf,
903 0x55, 0xec, 0xd9, 0x11, 0x3f, 0x71, 0xe5, 0xeb,
904 0xcb, 0x45, 0x75, 0xf3, 0xd6, 0xa6, 0x8a, 0x6b };
905
906 static const unsigned char result_pr[] =
907 { 0xce, 0x2f, 0xdb, 0xb6, 0xd9, 0xb7, 0x39, 0x85,
908 0x04, 0xc5, 0xc0, 0x42, 0xc2, 0x31, 0xc6, 0x1d,
909 0x9b, 0x5a, 0x59, 0xf8, 0x7e, 0x0d, 0xcc, 0x62,
910 0x7b, 0x65, 0x11, 0x55, 0x10, 0xeb, 0x9e, 0x3d,
911 0xa4, 0xfb, 0x1c, 0x6a, 0x18, 0xc0, 0x74, 0xdb,
912 0xdd, 0xe7, 0x02, 0x23, 0x63, 0x21, 0xd0, 0x39,
913 0xf9, 0xa7, 0xc4, 0x52, 0x84, 0x3b, 0x49, 0x40,
914 0x72, 0x2b, 0xb0, 0x6c, 0x9c, 0xdb, 0xc3, 0x43 };
915
916 static const unsigned char result_nopr[] =
917 { 0xa5, 0x51, 0x80, 0xa1, 0x90, 0xbe, 0xf3, 0xad,
918 0xaf, 0x28, 0xf6, 0xb7, 0x95, 0xe9, 0xf1, 0xf3,
919 0xd6, 0xdf, 0xa1, 0xb2, 0x7d, 0xd0, 0x46, 0x7b,
920 0x0c, 0x75, 0xf5, 0xfa, 0x93, 0x1e, 0x97, 0x14,
921 0x75, 0xb2, 0x7c, 0xae, 0x03, 0xa2, 0x96, 0x54,
922 0xe2, 0xf4, 0x09, 0x66, 0xea, 0x33, 0x64, 0x30,
923 0x40, 0xd1, 0x40, 0x0f, 0xe6, 0x77, 0x87, 0x3a,
924 0xf8, 0x09, 0x7c, 0x1f, 0xe9, 0xf0, 0x02, 0x98 };
925 #endif /* MBEDTLS_CTR_DRBG_USE_128_BIT_KEY */
926
927 static size_t test_offset;
ctr_drbg_self_test_entropy(void * data,unsigned char * buf,size_t len)928 static int ctr_drbg_self_test_entropy(void *data, unsigned char *buf,
929 size_t len)
930 {
931 const unsigned char *p = data;
932 memcpy(buf, p + test_offset, len);
933 test_offset += len;
934 return 0;
935 }
936
937 #define CHK(c) if ((c) != 0) \
938 { \
939 if (verbose != 0) \
940 mbedtls_printf("failed\n"); \
941 return 1; \
942 }
943
944 #define SELF_TEST_OUTPUT_DISCARD_LENGTH 64
945
946 /*
947 * Checkup routine
948 */
mbedtls_ctr_drbg_self_test(int verbose)949 int mbedtls_ctr_drbg_self_test(int verbose)
950 {
951 mbedtls_ctr_drbg_context ctx;
952 unsigned char buf[sizeof(result_pr)];
953
954 mbedtls_ctr_drbg_init(&ctx);
955
956 /*
957 * Based on a NIST CTR_DRBG test vector (PR = True)
958 */
959 if (verbose != 0) {
960 mbedtls_printf(" CTR_DRBG (PR = TRUE) : ");
961 }
962
963 test_offset = 0;
964 mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
965 mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2);
966 CHK(mbedtls_ctr_drbg_seed(&ctx,
967 ctr_drbg_self_test_entropy,
968 (void *) entropy_source_pr,
969 pers_pr, MBEDTLS_CTR_DRBG_KEYSIZE));
970 mbedtls_ctr_drbg_set_prediction_resistance(&ctx, MBEDTLS_CTR_DRBG_PR_ON);
971 CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH));
972 CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_pr)));
973 CHK(memcmp(buf, result_pr, sizeof(result_pr)));
974
975 mbedtls_ctr_drbg_free(&ctx);
976
977 if (verbose != 0) {
978 mbedtls_printf("passed\n");
979 }
980
981 /*
982 * Based on a NIST CTR_DRBG test vector (PR = FALSE)
983 */
984 if (verbose != 0) {
985 mbedtls_printf(" CTR_DRBG (PR = FALSE): ");
986 }
987
988 mbedtls_ctr_drbg_init(&ctx);
989
990 test_offset = 0;
991 mbedtls_ctr_drbg_set_entropy_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE);
992 mbedtls_ctr_drbg_set_nonce_len(&ctx, MBEDTLS_CTR_DRBG_KEYSIZE / 2);
993 CHK(mbedtls_ctr_drbg_seed(&ctx,
994 ctr_drbg_self_test_entropy,
995 (void *) entropy_source_nopr,
996 pers_nopr, MBEDTLS_CTR_DRBG_KEYSIZE));
997 CHK(mbedtls_ctr_drbg_reseed(&ctx, NULL, 0));
998 CHK(mbedtls_ctr_drbg_random(&ctx, buf, SELF_TEST_OUTPUT_DISCARD_LENGTH));
999 CHK(mbedtls_ctr_drbg_random(&ctx, buf, sizeof(result_nopr)));
1000 CHK(memcmp(buf, result_nopr, sizeof(result_nopr)));
1001
1002 mbedtls_ctr_drbg_free(&ctx);
1003
1004 if (verbose != 0) {
1005 mbedtls_printf("passed\n");
1006 }
1007
1008 if (verbose != 0) {
1009 mbedtls_printf("\n");
1010 }
1011
1012 return 0;
1013 }
1014 #endif /* MBEDTLS_SELF_TEST */
1015
1016 #endif /* MBEDTLS_CTR_DRBG_C */
1017