1*b077aed3SPierre Pronchery /* 2*b077aed3SPierre Pronchery * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3*b077aed3SPierre Pronchery * 4*b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use 5*b077aed3SPierre Pronchery * this file except in compliance with the License. You can obtain a copy 6*b077aed3SPierre Pronchery * in the file LICENSE in the source distribution or at 7*b077aed3SPierre Pronchery * https://www.openssl.org/source/license.html 8*b077aed3SPierre Pronchery */ 9*b077aed3SPierre Pronchery 10*b077aed3SPierre Pronchery #ifndef OSSL_PROVIDER_RAND_POOL_H 11*b077aed3SPierre Pronchery # define OSSL_PROVIDER_RAND_POOL_H 12*b077aed3SPierre Pronchery # pragma once 13*b077aed3SPierre Pronchery 14*b077aed3SPierre Pronchery # include <stdio.h> 15*b077aed3SPierre Pronchery # include <openssl/rand.h> 16*b077aed3SPierre Pronchery 17*b077aed3SPierre Pronchery /* 18*b077aed3SPierre Pronchery * Maximum allocation size for RANDOM_POOL buffers 19*b077aed3SPierre Pronchery * 20*b077aed3SPierre Pronchery * The max_len value for the buffer provided to the rand_drbg_get_entropy() 21*b077aed3SPierre Pronchery * callback is currently 2^31 bytes (2 gigabytes), if a derivation function 22*b077aed3SPierre Pronchery * is used. Since this is much too large to be allocated, the ossl_rand_pool_new() 23*b077aed3SPierre Pronchery * function chooses more modest values as default pool length, bounded 24*b077aed3SPierre Pronchery * by RAND_POOL_MIN_LENGTH and RAND_POOL_MAX_LENGTH 25*b077aed3SPierre Pronchery * 26*b077aed3SPierre Pronchery * The choice of the RAND_POOL_FACTOR is large enough such that the 27*b077aed3SPierre Pronchery * RAND_POOL can store a random input which has a lousy entropy rate of 28*b077aed3SPierre Pronchery * 8/256 (= 0.03125) bits per byte. This input will be sent through the 29*b077aed3SPierre Pronchery * derivation function which 'compresses' the low quality input into a 30*b077aed3SPierre Pronchery * high quality output. 31*b077aed3SPierre Pronchery * 32*b077aed3SPierre Pronchery * The factor 1.5 below is the pessimistic estimate for the extra amount 33*b077aed3SPierre Pronchery * of entropy required when no get_nonce() callback is defined. 34*b077aed3SPierre Pronchery */ 35*b077aed3SPierre Pronchery # define RAND_POOL_FACTOR 256 36*b077aed3SPierre Pronchery # define RAND_POOL_MAX_LENGTH (RAND_POOL_FACTOR * \ 37*b077aed3SPierre Pronchery 3 * (RAND_DRBG_STRENGTH / 16)) 38*b077aed3SPierre Pronchery /* 39*b077aed3SPierre Pronchery * = (RAND_POOL_FACTOR * \ 40*b077aed3SPierre Pronchery * 1.5 * (RAND_DRBG_STRENGTH / 8)) 41*b077aed3SPierre Pronchery */ 42*b077aed3SPierre Pronchery 43*b077aed3SPierre Pronchery /* 44*b077aed3SPierre Pronchery * Initial allocation minimum. 45*b077aed3SPierre Pronchery * 46*b077aed3SPierre Pronchery * There is a distinction between the secure and normal allocation minimums. 47*b077aed3SPierre Pronchery * Ideally, the secure allocation size should be a power of two. The normal 48*b077aed3SPierre Pronchery * allocation size doesn't have any such restriction. 49*b077aed3SPierre Pronchery * 50*b077aed3SPierre Pronchery * The secure value is based on 128 bits of secure material, which is 16 bytes. 51*b077aed3SPierre Pronchery * Typically, the DRBGs will set a minimum larger than this so optimal 52*b077aed3SPierre Pronchery * allocation ought to take place (for full quality seed material). 53*b077aed3SPierre Pronchery * 54*b077aed3SPierre Pronchery * The normal value has been chosen by noticing that the rand_drbg_get_nonce 55*b077aed3SPierre Pronchery * function is usually the largest of the built in allocation (twenty four 56*b077aed3SPierre Pronchery * bytes and then appending another sixteen bytes). This means the buffer ends 57*b077aed3SPierre Pronchery * with 40 bytes. The value of forty eight is comfortably above this which 58*b077aed3SPierre Pronchery * allows some slack in the platform specific values used. 59*b077aed3SPierre Pronchery */ 60*b077aed3SPierre Pronchery # define RAND_POOL_MIN_ALLOCATION(secure) ((secure) ? 16 : 48) 61*b077aed3SPierre Pronchery 62*b077aed3SPierre Pronchery /* 63*b077aed3SPierre Pronchery * The 'random pool' acts as a dumb container for collecting random 64*b077aed3SPierre Pronchery * input from various entropy sources. It is the callers duty to 1) initialize 65*b077aed3SPierre Pronchery * the random pool, 2) pass it to the polling callbacks, 3) seed the RNG, and 66*b077aed3SPierre Pronchery * 4) cleanup the random pool again. 67*b077aed3SPierre Pronchery * 68*b077aed3SPierre Pronchery * The random pool contains no locking mechanism because its scope and 69*b077aed3SPierre Pronchery * lifetime is intended to be restricted to a single stack frame. 70*b077aed3SPierre Pronchery */ 71*b077aed3SPierre Pronchery typedef struct rand_pool_st { 72*b077aed3SPierre Pronchery unsigned char *buffer; /* points to the beginning of the random pool */ 73*b077aed3SPierre Pronchery size_t len; /* current number of random bytes contained in the pool */ 74*b077aed3SPierre Pronchery 75*b077aed3SPierre Pronchery int attached; /* true pool was attached to existing buffer */ 76*b077aed3SPierre Pronchery int secure; /* 1: allocated on the secure heap, 0: otherwise */ 77*b077aed3SPierre Pronchery 78*b077aed3SPierre Pronchery size_t min_len; /* minimum number of random bytes requested */ 79*b077aed3SPierre Pronchery size_t max_len; /* maximum number of random bytes (allocated buffer size) */ 80*b077aed3SPierre Pronchery size_t alloc_len; /* current number of bytes allocated */ 81*b077aed3SPierre Pronchery size_t entropy; /* current entropy count in bits */ 82*b077aed3SPierre Pronchery size_t entropy_requested; /* requested entropy count in bits */ 83*b077aed3SPierre Pronchery } RAND_POOL; 84*b077aed3SPierre Pronchery 85*b077aed3SPierre Pronchery RAND_POOL *ossl_rand_pool_new(int entropy_requested, int secure, 86*b077aed3SPierre Pronchery size_t min_len, size_t max_len); 87*b077aed3SPierre Pronchery RAND_POOL *ossl_rand_pool_attach(const unsigned char *buffer, size_t len, 88*b077aed3SPierre Pronchery size_t entropy); 89*b077aed3SPierre Pronchery void ossl_rand_pool_free(RAND_POOL *pool); 90*b077aed3SPierre Pronchery 91*b077aed3SPierre Pronchery const unsigned char *ossl_rand_pool_buffer(RAND_POOL *pool); 92*b077aed3SPierre Pronchery unsigned char *ossl_rand_pool_detach(RAND_POOL *pool); 93*b077aed3SPierre Pronchery void ossl_rand_pool_reattach(RAND_POOL *pool, unsigned char *buffer); 94*b077aed3SPierre Pronchery 95*b077aed3SPierre Pronchery size_t ossl_rand_pool_entropy(RAND_POOL *pool); 96*b077aed3SPierre Pronchery size_t ossl_rand_pool_length(RAND_POOL *pool); 97*b077aed3SPierre Pronchery 98*b077aed3SPierre Pronchery size_t ossl_rand_pool_entropy_available(RAND_POOL *pool); 99*b077aed3SPierre Pronchery size_t ossl_rand_pool_entropy_needed(RAND_POOL *pool); 100*b077aed3SPierre Pronchery /* |entropy_factor| expresses how many bits of data contain 1 bit of entropy */ 101*b077aed3SPierre Pronchery size_t ossl_rand_pool_bytes_needed(RAND_POOL *pool, unsigned int entropy_factor); 102*b077aed3SPierre Pronchery size_t ossl_rand_pool_bytes_remaining(RAND_POOL *pool); 103*b077aed3SPierre Pronchery 104*b077aed3SPierre Pronchery int ossl_rand_pool_add(RAND_POOL *pool, 105*b077aed3SPierre Pronchery const unsigned char *buffer, size_t len, size_t entropy); 106*b077aed3SPierre Pronchery unsigned char *ossl_rand_pool_add_begin(RAND_POOL *pool, size_t len); 107*b077aed3SPierre Pronchery int ossl_rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy); 108*b077aed3SPierre Pronchery 109*b077aed3SPierre Pronchery #endif /* OSSL_PROVIDER_RAND_POOL_H */ 110