1 /*
2  * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <string.h>
11 #include <openssl/rand.h>
12 #include <openssl/core_dispatch.h>
13 #include <openssl/e_os2.h>
14 #include <openssl/params.h>
15 #include <openssl/core_names.h>
16 #include <openssl/evp.h>
17 #include <openssl/err.h>
18 #include <openssl/randerr.h>
19 #include <openssl/proverr.h>
20 #include "prov/implementations.h"
21 #include "prov/provider_ctx.h"
22 #include "crypto/rand.h"
23 #include "crypto/rand_pool.h"
24 
25 #ifndef OPENSSL_NO_JITTER
26 # include <jitterentropy.h>
27 
28 # define JITTER_MAX_NUM_TRIES 3
29 
30 static OSSL_FUNC_rand_newctx_fn jitter_new;
31 static OSSL_FUNC_rand_freectx_fn jitter_free;
32 static OSSL_FUNC_rand_instantiate_fn jitter_instantiate;
33 static OSSL_FUNC_rand_uninstantiate_fn jitter_uninstantiate;
34 static OSSL_FUNC_rand_generate_fn jitter_generate;
35 static OSSL_FUNC_rand_reseed_fn jitter_reseed;
36 static OSSL_FUNC_rand_gettable_ctx_params_fn jitter_gettable_ctx_params;
37 static OSSL_FUNC_rand_get_ctx_params_fn jitter_get_ctx_params;
38 static OSSL_FUNC_rand_verify_zeroization_fn jitter_verify_zeroization;
39 static OSSL_FUNC_rand_enable_locking_fn jitter_enable_locking;
40 static OSSL_FUNC_rand_lock_fn jitter_lock;
41 static OSSL_FUNC_rand_unlock_fn jitter_unlock;
42 static OSSL_FUNC_rand_get_seed_fn jitter_get_seed;
43 static OSSL_FUNC_rand_clear_seed_fn jitter_clear_seed;
44 
45 typedef struct {
46     void *provctx;
47     int state;
48 } PROV_JITTER;
49 
50 static size_t get_jitter_random_value(PROV_JITTER *s, unsigned char *buf, size_t len);
51 
52 /*
53  * Acquire entropy from jitterentropy library
54  *
55  * Returns the total entropy count, if it exceeds the requested
56  * entropy count. Otherwise, returns an entropy count of 0.
57  */
ossl_prov_acquire_entropy_from_jitter(PROV_JITTER * s,RAND_POOL * pool)58 static size_t ossl_prov_acquire_entropy_from_jitter(PROV_JITTER *s,
59                                                     RAND_POOL *pool)
60 {
61     size_t bytes_needed;
62     unsigned char *buffer;
63 
64     bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /* entropy_factor */);
65     if (bytes_needed > 0) {
66         buffer = ossl_rand_pool_add_begin(pool, bytes_needed);
67 
68         if (buffer != NULL) {
69             if (get_jitter_random_value(s, buffer, bytes_needed) == bytes_needed) {
70                 ossl_rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
71             } else {
72                 ossl_rand_pool_add_end(pool, 0, 0);
73             }
74         }
75     }
76 
77     return ossl_rand_pool_entropy_available(pool);
78 }
79 
80 /* Obtain random bytes from the jitter library */
get_jitter_random_value(PROV_JITTER * s,unsigned char * buf,size_t len)81 static size_t get_jitter_random_value(PROV_JITTER *s,
82                                       unsigned char *buf, size_t len)
83 {
84     struct rand_data *jitter_ec = NULL;
85     ssize_t result = 0;
86     size_t num_tries;
87 
88     /* Retry intermittent failures, then give up */
89     for (num_tries = 0; num_tries < JITTER_MAX_NUM_TRIES; num_tries++) {
90         /* Allocate a fresh collector */
91         jitter_ec = jent_entropy_collector_alloc(0, JENT_FORCE_FIPS);
92         if (jitter_ec == NULL)
93             continue;
94 
95         /* Do not use _safe API as per typical security policies */
96         result = jent_read_entropy(jitter_ec, (char *) buf, len);
97         jent_entropy_collector_free(jitter_ec);
98 
99         /*
100          * Permanent Failure
101          * https://github.com/smuellerDD/jitterentropy-library/issues/118
102          */
103         if (result < -5)
104             break;
105 
106         /* Success */
107         if (result >= 0 && (size_t)result == len)
108             return len;
109     }
110 
111     /* Permanent failure or too many intermittent failures */
112     s->state = EVP_RAND_STATE_ERROR;
113     ERR_raise_data(ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_ENTROPY,
114                    "jent_read_entropy (%d)", result);
115     return 0;
116 }
117 
jitter_new(void * provctx,void * parent,const OSSL_DISPATCH * parent_dispatch)118 static void *jitter_new(void *provctx, void *parent,
119                         const OSSL_DISPATCH *parent_dispatch)
120 {
121     PROV_JITTER *s;
122 
123     if (parent != NULL) {
124         ERR_raise(ERR_LIB_PROV, PROV_R_SEED_SOURCES_MUST_NOT_HAVE_A_PARENT);
125         return NULL;
126     }
127 
128     s = OPENSSL_zalloc(sizeof(*s));
129     if (s == NULL)
130         return NULL;
131 
132     s->provctx = provctx;
133     s->state = EVP_RAND_STATE_UNINITIALISED;
134     return s;
135 }
136 
jitter_free(void * vseed)137 static void jitter_free(void *vseed)
138 {
139     OPENSSL_free(vseed);
140 }
141 
jitter_instantiate(void * vseed,unsigned int strength,int prediction_resistance,const unsigned char * pstr,size_t pstr_len,ossl_unused const OSSL_PARAM params[])142 static int jitter_instantiate(void *vseed, unsigned int strength,
143                               int prediction_resistance,
144                               const unsigned char *pstr,
145                               size_t pstr_len,
146                               ossl_unused const OSSL_PARAM params[])
147 {
148     PROV_JITTER *s = (PROV_JITTER *)vseed;
149     int ret;
150 
151     if ((ret = jent_entropy_init_ex(0, JENT_FORCE_FIPS)) != 0) {
152         ERR_raise_data(ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_ENTROPY,
153                        "jent_entropy_init_ex (%d)", ret);
154         s->state = EVP_RAND_STATE_ERROR;
155         return 0;
156     }
157 
158     s->state = EVP_RAND_STATE_READY;
159     return 1;
160 }
161 
jitter_uninstantiate(void * vseed)162 static int jitter_uninstantiate(void *vseed)
163 {
164     PROV_JITTER *s = (PROV_JITTER *)vseed;
165 
166     s->state = EVP_RAND_STATE_UNINITIALISED;
167     return 1;
168 }
169 
jitter_generate(void * vseed,unsigned char * out,size_t outlen,unsigned int strength,ossl_unused int prediction_resistance,ossl_unused const unsigned char * adin,ossl_unused size_t adin_len)170 static int jitter_generate(void *vseed, unsigned char *out, size_t outlen,
171                            unsigned int strength,
172                            ossl_unused int prediction_resistance,
173                            ossl_unused const unsigned char *adin,
174                            ossl_unused size_t adin_len)
175 {
176     PROV_JITTER *s = (PROV_JITTER *)vseed;
177     size_t entropy_available;
178     RAND_POOL *pool;
179 
180     if (s->state != EVP_RAND_STATE_READY) {
181         ERR_raise(ERR_LIB_PROV,
182                   s->state == EVP_RAND_STATE_ERROR ? PROV_R_IN_ERROR_STATE
183                                                    : PROV_R_NOT_INSTANTIATED);
184         return 0;
185     }
186 
187     pool = ossl_rand_pool_new(strength, 1, outlen, outlen);
188     if (pool == NULL) {
189         ERR_raise(ERR_LIB_PROV, ERR_R_RAND_LIB);
190         return 0;
191     }
192 
193     /* Get entropy from jitter entropy library. */
194     entropy_available = ossl_prov_acquire_entropy_from_jitter(s, pool);
195 
196     if (entropy_available > 0)
197         memcpy(out, ossl_rand_pool_buffer(pool), ossl_rand_pool_length(pool));
198 
199     ossl_rand_pool_free(pool);
200     return entropy_available > 0;
201 }
202 
jitter_reseed(void * vseed,ossl_unused int prediction_resistance,ossl_unused const unsigned char * ent,ossl_unused size_t ent_len,ossl_unused const unsigned char * adin,ossl_unused size_t adin_len)203 static int jitter_reseed(void *vseed,
204                          ossl_unused int prediction_resistance,
205                          ossl_unused const unsigned char *ent,
206                          ossl_unused size_t ent_len,
207                          ossl_unused const unsigned char *adin,
208                          ossl_unused size_t adin_len)
209 {
210     PROV_JITTER *s = (PROV_JITTER *)vseed;
211 
212     if (s->state != EVP_RAND_STATE_READY) {
213         ERR_raise(ERR_LIB_PROV,
214                   s->state == EVP_RAND_STATE_ERROR ? PROV_R_IN_ERROR_STATE
215                                                    : PROV_R_NOT_INSTANTIATED);
216         return 0;
217     }
218     return 1;
219 }
220 
jitter_get_ctx_params(void * vseed,OSSL_PARAM params[])221 static int jitter_get_ctx_params(void *vseed, OSSL_PARAM params[])
222 {
223     PROV_JITTER *s = (PROV_JITTER *)vseed;
224     OSSL_PARAM *p;
225 
226     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STATE);
227     if (p != NULL && !OSSL_PARAM_set_int(p, s->state))
228         return 0;
229 
230     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STRENGTH);
231     if (p != NULL && !OSSL_PARAM_set_int(p, 1024))
232         return 0;
233 
234     p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST);
235     if (p != NULL && !OSSL_PARAM_set_size_t(p, 128))
236         return 0;
237     return 1;
238 }
239 
jitter_gettable_ctx_params(ossl_unused void * vseed,ossl_unused void * provctx)240 static const OSSL_PARAM *jitter_gettable_ctx_params(ossl_unused void *vseed,
241                                                     ossl_unused void *provctx)
242 {
243     static const OSSL_PARAM known_gettable_ctx_params[] = {
244         OSSL_PARAM_int(OSSL_RAND_PARAM_STATE, NULL),
245         OSSL_PARAM_uint(OSSL_RAND_PARAM_STRENGTH, NULL),
246         OSSL_PARAM_size_t(OSSL_RAND_PARAM_MAX_REQUEST, NULL),
247         OSSL_PARAM_END
248     };
249     return known_gettable_ctx_params;
250 }
251 
jitter_verify_zeroization(ossl_unused void * vseed)252 static int jitter_verify_zeroization(ossl_unused void *vseed)
253 {
254     return 1;
255 }
256 
jitter_get_seed(void * vseed,unsigned char ** pout,int entropy,size_t min_len,size_t max_len,int prediction_resistance,const unsigned char * adin,size_t adin_len)257 static size_t jitter_get_seed(void *vseed, unsigned char **pout,
258                               int entropy, size_t min_len,
259                               size_t max_len,
260                               int prediction_resistance,
261                               const unsigned char *adin,
262                               size_t adin_len)
263 {
264     size_t ret = 0;
265     size_t entropy_available = 0;
266     size_t i;
267     RAND_POOL *pool;
268     PROV_JITTER *s = (PROV_JITTER *)vseed;
269 
270     pool = ossl_rand_pool_new(entropy, 1, min_len, max_len);
271     if (pool == NULL) {
272         ERR_raise(ERR_LIB_PROV, ERR_R_RAND_LIB);
273         return 0;
274     }
275 
276     /* Get entropy from jitter entropy library. */
277     entropy_available = ossl_prov_acquire_entropy_from_jitter(s, pool);
278 
279     if (entropy_available > 0) {
280         ret = ossl_rand_pool_length(pool);
281         *pout = ossl_rand_pool_detach(pool);
282 
283         /* xor the additional data into the output */
284         for (i = 0; i < adin_len; ++i)
285             (*pout)[i % ret] ^= adin[i];
286     } else {
287         ERR_raise(ERR_LIB_PROV, PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK);
288     }
289     ossl_rand_pool_free(pool);
290     return ret;
291 }
292 
jitter_clear_seed(ossl_unused void * vdrbg,unsigned char * out,size_t outlen)293 static void jitter_clear_seed(ossl_unused void *vdrbg,
294                               unsigned char *out, size_t outlen)
295 {
296     OPENSSL_secure_clear_free(out, outlen);
297 }
298 
jitter_enable_locking(ossl_unused void * vseed)299 static int jitter_enable_locking(ossl_unused void *vseed)
300 {
301     return 1;
302 }
303 
jitter_lock(ossl_unused void * vctx)304 int jitter_lock(ossl_unused void *vctx)
305 {
306     return 1;
307 }
308 
jitter_unlock(ossl_unused void * vctx)309 void jitter_unlock(ossl_unused void *vctx)
310 {
311 }
312 
313 const OSSL_DISPATCH ossl_jitter_functions[] = {
314     { OSSL_FUNC_RAND_NEWCTX, (void(*)(void))jitter_new },
315     { OSSL_FUNC_RAND_FREECTX, (void(*)(void))jitter_free },
316     { OSSL_FUNC_RAND_INSTANTIATE,
317       (void(*)(void))jitter_instantiate },
318     { OSSL_FUNC_RAND_UNINSTANTIATE,
319       (void(*)(void))jitter_uninstantiate },
320     { OSSL_FUNC_RAND_GENERATE, (void(*)(void))jitter_generate },
321     { OSSL_FUNC_RAND_RESEED, (void(*)(void))jitter_reseed },
322     { OSSL_FUNC_RAND_ENABLE_LOCKING, (void(*)(void))jitter_enable_locking },
323     { OSSL_FUNC_RAND_LOCK, (void(*)(void))jitter_lock },
324     { OSSL_FUNC_RAND_UNLOCK, (void(*)(void))jitter_unlock },
325     { OSSL_FUNC_RAND_GETTABLE_CTX_PARAMS,
326       (void(*)(void))jitter_gettable_ctx_params },
327     { OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))jitter_get_ctx_params },
328     { OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
329       (void(*)(void))jitter_verify_zeroization },
330     { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))jitter_get_seed },
331     { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))jitter_clear_seed },
332     OSSL_DISPATCH_END
333 };
334 #else
335 NON_EMPTY_TRANSLATION_UNIT
336 #endif
337