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