1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 #ifdef LTC_RNG_MAKE_PRNG
6 /**
7 @file rng_make_prng.c
8 portable way to get secure random bits to feed a PRNG (Tom St Denis)
9 */
10
11 /**
12 Create a PRNG from a RNG
13
14 In case you pass bits as '-1' the PRNG will be setup
15 as if the export/import functionality has been used,
16 but the imported data comes directly from the RNG.
17
18 @param bits Number of bits of entropy desired (-1 or 64 ... 1024)
19 @param wprng Index of which PRNG to setup
20 @param prng [out] PRNG state to initialize
21 @param callback A pointer to a void function for when the RNG is slow, this can be NULL
22 @return CRYPT_OK if successful
23 */
rng_make_prng(int bits,int wprng,prng_state * prng,void (* callback)(void))24 int rng_make_prng(int bits, int wprng, prng_state *prng,
25 void (*callback)(void))
26 {
27 unsigned char* buf;
28 unsigned long bytes;
29 int err;
30
31 LTC_ARGCHK(prng != NULL);
32
33 /* check parameter */
34 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
35 return err;
36 }
37
38 if (bits == -1) {
39 bytes = prng_descriptor[wprng]->export_size;
40 } else if (bits < 64 || bits > 1024) {
41 return CRYPT_INVALID_PRNGSIZE;
42 } else {
43 bytes = (unsigned long)((bits+7)/8) * 2;
44 }
45
46 if ((err = prng_descriptor[wprng]->start(prng)) != CRYPT_OK) {
47 return err;
48 }
49
50 buf = XMALLOC(bytes);
51 if (buf == NULL) {
52 return CRYPT_MEM;
53 }
54
55 if (rng_get_bytes(buf, bytes, callback) != bytes) {
56 err = CRYPT_ERROR_READPRNG;
57 goto LBL_ERR;
58 }
59
60 if (bits == -1) {
61 if ((err = prng_descriptor[wprng]->pimport(buf, bytes, prng)) != CRYPT_OK) {
62 goto LBL_ERR;
63 }
64 } else {
65 if ((err = prng_descriptor[wprng]->add_entropy(buf, bytes, prng)) != CRYPT_OK) {
66 goto LBL_ERR;
67 }
68 }
69 if ((err = prng_descriptor[wprng]->ready(prng)) != CRYPT_OK) {
70 goto LBL_ERR;
71 }
72
73 LBL_ERR:
74 #ifdef LTC_CLEAN_STACK
75 zeromem(buf, bytes);
76 #endif
77 XFREE(buf);
78 return err;
79 }
80 #endif /* #ifdef LTC_RNG_MAKE_PRNG */
81
82