1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4 
5 /**
6    @file sprng.c
7    Secure PRNG, Tom St Denis
8 */
9 
10 /* A secure PRNG using the RNG functions.  Basically this is a
11  * wrapper that allows you to use a secure RNG as a PRNG
12  * in the various other functions.
13  */
14 
15 #ifdef LTC_SPRNG
16 
17 const struct ltc_prng_descriptor sprng_desc =
18 {
19     "sprng", 0,
20     &sprng_start,
21     &sprng_add_entropy,
22     &sprng_ready,
23     &sprng_read,
24     &sprng_done,
25     &sprng_export,
26     &sprng_import,
27     &sprng_test
28 };
29 
30 /**
31   Start the PRNG
32   @param prng     [out] The PRNG state to initialize
33   @return CRYPT_OK if successful
34 */
sprng_start(prng_state * prng)35 int sprng_start(prng_state *prng)
36 {
37    LTC_UNUSED_PARAM(prng);
38    return CRYPT_OK;
39 }
40 
41 /**
42   Add entropy to the PRNG state
43   @param in       The data to add
44   @param inlen    Length of the data to add
45   @param prng     PRNG state to update
46   @return CRYPT_OK if successful
47 */
sprng_add_entropy(const unsigned char * in,unsigned long inlen,prng_state * prng)48 int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
49 {
50    LTC_UNUSED_PARAM(in);
51    LTC_UNUSED_PARAM(inlen);
52    LTC_UNUSED_PARAM(prng);
53    return CRYPT_OK;
54 }
55 
56 /**
57   Make the PRNG ready to read from
58   @param prng   The PRNG to make active
59   @return CRYPT_OK if successful
60 */
sprng_ready(prng_state * prng)61 int sprng_ready(prng_state *prng)
62 {
63    LTC_UNUSED_PARAM(prng);
64    return CRYPT_OK;
65 }
66 
67 /**
68   Read from the PRNG
69   @param out      Destination
70   @param outlen   Length of output
71   @param prng     The active PRNG to read from
72   @return Number of octets read
73 */
sprng_read(unsigned char * out,unsigned long outlen,prng_state * prng)74 unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng)
75 {
76    LTC_ARGCHK(out != NULL);
77    LTC_UNUSED_PARAM(prng);
78    return rng_get_bytes(out, outlen, NULL);
79 }
80 
81 /**
82   Terminate the PRNG
83   @param prng   The PRNG to terminate
84   @return CRYPT_OK if successful
85 */
sprng_done(prng_state * prng)86 int sprng_done(prng_state *prng)
87 {
88    LTC_UNUSED_PARAM(prng);
89    return CRYPT_OK;
90 }
91 
92 /**
93   Export the PRNG state
94   @param out       [out] Destination
95   @param outlen    [in/out] Max size and resulting size of the state
96   @param prng      The PRNG to export
97   @return CRYPT_OK if successful
98 */
99 /* NOLINTNEXTLINE(readability-non-const-parameter) - silence clang-tidy warning */
sprng_export(unsigned char * out,unsigned long * outlen,prng_state * prng)100 int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
101 {
102    LTC_ARGCHK(outlen != NULL);
103    LTC_UNUSED_PARAM(out);
104    LTC_UNUSED_PARAM(prng);
105 
106    *outlen = 0;
107    return CRYPT_OK;
108 }
109 
110 /**
111   Import a PRNG state
112   @param in       The PRNG state
113   @param inlen    Size of the state
114   @param prng     The PRNG to import
115   @return CRYPT_OK if successful
116 */
sprng_import(const unsigned char * in,unsigned long inlen,prng_state * prng)117 int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
118 {
119   LTC_UNUSED_PARAM(in);
120   LTC_UNUSED_PARAM(inlen);
121   LTC_UNUSED_PARAM(prng);
122    return CRYPT_OK;
123 }
124 
125 /**
126   PRNG self-test
127   @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
128 */
sprng_test(void)129 int sprng_test(void)
130 {
131 #ifndef LTC_TEST
132    return CRYPT_NOP;
133 #else
134    prng_state st;
135    unsigned char en[] = { 0x01, 0x02, 0x03, 0x04 };
136    unsigned char out[1000];
137    int err;
138 
139    if ((err = sprng_start(&st)) != CRYPT_OK)                         return err;
140    if ((err = sprng_add_entropy(en, sizeof(en), &st)) != CRYPT_OK)   return err;
141    if ((err = sprng_ready(&st)) != CRYPT_OK)                         return err;
142    if (sprng_read(out, 500, &st) != 500)                             return CRYPT_ERROR_READPRNG; /* skip 500 bytes */
143    if ((err = sprng_done(&st)) != CRYPT_OK)                          return err;
144 
145    return CRYPT_OK;
146 #endif
147 }
148 
149 #endif
150 
151 
152 
153