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