From a73d990e2b6b1a406b1c85837a176bf7525d3914 Mon Sep 17 00:00:00 2001 From: "Dr. Matthias St. Pierre" Date: Tue, 27 Feb 2018 19:02:24 +0100 Subject: [PATCH] Add documentation for the RAND_DRBG API The RAND_DRBG API was added in PR #5462 and modified by PR #5547. This commit adds the corresponding documention. Reviewed-by: Kurt Roeckx Reviewed-by: Rich Salz (Merged from https://github.com/openssl/openssl/pull/5461) --- CHANGES | 4 + INSTALL | 57 ++++- crypto/rand/drbg_lib.c | 157 +++++--------- doc/man3/CRYPTO_get_ex_new_index.pod | 20 +- doc/man3/RAND_DRBG_generate.pod | 88 ++++++++ doc/man3/RAND_DRBG_get0_master.pod | 80 +++++++ doc/man3/RAND_DRBG_new.pod | 127 ++++++++++++ doc/man3/RAND_DRBG_reseed.pod | 111 ++++++++++ doc/man3/RAND_DRBG_set_callbacks.pod | 147 +++++++++++++ doc/man3/RAND_DRBG_set_ex_data.pod | 68 ++++++ doc/man3/RAND_add.pod | 123 +++-------- doc/man3/RAND_bytes.pod | 12 +- doc/man3/RAND_cleanup.pod | 4 + doc/man3/RAND_egd.pod | 4 +- doc/man3/RAND_load_file.pod | 6 +- doc/man3/RAND_set_rand_method.pod | 9 +- doc/man7/RAND.pod | 78 +++++++ doc/man7/RAND_DRBG.pod | 300 +++++++++++++++++++++++++++ include/openssl/rand_drbg.h | 12 +- util/private.num | 6 + 20 files changed, 1173 insertions(+), 240 deletions(-) create mode 100644 doc/man3/RAND_DRBG_generate.pod create mode 100644 doc/man3/RAND_DRBG_get0_master.pod create mode 100644 doc/man3/RAND_DRBG_new.pod create mode 100644 doc/man3/RAND_DRBG_reseed.pod create mode 100644 doc/man3/RAND_DRBG_set_callbacks.pod create mode 100644 doc/man3/RAND_DRBG_set_ex_data.pod create mode 100644 doc/man7/RAND.pod create mode 100644 doc/man7/RAND_DRBG.pod diff --git a/CHANGES b/CHANGES index 462394ca3a..4eaed6fecc 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,10 @@ Changes between 1.1.0g and 1.1.1 [xx XXX xxxx] + *) Added new public header file and documentation + for the RAND_DRBG API. See manual page RAND_DRBG(7) for an overview. + [Matthias St. Pierre] + *) QNX support removed (cannot find contributors to get their approval for the license change). [Rich Salz] diff --git a/INSTALL b/INSTALL index 007f6a38a5..71d6b8883f 100644 --- a/INSTALL +++ b/INSTALL @@ -1,4 +1,3 @@ - OPENSSL INSTALLATION -------------------- @@ -209,12 +208,40 @@ without a path). This flag must be provided if the zlib-dynamic option is not also used. If zlib-dynamic is used then this flag is optional and a default value ("ZLIB1") is - used if not provided. + used if not provided. On VMS: this is the filename of the zlib library (with or without a path). This flag is optional and if not provided then "GNV$LIBZSHR", "GNV$LIBZSHR32" or "GNV$LIBZSHR64" is used by default depending on the pointer size chosen. + + --with-rand-seed=seed1[,seed2,...] + A comma separated list of seeding methods which will be tried + by OpenSSL in order to obtain random input (a.k.a "entropy") + for seeding its cryptographically secure random number + generator (CSPRNG). The current seeding methods are: + + os: Use a trusted operating system entropy source. + This is the default method if such an entropy + source exists. + getrandom: Use the L system call if available. + devrandom: Use the the first device from the DEVRANDOM list + which can be opened to read random bytes. The + DEVRANDOM preprocessor constant expands to + "/dev/urandom","/dev/random","/dev/srandom" on + most unix-ish operating systems. + egd: Check for an entropy generating daemon. + rdcpu: Use the RDSEED or RDRAND command if provided by + the CPU. + librandom: Use librandom (not implemented yet). + none: Disable automatic seeding. This is the default + on some operating systems where no suitable + entropy source exists, or no support for it is + implemented yet. + + For more information, see the section 'Note on random number + generation' at the end of this document. + no-afalgeng Don't build the AFALG engine. This option will be forced if on a platform that does not support AFALG. @@ -810,7 +837,7 @@ $ nmake TESTS='test_rsa test_dsa' test # Windows And of course, you can combine (Unix example shown): - + $ make VERBOSE=1 TESTS='test_rsa test_dsa' test You can find the list of available tests like this: @@ -883,7 +910,7 @@ command symbols. [.SYSTEST] Contains the installation verification procedure. [.HTML] Contains the HTML rendition of the manual pages. - + Additionally, install will add the following directories under OPENSSLDIR (the directory given with --openssldir or its default) @@ -1164,10 +1191,22 @@ Availability of cryptographically secure random numbers is required for secret key generation. OpenSSL provides several options to seed the - internal PRNG. If not properly seeded, the internal PRNG will refuse + internal CSPRNG. If not properly seeded, the internal CSPRNG will refuse to deliver random bytes and a "PRNG not seeded error" will occur. - On systems without /dev/urandom (or similar) device, it may be necessary - to install additional support software to obtain a random seed. - Please check out the manual pages for RAND_add(), RAND_bytes(), RAND_egd(), - and the FAQ for more information. + The seeding method can be configured using the --with-rand-seed option, + which can be used to specify a comma separated list of seed methods. + However in most cases OpenSSL will choose a suitable default method, + so it is not necessary to explicitely provide this option. Note also + that not all methods are available on all platforms. + + I) On operating systems which provide a suitable randomness source (in + form of a system call or system device), OpenSSL will use the optimal + available method to seed the CSPRNG from the operating system's + randomness sources. This corresponds to the option --with-rand-seed=os. + + II) On systems without such a suitable randomness source, automatic seeding + and reseeding is disabled (--with-rand-seed=none) and it may be necessary + to install additional support software to obtain a random seed and reseed + the CSPRNG manually. Please check out the manual pages for RAND_add(), + RAND_bytes(), RAND_egd(), and the FAQ for more information. diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c index 723f6307fd..e1b3ddb57f 100644 --- a/crypto/rand/drbg_lib.c +++ b/crypto/rand/drbg_lib.c @@ -17,8 +17,9 @@ #include "internal/cryptlib_int.h" /* - * Support framework for NIST SP 800-90A DRBG, AES-CTR mode. - * The RAND_DRBG is OpenSSL's pointer to an instance of the DRBG. + * Support framework for NIST SP 800-90A DRBG + * + * See manual page RAND_DRBG(7) for a general overview. * * The OpenSSL model is to have new and free functions, and that new * does all initialization. That is not the NIST model, which has @@ -29,80 +30,46 @@ */ /* - * THE THREE SHARED DRBGs - * - * There are three shared DRBGs (master, public and private), which are - * accessed concurrently by all threads. + * The three shared DRBG instances * - * THE MASTER DRBG + * There are three shared DRBG instances: , , and . + */ + +/* + * The DRBG * * Not used directly by the application, only for reseeding the two other * DRBGs. It reseeds itself by pulling either randomness from os entropy - * sources or by consuming randomnes which was added by RAND_add() - */ -static RAND_DRBG *drbg_master; -/*+ - * DRBG HIERARCHY - * - * In addition there are DRBGs, which are not shared, but used only by a - * single thread at every time, for example the DRBGs which are owned by - * an SSL context. All DRBGs are organized in a hierarchical fashion - * with the DRBG as root. + * sources or by consuming randomness which was added by RAND_add(). * - * This gives the following overall picture: - * - * - * | - * RAND_add() ==> \ - * / \ | shared DRBGs (with locking) - * / - * | - * owned by an SSL context - * - * AUTOMATIC RESEEDING - * - * Before satisfying a generate request, a DRBG reseeds itself automatically, - * if one of the following two conditions holds: - * - * - the number of generate requests since the last reseeding exceeds a - * certain threshold, the so called |reseed_interval|. This behaviour - * can be disabled by setting the |reseed_interval| to 0. - * - * - the time elapsed since the last reseeding exceeds a certain time - * interval, the so called |reseed_time_interval|. This behaviour - * can be disabled by setting the |reseed_time_interval| to 0. - * - * MANUAL RESEEDING + * The DRBG is a global instance which is accessed concurrently by + * all threads. The necessary locking is managed automatically by its child + * DRBG instances during reseeding. + */ +static RAND_DRBG *master_drbg; +/* + * The DRBG * - * For the three shared DRBGs (and only for these) there is another way to - * reseed them manually by calling RAND_seed() (or RAND_add() with a positive - * |randomness| argument). This will immediately reseed the DRBG. - * The and DRBG will detect this on their next generate - * call and reseed, pulling randomness from . + * Used by default for generating random bytes using RAND_bytes(). * - * LOCKING + * The DRBG is thread-local, i.e., there is one instance per thread. + */ +static CRYPTO_THREAD_LOCAL public_drbg; +/* + * The DRBG * - * The three shared DRBGs are intended to be used concurrently, so they - * support locking. The RAND methods take the locks automatically, so using - * the RAND api (in particular RAND_bytes() and RAND_priv_bytes()) is - * thread-safe. Note however that accessing the shared DRBGs directly via - * the RAND_DRBG interface is *not* thread-safe. + * Used by default for generating private keys using RAND_priv_bytes() * - * All other DRBG instances don't support locking, because they are - * intendended to be used by a single thread. Instead of accessing a single - * DRBG instance concurrently from different threads, it is recommended to - * instantiate a separate DRBG instance per thread. Using the same shared - * DRBG (preferrably the public DRBG) as parent of DRBG instances on - * different threads is safe. + * The DRBG is thread-local, i.e., there is one instance per thread. */ +static CRYPTO_THREAD_LOCAL private_drbg; + /* NIST SP 800-90A DRBG recommends the use of a personalization string. */ static const char ossl_pers_string[] = "OpenSSL NIST SP 800-90A DRBG"; static CRYPTO_ONCE rand_drbg_init = CRYPTO_ONCE_STATIC_INIT; -static CRYPTO_THREAD_LOCAL private_drbg_thread_local_key; -static CRYPTO_THREAD_LOCAL public_drbg_thread_local_key; @@ -683,40 +650,10 @@ err: /* * Set the RAND_DRBG callbacks for obtaining entropy and nonce. * - * In the following, the signature and the semantics of the - * get_entropy() and cleanup_entropy() callbacks are explained. - * - * GET_ENTROPY - * - * size_t get_entropy(RAND_DRBG *ctx, - * unsigned char **pout, - * int entropy, - * size_t min_len, size_t max_len); - * - * This is a request to allocate and fill a buffer of size - * |min_len| <= size <= |max_len| (in bytes) which contains - * at least |entropy| bits of randomness. The buffer's address is - * to be returned in |*pout| and the number of collected - * randomness bytes (which may be less than the allocated size - * of the buffer) as return value. + * Setting the callbacks is allowed only if the drbg has not been + * initialized yet. Otherwise, the operation will fail. * - * If the callback fails to acquire at least |entropy| bits of - * randomness, it shall return a buffer length of 0. - * - * CLEANUP_ENTROPY - * - * void cleanup_entropy(RAND_DRBG *ctx, - * unsigned char *out, size_t outlen); - * - * A request to clear and free the buffer allocated by get_entropy(). - * The values |out| and |outlen| are expected to be the random buffer's - * address and length, as returned by the get_entropy() callback. - * - * GET_NONCE, CLEANUP_NONCE - * - * Signature and semantics of the get_nonce() and cleanup_nonce() - * callbacks are analogous to get_entropy() and cleanup_entropy(). - * Currently, the nonce is used only for the known answer tests. + * Returns 1 on success, 0 on failure. */ int RAND_DRBG_set_callbacks(RAND_DRBG *drbg, RAND_DRBG_get_entropy_fn get_entropy, @@ -936,12 +873,12 @@ DEFINE_RUN_ONCE_STATIC(do_rand_drbg_init) ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND); - drbg_master = drbg_setup(NULL); + master_drbg = drbg_setup(NULL); - ret &= CRYPTO_THREAD_init_local(&private_drbg_thread_local_key, NULL); - ret &= CRYPTO_THREAD_init_local(&public_drbg_thread_local_key, NULL); + ret &= CRYPTO_THREAD_init_local(&private_drbg, NULL); + ret &= CRYPTO_THREAD_init_local(&public_drbg, NULL); - if (drbg_master == NULL || ret == 0) + if (master_drbg == NULL || ret == 0) return 0; return 1; @@ -950,21 +887,21 @@ DEFINE_RUN_ONCE_STATIC(do_rand_drbg_init) /* Clean up the global DRBGs before exit */ void rand_drbg_cleanup_int(void) { - RAND_DRBG_free(drbg_master); - drbg_master = NULL; + RAND_DRBG_free(master_drbg); + master_drbg = NULL; - CRYPTO_THREAD_cleanup_local(&private_drbg_thread_local_key); - CRYPTO_THREAD_cleanup_local(&public_drbg_thread_local_key); + CRYPTO_THREAD_cleanup_local(&private_drbg); + CRYPTO_THREAD_cleanup_local(&public_drbg); } void drbg_delete_thread_state() { RAND_DRBG *drbg; - drbg = CRYPTO_THREAD_get_local(&public_drbg_thread_local_key); + drbg = CRYPTO_THREAD_get_local(&public_drbg); RAND_DRBG_free(drbg); - drbg = CRYPTO_THREAD_get_local(&private_drbg_thread_local_key); + drbg = CRYPTO_THREAD_get_local(&private_drbg); RAND_DRBG_free(drbg); } @@ -1044,7 +981,7 @@ RAND_DRBG *RAND_DRBG_get0_master(void) if (!RUN_ONCE(&rand_drbg_init, do_rand_drbg_init)) return NULL; - return drbg_master; + return master_drbg; } /* @@ -1058,11 +995,11 @@ RAND_DRBG *RAND_DRBG_get0_public(void) if (!RUN_ONCE(&rand_drbg_init, do_rand_drbg_init)) return NULL; - drbg = CRYPTO_THREAD_get_local(&public_drbg_thread_local_key); + drbg = CRYPTO_THREAD_get_local(&public_drbg); if (drbg == NULL) { ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND); - drbg = drbg_setup(drbg_master); - CRYPTO_THREAD_set_local(&public_drbg_thread_local_key, drbg); + drbg = drbg_setup(master_drbg); + CRYPTO_THREAD_set_local(&public_drbg, drbg); } return drbg; } @@ -1078,11 +1015,11 @@ RAND_DRBG *RAND_DRBG_get0_private(void) if (!RUN_ONCE(&rand_drbg_init, do_rand_drbg_init)) return NULL; - drbg = CRYPTO_THREAD_get_local(&private_drbg_thread_local_key); + drbg = CRYPTO_THREAD_get_local(&private_drbg); if (drbg == NULL) { ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND); - drbg = drbg_setup(drbg_master); - CRYPTO_THREAD_set_local(&private_drbg_thread_local_key, drbg); + drbg = drbg_setup(master_drbg); + CRYPTO_THREAD_set_local(&private_drbg, drbg); } return drbg; } diff --git a/doc/man3/CRYPTO_get_ex_new_index.pod b/doc/man3/CRYPTO_get_ex_new_index.pod index 1a4ad52de0..4d5a2b93a0 100644 --- a/doc/man3/CRYPTO_get_ex_new_index.pod +++ b/doc/man3/CRYPTO_get_ex_new_index.pod @@ -40,20 +40,22 @@ Several OpenSSL structures can have application-specific data attached to them, known as "exdata." The specific structures are: - SSL - SSL_CTX - SSL_SESSION - X509 - X509_STORE - X509_STORE_CTX + APP + BIO DH + DRBG DSA EC_KEY - RSA ENGINE + RSA + SSL + SSL_CTX + SSL_SESSION UI UI_METHOD - BIO + X509 + X509_STORE + X509_STORE_CTX Each is identified by an B define in the B header file. In addition, B is reserved for @@ -155,7 +157,7 @@ dup_func() should return 0 for failure and 1 for success. =head1 COPYRIGHT -Copyright 2015-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. Licensed under the OpenSSL license (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/RAND_DRBG_generate.pod b/doc/man3/RAND_DRBG_generate.pod new file mode 100644 index 0000000000..b39ee93f51 --- /dev/null +++ b/doc/man3/RAND_DRBG_generate.pod @@ -0,0 +1,88 @@ +=pod + +=head1 NAME + +RAND_DRBG_generate, +RAND_DRBG_bytes +- generate random bytes using the given drbg instance + +=head1 SYNOPSIS + + #include + + int RAND_DRBG_generate(RAND_DRBG *drbg, + unsigned char *out, size_t outlen, + int prediction_resistance, + const unsigned char *adin, size_t adinlen); + + int RAND_DRBG_bytes(RAND_DRBG *drbg, + unsigned char *out, size_t outlen); + + +=head1 DESCRIPTION + +RAND_DRBG_generate() generates B random bytes using the given +DRBG instance B and stores them in the buffer at B. + +Before generating the output, the DRBG instance checks whether the maximum +number of generate requests (I) or the maximum timespan +(I) since its last seeding have been reached. +If this is the case, the DRBG reseeds automatically. +Additionally, an immediate reseeding can be requested by setting the +B flag to 1. See NOTES section for more details. + +The caller can optionally provide additional data to be used for reseeding +by passing a pointer B to a buffer of length B. +This additional data is mixed into the internal state of the random +generator but does not contribute to the entropy count. +The additional data can be omitted by setting B to NULL and +B to 0; + +RAND_DRBG_bytes() generates B random bytes using the given +DRBG instance B and stores them in the buffer at B. +This function is a wrapper around the RAND_DRBG_generate() call, +which collects some additional data from low entropy sources +(e.g., a high resolution timer) and calls +RAND_DRBG_generate(drbg, out, outlen, 0, adin, adinlen). + + +=head1 RETURN VALUES + +RAND_DRBG_generate() and RAND_DRBG_bytes() return 1 on success, +and 0 on failure. + +=head1 NOTES + +The I and I of the B are set to +reasonable default values, which in general do not have to be adjusted. +If necessary, they can be changed using L +and L, respectively. + +A request for prediction resistance can only be satisfied by pulling fresh +entropy from one of the approved entropy sources listed in section 5.5.2 of +[NIST SP 800-90C]. +Since the default DRBG implementation does not have access to such an approved +entropy source, a request for prediction resistance will always fail. +In other words, prediction resistance is currently not supported yet by the DRBG. + +=head1 HISTORY + +The RAND_DRBG functions were added in OpenSSL 1.1.1. + +=head1 SEE ALSO + +L, +L, +L, +L + +=head1 COPYRIGHT + +Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/RAND_DRBG_get0_master.pod b/doc/man3/RAND_DRBG_get0_master.pod new file mode 100644 index 0000000000..c958bf20ec --- /dev/null +++ b/doc/man3/RAND_DRBG_get0_master.pod @@ -0,0 +1,80 @@ +=pod + +=head1 NAME + +RAND_DRBG_get0_master, +RAND_DRBG_get0_public, +RAND_DRBG_get0_private +- get access to the global RAND_DRBG instances + +=head1 SYNOPSIS + + #include + + RAND_DRBG *RAND_DRBG_get0_master(void); + RAND_DRBG *RAND_DRBG_get0_public(void); + RAND_DRBG *RAND_DRBG_get0_private(void); + + +=head1 DESCRIPTION + +The default RAND API implementation (RAND_OpenSSL()) utilizes three +shared DRBG instances which are accessed via the RAND API: + +The and DRBG are thread-local instances, which are used +by RAND_bytes() and RAND_priv_bytes(), respectively. +The DRBG is a global instance, which is not intended to be used +directly, but is used internally to reseed the other two instances. + +These functions here provide access to the shared DRBG instances. + +=head1 RETURN VALUES + +RAND_DRBG_get0_master() returns a pointer to the DRBG instance. + +RAND_DRBG_get0_public() returns a pointer to the DRBG instance. + +RAND_DRBG_get0_private() returns a pointer to the DRBG instance. + + +=head1 NOTES + +It is not thread-safe to access the DRBG instance. +The and DRBG instance can be accessed safely, because +they are thread-local. Note however, that changes to these two instances +apply only to the current thread. + +For that reason it is recommended not to change the settings of these +three instances directly. +Instead, an application should change the default settings for new DRBG instances +at initialization time, before creating additional threads. + +During initialization, it is possible to change the reseed interval +and reseed time interval. +It is also possible to exchange the reseeding callbacks entirely. + + +=head1 HISTORY + +The RAND_DRBG functions were added in OpenSSL 1.1.1. + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L + +=head1 COPYRIGHT + +Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/RAND_DRBG_new.pod b/doc/man3/RAND_DRBG_new.pod new file mode 100644 index 0000000000..dcd7a94419 --- /dev/null +++ b/doc/man3/RAND_DRBG_new.pod @@ -0,0 +1,127 @@ +=pod + +=head1 NAME + +RAND_DRBG_new, +RAND_DRBG_secure_new, +RAND_DRBG_set, +RAND_DRBG_set_defaults, +RAND_DRBG_instantiate, +RAND_DRBG_uninstantiate, +RAND_DRBG_free +- initialize and cleanup a RAND_DRBG instance + +=head1 SYNOPSIS + + #include + + + RAND_DRBG *RAND_DRBG_new(int type, + unsigned int flags, + RAND_DRBG *parent); + + RAND_DRBG *RAND_DRBG_secure_new(int type, + unsigned int flags, + RAND_DRBG *parent); + + int RAND_DRBG_set(RAND_DRBG *drbg, + int type, unsigned int flags); + + int RAND_DRBG_set_defaults(int type, unsigned int flags); + + int RAND_DRBG_instantiate(RAND_DRBG *drbg, + const unsigned char *pers, size_t perslen); + + int RAND_DRBG_uninstantiate(RAND_DRBG *drbg); + + void RAND_DRBG_free(RAND_DRBG *drbg); + + +=head1 DESCRIPTION + +RAND_DRBG_new() and RAND_DRBG_secure_new() +create a new DRBG instance of the given B, allocated from the heap resp. +the secure heap +(using OPENSSL_zalloc() resp. OPENSSL_secure_zalloc()). + +RAND_DRBG_set() initializes the B with the given B and B. + +RAND_DRBG_set_defaults() sets the default B and B for new DRBG +instances. + +Currently, all DRBG types are based on AES-CTR, so B can be one of the +following values: NID_aes_128_ctr, NID_aes_192_ctr, NID_aes_256_ctr. +Before the DRBG can be used to generate random bits, it is necessary to set +its type and to instantiate it. + +The optional B argument specifies a set of bit flags which can be +joined using the | operator. Currently, the only flag is +RAND_DRBG_FLAG_CTR_NO_DF, which disables the use of a the derivation function +ctr_df. For an explanation, see [NIST SP 800-90A Rev. 1]. + +If a B instance is specified then this will be used instead of +the default entropy source for reseeding the B. It is said that the +B is I to its B. +For more information, see the NOTES section. + + +RAND_DRBG_instantiate() +seeds the B instance using random input from trusted entropy sources. +Optionally, a personalization string B of length B can be +specified. +To omit the personalization string, set B=NULL and B=0; + +RAND_DRBG_uninstantiate() +clears the internal state of the B and puts it back in the +uninstantiated state. + +=head1 RETURN VALUES + + +RAND_DRBG_new() and RAND_DRBG_secure_new() return a pointer to a DRBG +instance allocated on the heap, resp. secure heap. + +RAND_DRBG_set(), +RAND_DRBG_instantiate(), and +RAND_DRBG_uninstantiate() +return 1 on success, and 0 on failure. + +RAND_DRBG_free() does not return a value. + +=head1 NOTES + +The DRBG design supports I, which means that a DRBG instance can +use another B DRBG instance instead of the default entropy source +to obtain fresh random input for reseeding, provided that B DRBG +instance was properly instantiated, either from a trusted entropy source, +or from yet another parent DRBG instance. +For a detailed description of the reseeding process, see L. + +The default DRBG type and flags are applied only during creation of a DRBG +instance. +To ensure that they are applied to the global and thread-local DRBG instances +(, resp. and ), it is necessary to call +RAND_DRBG_set_defaults() before creating any thread and before calling any +cryptographic routines that obtain random data directly or indirectly. + +=head1 HISTORY + +The RAND_DRBG functions were added in OpenSSL 1.1.1. + +=head1 SEE ALSO + +L, +L, +L, +L + +=head1 COPYRIGHT + +Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/RAND_DRBG_reseed.pod b/doc/man3/RAND_DRBG_reseed.pod new file mode 100644 index 0000000000..da3a40be44 --- /dev/null +++ b/doc/man3/RAND_DRBG_reseed.pod @@ -0,0 +1,111 @@ +=pod + +=head1 NAME + +RAND_DRBG_reseed, +RAND_DRBG_set_reseed_interval, +RAND_DRBG_set_reseed_time_interval, +RAND_DRBG_set_reseed_defaults +- reseed a RAND_DRBG instance + +=head1 SYNOPSIS + + #include + + int RAND_DRBG_reseed(RAND_DRBG *drbg, + const unsigned char *adin, size_t adinlen); + + int RAND_DRBG_set_reseed_interval(RAND_DRBG *drbg, + unsigned int interval); + + int RAND_DRBG_set_reseed_time_interval(RAND_DRBG *drbg, + time_t interval); + + int RAND_DRBG_set_reseed_defaults( + unsigned int master_reseed_interval, + unsigned int slave_reseed_interval, + time_t master_reseed_time_interval, + time_t slave_reseed_time_interval + ); + + +=head1 DESCRIPTION + +RAND_DRBG_reseed() +reseeds the given B, obtaining entropy input from its entropy source +and mixing in the specified additional data provided in the buffer B +of length B. +The additional data can be omitted by setting B to NULL and B +to 0. + +RAND_DRBG_set_reseed_interval() +sets the reseed interval of the B, which is the maximum allowed number +of generate requests between consecutive reseedings. +If B > 0, then the B will reseed automatically whenever the +number of generate requests since its last seeding exceeds the given reseed +interval. +If B == 0, then this feature is disabled. + + +RAND_DRBG_set_reseed_time_interval() +sets the reseed time interval of the B, which is the maximum allowed +number of seconds between consecutive reseedings. +If B > 0, then the B will reseed automatically whenever the +elapsed time since its last reseeding exceeds the given reseed time interval. +If B == 0, then this feature is disabled. + +RAND_DRBG_set_reseed_defaults() sets the default values for the reseed interval +(B and B) +and the reseed time interval +(B and B) +of DRBG instances. +The default values are set independently for master DRBG instances (which don't +have a parent) and slave DRBG instances (which are chained to a parent DRBG). + +=head1 RETURN VALUES + +RAND_DRBG_reseed(), +RAND_DRBG_set_reseed_interval(), and +RAND_DRBG_set_reseed_time_interval(), +return 1 on success, 0 on failure. + + +=head1 NOTES + +The default OpenSSL random generator is already set up for automatic reseeding, +so in general it is not necessary to reseed it explicitly, or to modify +its reseeding thresholds. + +Normally, the entropy input for seeding a DRBG is either obtained from a +trusted os entropy source or from a parent DRBG instance, which was seeded +(directly or indirectly) from a trusted os entropy source. +In exceptional cases it is possible to replace the reseeding mechanism entirely +by providing application defined callbacks using RAND_DRBG_set_callbacks(). + +The reseeding default values are applied only during creation of a DRBG instance. +To ensure that they are applied to the global and thread-local DRBG instances +(, resp. and ), it is necessary to call +RAND_DRBG_set_reseed_defaults() before creating any thread and before calling any + cryptographic routines that obtain random data directly or indirectly. + +=head1 HISTORY + +The RAND_DRBG functions were added in OpenSSL 1.1.1. + +=head1 SEE ALSO + +L, +L, +L. +L + +=head1 COPYRIGHT + +Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/RAND_DRBG_set_callbacks.pod b/doc/man3/RAND_DRBG_set_callbacks.pod new file mode 100644 index 0000000000..3e9a98585e --- /dev/null +++ b/doc/man3/RAND_DRBG_set_callbacks.pod @@ -0,0 +1,147 @@ +=pod + +=head1 NAME + +RAND_DRBG_set_callbacks, +RAND_DRBG_get_entropy_fn, +RAND_DRBG_cleanup_entropy_fn, +RAND_DRBG_get_nonce_fn, +RAND_DRBG_cleanup_nonce_fn +- set callbacks for reseeding + +=head1 SYNOPSIS + + #include + + + int RAND_DRBG_set_callbacks(RAND_DRBG *drbg, + RAND_DRBG_get_entropy_fn get_entropy, + RAND_DRBG_cleanup_entropy_fn cleanup_entropy, + RAND_DRBG_get_nonce_fn get_nonce, + RAND_DRBG_cleanup_nonce_fn cleanup_nonce); + + +=head2 Callback Functions + + typedef size_t (*RAND_DRBG_get_entropy_fn)( + RAND_DRBG *drbg, + unsigned char **pout, + int entropy, + size_t min_len, size_t max_len, + int prediction_resistance); + + typedef void (*RAND_DRBG_cleanup_entropy_fn)( + RAND_DRBG *drbg, + unsigned char *out, size_t outlen); + + typedef size_t (*RAND_DRBG_get_nonce_fn)( + RAND_DRBG *drbg, + unsigned char **pout, + int entropy, + size_t min_len, size_t max_len); + + typedef void (*RAND_DRBG_cleanup_nonce_fn)( + RAND_DRBG *drbg, + unsigned char *out, size_t outlen); + + + +=head1 DESCRIPTION + +RAND_DRBG_set_callbacks() sets the callbacks for obtaining fresh entropy and +the nonce when reseeding the given B. +The callback functions are implemented and provided by the caller. +Their parameter lists need to match the function prototypes above. + +Setting the callbacks is allowed only if the DRBG has not been initialized yet. +Otherwise, the operation will fail. +To change the settings for one of the three shared DRBGs it is necessary to call +RAND_DRBG_uninstantiate() first. + +The B() callback is called by the B when it requests fresh +random input. +It is expected that the callback allocates and fills a random buffer of size +B <= size <= B (in bytes) which contains at least B +bits of randomness. +The B flag indicates whether the reseeding was +triggered by a prediction resistance request. + +The buffer's address is to be returned in *B and the number of collected +randomness bytes as return value. + +If the callback fails to acquire at least B bits of randomness, +it must indicate an error by returning a buffer length of 0. + +If B was requested and the random source of the DRBG +does not satisfy the conditions requested by [NIST SP 800-90C], then +it must also indicate an error by returning a buffer length of 0. +See NOTES section for more details. + +The B() callback is called from the B to to clear and +free the buffer allocated previously by get_entropy(). +The values B and B are the random buffer's address and length, +as returned by the get_entropy() callback. + +The B() and B() callbacks are used to obtain a nonce +and free it again. A nonce is only required for instantiation (not for reseeding) +and only in the case where the DRBG uses a derivation function. +The callbacks are analogous to get_entropy() and cleanup_entropy(), +except for the missing prediction_resistance flag. + +If the derivation function is disabled, then no nonce is used for instantiation, +and the B() and B() callbacks can be omitted by +setting them to NULL. + + +=head1 RETURN VALUES + +RAND_DRBG_set_callbacks() return 1 on success, and 0 on failure + +=head1 NOTES + +It is important that B() and B() clear the buffer +contents safely before freeing it, in order not to leave sensitive information +about the DRBG's state in memory. + +A request for prediction resistance can only be satisfied by pulling fresh +entropy from one of the approved entropy sources listed in section 5.5.2 of +[NIST SP 800-90C]. +Since the default implementation of the get_entropy callback does not have access +to such an approved entropy source, a request for prediction resistance will +always fail. +In other words, prediction resistance is currently not supported yet by the DRBG. + +The derivation function is disabled during initialization by calling the +RAND_DRBG_set() function with the RAND_DRBG_FLAG_CTR_NO_DF flag. +For more information on the derivation function and when it can be omitted, +see [NIST SP 800-90A Rev. 1]. Roughly speeking it can be omitted if the random +source has "full entropy", i.e., contains 8 bits of entropy per byte. + +Even if a nonce is required, the B() and B() +callbacks can be omitted by setting them to NULL. +In this case the DRBG will automatically request an extra amount of entropy +(using the B() and B() callbacks) which it will +utilize for the nonce, following the recommendations of [NIST SP 800-90A Rev. 1], +section 8.6.7. + + +=head1 HISTORY + +The RAND_DRBG functions were added in OpenSSL 1.1.1. + +=head1 SEE ALSO + +L, +L, +L + +=head1 COPYRIGHT + +Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/RAND_DRBG_set_ex_data.pod b/doc/man3/RAND_DRBG_set_ex_data.pod new file mode 100644 index 0000000000..22b7332571 --- /dev/null +++ b/doc/man3/RAND_DRBG_set_ex_data.pod @@ -0,0 +1,68 @@ +=pod + +=head1 NAME + +RAND_DRBG_set_ex_data, +RAND_DRBG_get_ex_data, +RAND_DRBG_get_ex_new_index +- store and retrieve extra data from the DRBG instance + +=head1 SYNOPSIS + + #include + + int RAND_DRBG_set_ex_data(RAND_DRBG *drbg, int idx, void *data); + + void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx); + + int RAND_DRBG_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); + + + +=head1 DESCRIPTION + +RAND_DRBG_set_ex_data() enables an application to store arbitrary application +specific data B in a RAND_DRBG instance B. The index B should +be a value previously returned from a call to RAND_DRBG_get_ex_new_index(). + +RAND_DRBG_get_ex_data() retrieves application specific data previously stored +in an RAND_DRBG instance B. The B value should be the same as that +used when originally storing the data. + +For more detailed information see L and +L which implement these functions and +L for generating a unique index. + +=head1 RETURN VALUES + +RAND_DRBG_set_ex_data() returns 1 for success or 0 for failure. + +RAND_DRBG_get_ex_data() returns the previously stored value or NULL on +failure. NULL may also be a valid value. + + +=head1 NOTES + +RAND_DRBG_get_ex_new_index(...) is implemented as a macro and equivalent to +CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DRBG,...). + +=head1 SEE ALSO + +L, +L, +L, +L + +=head1 COPYRIGHT + +Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/RAND_add.pod b/doc/man3/RAND_add.pod index 62048e6792..1b06d1be87 100644 --- a/doc/man3/RAND_add.pod +++ b/doc/man3/RAND_add.pod @@ -24,43 +24,42 @@ Deprecated: =head1 DESCRIPTION -Random numbers are a vital part of cryptography, including key generation, -creating salts, etc., and software-based -generators must be "seeded" with external randomness before they can be -used as a cryptographically-secure pseudo-random number generator (CSPRNG). -The availability of common hardware with special instructions and -modern operating systems, which may use items such as interrupt jitter -and network packet timings, can be reasonable sources of seeding material. - -RAND_status() indicates whether or not the CSPRNG has been sufficiently -seeded. If not, functions such as RAND_bytes(3) will fail. - -RAND_poll() uses the system's capabilities to seed the CSPRNG using +These functions can be used to seed the random generator and to check its +seeded state. +In general, manual (re-)seeding of the default OpenSSL random generator +(L) is not necessary (but allowed), since it does (re-)seed +itself automatically using trusted system entropy sources. +This holds unless the default RAND_METHOD has been replaced or OpenSSL was +built with automatic reseeding disabled, see L for more details. + +RAND_status() indicates whether or not the random generator has been sufficiently +seeded. If not, functions such as L will fail. + +RAND_poll() uses the system's capabilities to seed the random generator using random input obtained from polling various trusted entropy sources. -The default choice of the entropy source can be modified at build time -using the --with-rand-seed configure option, see also the B section. -A summary of the configure options can be displayed with the OpenSSL -L command. +The default choice of the entropy source can be modified at build time, +see L for more details. -RAND_add() mixes the B bytes at B into the PRNG state. +RAND_add() mixes the B bytes at B into the internal state +of the random generator. +This function will not normally be needed, as mentioned above. The B argument is an estimate of how much randomness is contained in B, in bytes, and should be a number between zero and B. Details about sources of randomness and how to estimate their randomness -can be found in the literature; for example NIST SP 800-90B. -The content of B cannot be recovered from subsequent CSPRNG output. -This function will not normally be needed, as RAND_poll() should have been -configured to do the appropriate seeding for the local platform. -Applications that need to keep random state in an external file should -use L. +can be found in the literature; for example [NIST SP 800-90B]. +The content of B cannot be recovered from subsequent random generator output. +Applications that intend to save and restore random state in an external file +should consider using L instead. RAND_seed() is equivalent to RAND_add() with B set to B. -RAND_event() and RAND_screen() are equivalent to RAND_poll(). +RAND_event() and RAND_screen() are equivalent to RAND_poll() and exist +for compatibility reasons only. See HISTORY section below. =head1 RETURN VALUES -RAND_status() returns 1 if the CSPRNG has been seeded +RAND_status() returns 1 if the random generator has been seeded with enough data, 0 otherwise. RAND_poll() returns 1 if it generated seed data, 0 otherwise. @@ -69,72 +68,6 @@ RAND_event() returns RAND_status(). The other functions do not return values. -=head1 NOTES - -The new OpenSSL DRBG has some peculiarities which need to be taken -into account when it is selected as the default OpenSSL CSPRNG, i.e., -when RAND_get_rand_method() == RAND_OpenSSL(). -This applies in particular to the way reseeding is done by the DRBG: - -=over 2 - -=item * - -The DRBG seeds itself automatically, pulling random input from trusted -entropy sources. -Automatic reseeding occurs after a predefined number of generate requests. -The selection of the trusted entropy sources is configured at build -time using the --with-rand-seed option. - -=item * - -The DRBG distinguishes two different types of random input: -'entropy', which comes from a trusted source, and 'additional input', -which can optionally be added by the user and is considered untrusted. - -=back - -Automatic seeding can be disabled using the --with-rand-seed=none option. - -=head2 DRBG with automatic seeding enabled - -Calling RAND_poll() or RAND_add() is not necessary, because the DRBG -polls the entropy source automatically. -However, both calls are permitted, and do reseed the RNG. - -RAND_add() can be used to add both kinds of random input, depending on the -value of the B argument: - -=over 4 - -=item randomness == 0: - -The random bytes are mixed as additional input into the current state of -the DRBG. -Mixing in additional input is not considered a full reseeding, hence the -reseed counter is not reset. - - -=item randomness > 0: - -The random bytes are used as entropy input for a full reseeding -(resp. reinstantiation) if the DRBG is instantiated -(resp. uninstantiated or in an error state). -A reseeding requires 16 bytes (128 bits) of randomness. -It is possible to provide less randomness than required. -In this case the missing randomness will be obtained by pulling random input -from the trusted entropy sources. - -=back - -=head2 DRBG with automatic seeding disabled (--with-rand-seed=none) - -Calling RAND_poll() will always fail. - -RAND_add() needs to be called for initial seeding and periodic reseeding. -At least 16 bytes (128 bits) of randomness have to be provided, otherwise -the (re-)seeding of the DRBG will fail. - =head1 HISTORY RAND_event() and RAND_screen() were deprecated in OpenSSL 1.1.0 and should @@ -142,12 +75,14 @@ not be used. =head1 SEE ALSO -L, L, -L +L, +L, +L, +L =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. Licensed under the OpenSSL license (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/RAND_bytes.pod b/doc/man3/RAND_bytes.pod index c3e6aef310..284b9dbe4d 100644 --- a/doc/man3/RAND_bytes.pod +++ b/doc/man3/RAND_bytes.pod @@ -20,7 +20,7 @@ Deprecated: =head1 DESCRIPTION RAND_bytes() puts B cryptographically strong pseudo-random bytes -into B. An error occurs if the PRNG has not been seeded with +into B. An error occurs if the CSPRNG has not been seeded with enough randomness to ensure an unpredictable byte sequence. RAND_priv_bytes() has the same semantics as RAND_bytes(). It is intended to @@ -30,7 +30,7 @@ a compromise of the global generator will not affect such key generation. =head1 RETURN VALUES -RAND_bytes() nad RAND_priv_bytes() +RAND_bytes() and RAND_priv_bytes() return 1 on success, -1 if not supported by the current RAND method, or 0 on other failure. The error code can be obtained by L. @@ -41,12 +41,14 @@ RAND_pseudo_bytes() was deprecated in OpenSSL 1.1.0; use RAND_bytes() instead. =head1 SEE ALSO -L, L, -L +L, +L, +L, +L =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. Licensed under the OpenSSL license (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/RAND_cleanup.pod b/doc/man3/RAND_cleanup.pod index 03a0798f68..3859ce343a 100644 --- a/doc/man3/RAND_cleanup.pod +++ b/doc/man3/RAND_cleanup.pod @@ -28,6 +28,10 @@ RAND_cleanup() returns no value. RAND_cleanup() was deprecated in OpenSSL 1.1.0; do not use it. See L +=head1 SEE ALSO + +L + =head1 COPYRIGHT Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/RAND_egd.pod b/doc/man3/RAND_egd.pod index ebbaf30335..2b975ebd6a 100644 --- a/doc/man3/RAND_egd.pod +++ b/doc/man3/RAND_egd.pod @@ -45,7 +45,9 @@ success, or -1 if the connection failed. =head1 SEE ALSO -L, L +L, +L, +L =head1 COPYRIGHT diff --git a/doc/man3/RAND_load_file.pod b/doc/man3/RAND_load_file.pod index 489ff2d7f1..24f8fdcf4f 100644 --- a/doc/man3/RAND_load_file.pod +++ b/doc/man3/RAND_load_file.pod @@ -71,11 +71,13 @@ error. =head1 SEE ALSO -L, L +L, +L, +L =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. Licensed under the OpenSSL license (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/RAND_set_rand_method.pod b/doc/man3/RAND_set_rand_method.pod index 70c1b23cd7..d4b65b91fd 100644 --- a/doc/man3/RAND_set_rand_method.pod +++ b/doc/man3/RAND_set_rand_method.pod @@ -19,8 +19,7 @@ RAND_set_rand_method, RAND_get_rand_method, RAND_OpenSSL - select RAND method A B specifies the functions that OpenSSL uses for random number generation. -Initially, the default B is the OpenSSL internal implementation, -as returned by RAND_OpenSSL(). +RAND_OpenSSL() returns the default B implementation by OpenSSL. This implementation ensures that the PRNG state is unique for each thread. If an B is loaded that provides the RAND API, however, it will @@ -54,11 +53,13 @@ RAND_OpenSSL() return pointers to the respective methods. =head1 SEE ALSO -L, L +L, +L, +L =head1 COPYRIGHT -Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. Licensed under the OpenSSL license (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/RAND.pod b/doc/man7/RAND.pod new file mode 100644 index 0000000000..6ec7548972 --- /dev/null +++ b/doc/man7/RAND.pod @@ -0,0 +1,78 @@ +=pod + +=head1 NAME + +RAND +- the OpenSSL random generator + +=head1 DESCRIPTION + +Random numbers are a vital part of cryptography, they are needed to provide +unpredictability for tasks like key generation, creating salts, and many more. +Software-based generators must be seeded with external randomness before they +can be used as a cryptographically-secure pseudo-random number generator +(CSPRNG). +The availability of common hardware with special instructions and +modern operating systems, which may use items such as interrupt jitter +and network packet timings, can be reasonable sources of seeding material. + +OpenSSL comes with a default implementation of the RAND API which is based on +the deterministic random bit generator (DRBG) model as described in +[NIST SP 800-90A Rev. 1]. The default random generator will initialize +automatically on first use and will be fully functional without having +to be initialized ('seeded') explicitly. +It seeds and reseeds itself automatically using trusted random sources +provided by the operating system. + +As a normal application developer, you don't have to worry about any details, +just use L to obtain random data. +Having said that, there is one important rule to obey: Always check the error +return value of L and don't take randomness for granted. + +For long-term secrets, you can use L instead. +This method does not provide 'better' randomness, it uses the same type of CSPRNG. +The intention behind using a dedicated CSPRNG exclusively for long-term secrets is +that none of its output should be visible to an attacker (e.g used as salt value), +in order to reveal as little information as possible about its internal state. + +In the rare case where the default implementation does not satisfy your special +requirements, there are two options: + +=over 2 + +=item * + +Replace the default RAND method by your own RAND method using +L. + +=item * + +Modify the default settings of the OpenSSL RAND method by modifying the security +parameters of the underlying DRBG, which is described in detail in L. + +=back + +Changing the default random generator or its default parameters should be necessary +only in exceptional cases and is not recommended, unless you have a profound knowledge +of cryptographic principles and understand the implications of your changes. + +=head1 SEE ALSO + +L, +L, +L, +L +L +L, +L, + +=head1 COPYRIGHT + +Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/RAND_DRBG.pod b/doc/man7/RAND_DRBG.pod new file mode 100644 index 0000000000..a4c58c1889 --- /dev/null +++ b/doc/man7/RAND_DRBG.pod @@ -0,0 +1,300 @@ +=pod + +=head1 NAME + +RAND_DRBG - the deterministic random bit generator + +=head1 SYNOPSIS + + #include + +=head1 DESCRIPTION + +The default OpenSSL RAND method is based on the RAND_DRBG class, +which implements a deterministic random bit generator (DRBG). +A DRBG is a certain type of cryptographically-secure pseudo-random +number generator (CSPRNG), which is described in +[NIST SP 800-90A Rev. 1]. + +While the RAND API is the 'frontend' which is intended to be used by +application developers for obtaining random bytes, the RAND_DRBG API +serves as the 'backend', connecting the former with the operating +systems's entropy sources and providing access to the DRBG's +configuration parameters. + +=head2 Disclaimer + +Unless you have very specific requirements for your random generator, +it is in general not necessary to utilize the RAND_DRBG API directly. +The usual way to obtain random bytes is to use L or +L, see also L. + +=head2 Typical Use Cases + +Typical examples for such special use cases are the following: + +=over 2 + +=item * + +You want to use your own private DRBG instances, similar to how it +is currently done in the ssl library. +Multiple DRBG instances which are accessed only by a single thread provide +additional security (because their internal states are independent) and +better scalability in multithreaded applications (because they don't need +to be locked). + +=item * + +You need to integrate a previously unsupported entropy source. + +=item * + +You need to change the default settings of the standard OpenSSL RAND +implementation to meet specific requirements. + +=back + + +=head1 CHAINING + +A DRBG instance can be used as the entropy source of another DRBG instance, +provided it has itself access to a valid entropy source. +The DRBG instance which acts as entropy source is called the I DRBG, +the other instance the I DRBG. + +This is called chaining. A chained DRBG instance is created by passing +a pointer to the parent DRBG as argument to the RAND_DRBG_new() call. +It is possible to create chains of more than two DRBG in a row. + +=head1 THE THREE SHARED DRBG INSTANCES + +Currently, there are three shared DRBG instances, +the , , and DRBG. +While the DRBG is a single global instance, the and +DRBG are created per thread and accessed through thread-local storage. + +By default, the functions L and L use +the thread-local and DRBG instance, respectively. + +=head2 The DRBG instance + +The DRBG is not used directly by the application, only for reseeding +the two other two DRBG instances. It reseeds itself by obtaining randomness +either from os entropy sources or by consuming randomness which was added +previously by L. + +=head2 The DRBG instance + +This instance is used per default by L. + +=head2 The DRBG instance + +This instance is used per default by L + + +=head1 LOCKING + +The DRBG is intended to be accessed concurrently for reseeding +by its child DRBG instances. The necessary locking is done internally. +It is I thread-safe to access the DRBG directly via the +RAND_DRBG interface. +The and DRBG are thread-local, i.e. there is an +instance of each per thread. So they can safely be accessed without +locking via the RAND_DRBG interface. + +Pointers to these DRBG instances can be obtained using +RAND_DRBG_get0_master(), +RAND_DRBG_get0_public(), and +RAND_DRBG_get0_private(), respectively. +Note that it is not allowed to store a pointer to one of the thread-local +DRBG instances in a variable or other memory location where it will be +accessed and used by multiple threads. + +All other DRBG instances created by an application don't support locking, +because they are intended to be used by a single thread. +Instead of accessing a single DRBG instance concurrently from different +threads, it is recommended to instantiate a separate DRBG instance per +thread. Using the DRBG as entropy source for multiple DRBG +instances on different threads is thread-safe, because the DRBG instance +will lock the DRBG automatically for obtaining random input. + +=head1 THE OVERALL PICTURE + +The following picture gives an overview over how the DRBG instances work +together and are being used. + + +--------------------+ + | os entropy sources | + +--------------------+ + | + v +-----------------------------+ + RAND_add() ==> <-| shared DRBG (with locking) | + / \ +-----------------------------+ + / \ +---------------------------+ + <- | per-thread DRBG instances | + | | +---------------------------+ + v v + RAND_bytes() RAND_priv_bytes() + | ^ + | | + +------------------+ +------------------------------------+ + | general purpose | | used for secrets like session keys | + | random generator | | and private keys for certificates | + +------------------+ +------------------------------------+ + + + +The method L is a convenience method wrapping the +L function, which serves the actual request for +random data. + +=head1 RESEEDING + +A DRBG instance seeds itself automatically, pulling random input from +its entropy source. The entropy source can be either a trusted operating +system entropy source, or another DRBG with access to such a source. + +Automatic reseeding occurs after a predefined number of generate requests. +The selection of the trusted entropy sources is configured at build +time using the --with-rand-seed option. The following sections explain +the reseeding process in more detail. + +=head2 Automatic Reseeding + +Before satisfying a generate request (L), the DRBG +reseeds itself automatically, if one of the following conditions holds: + +- the DRBG was not instantiated (=seeded) yet or has been uninstantiated. + +- the number of generate requests since the last reseeding exceeds a +certain threshold, the so called I. +This behaviour can be disabled by setting the I to 0. + +- the time elapsed since the last reseeding exceeds a certain time +interval, the so called I. +This can be disabled by setting the I to 0. + +- the DRBG is in an error state. + +B: An error state is entered if the entropy source fails while +the DRBG is seeding or reseeding. +The last case ensures that the DRBG automatically recovers +from the error as soon as the entropy source is available again. + +=head2 Manual Reseeding + +In addition to automatic reseeding, the caller can request an immediate +reseeding of the DRBG with fresh entropy by setting the +I parameter to 1 when calling L. + +The dcoument [NIST SP 800-90C] describes prediction resistance requests +in detail and imposes strict conditions on the entropy sources that are +approved for providing prediction resistance. +Since the default DRBG implementation does not have access to such an approved +entropy source, a request for prediction resistance will currently always fail. +In other words, prediction resistance is currently not supported yet by the DRBG. + + +For the three shared DRBGs (and only for these) there is another way to +reseed them manually: +If L is called with a positive I argument +(or L), then this will immediately reseed the DRBG. +The and DRBG will detect this on their next generate +call and reseed, pulling randomness from . + +The last feature has been added to support the common practice used with +previous OpenSSL versions to call RAND_add() before calling RAND_bytes(). + + +=head2 Entropy Input vs. Additional Data + +The DRBG distinguishes two different types of random input: I, +which comes from a trusted source, and I', +which can optionally be added by the user and is considered untrusted. +It is possible to add I not only during reseeding, +but also for every generate request. +This is in fact done automatically by L. + + +=head2 Configuring the Random Seed Source + +In most cases OpenSSL will automatically choose a suitable seed source +for automatically seeding and reseeding its DRBG. In some cases +however, it will be necessary to explicitely specify a seed source during +configuration, using the --with-rand-seed option. For more information, +see the INSTALL instructions. There are also operating systems where no +seed source is available and automatic reseeding is disabled by default. + +The following two sections describe the reseeding process of the master +DRBG, depending on whether automatic reseeding is available or not. + + +=head2 Reseeding the master DRBG with automatic seeding enabled + +Calling RAND_poll() or RAND_add() is not necessary, because the DRBG +pulls the necessary entropy from its source automatically. +However, both calls are permitted, and do reseed the RNG. + +RAND_add() can be used to add both kinds of random input, depending on the +value of the B argument: + +=over 4 + +=item randomness == 0: + +The random bytes are mixed as additional input into the current state of +the DRBG. +Mixing in additional input is not considered a full reseeding, hence the +reseed counter is not reset. + + +=item randomness > 0: + +The random bytes are used as entropy input for a full reseeding +(resp. reinstantiation) if the DRBG is instantiated +(resp. uninstantiated or in an error state). +The number of random bits required for reseeding is determined by the +security strength of the DRBG. Currently it defaults to 256 bits (32 bytes). +It is possible to provide less randomness than required. +In this case the missing randomness will be obtained by pulling random input +from the trusted entropy sources. + +=back + +=head2 Reseeding the master DRBG with automatic seeding disabled + +Calling RAND_poll() will always fail. + +RAND_add() needs to be called for initial seeding and periodic reseeding. +At least 48 bytes (384 bits) of randomness have to be provided, otherwise +the (re-)seeding of the DRBG will fail. This corresponds to one and a half +times the security strength of the DRBG. The extra half is used for the +nonce during instantiation. + +More precisely, the number of bytes needed for seeding depend on the +I of the DRBG, which is set to 256 by default. + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L, +L, +L, +L, + +=head1 COPYRIGHT + +Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/include/openssl/rand_drbg.h b/include/openssl/rand_drbg.h index 790dca5e88..282356e161 100644 --- a/include/openssl/rand_drbg.h +++ b/include/openssl/rand_drbg.h @@ -87,26 +87,26 @@ RAND_DRBG *RAND_DRBG_get0_private(void); */ # define RAND_DRBG_get_ex_new_index(l, p, newf, dupf, freef) \ CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DRBG, l, p, newf, dupf, freef) -int RAND_DRBG_set_ex_data(RAND_DRBG *dctx, int idx, void *arg); -void *RAND_DRBG_get_ex_data(const RAND_DRBG *dctx, int idx); +int RAND_DRBG_set_ex_data(RAND_DRBG *drbg, int idx, void *arg); +void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx); /* * Callback function typedefs */ -typedef size_t (*RAND_DRBG_get_entropy_fn)(RAND_DRBG *ctx, +typedef size_t (*RAND_DRBG_get_entropy_fn)(RAND_DRBG *drbg, unsigned char **pout, int entropy, size_t min_len, size_t max_len, int prediction_resistance); typedef void (*RAND_DRBG_cleanup_entropy_fn)(RAND_DRBG *ctx, unsigned char *out, size_t outlen); -typedef size_t (*RAND_DRBG_get_nonce_fn)(RAND_DRBG *ctx, unsigned char **pout, +typedef size_t (*RAND_DRBG_get_nonce_fn)(RAND_DRBG *drbg, unsigned char **pout, int entropy, size_t min_len, size_t max_len); -typedef void (*RAND_DRBG_cleanup_nonce_fn)(RAND_DRBG *ctx, +typedef void (*RAND_DRBG_cleanup_nonce_fn)(RAND_DRBG *drbg, unsigned char *out, size_t outlen); -int RAND_DRBG_set_callbacks(RAND_DRBG *dctx, +int RAND_DRBG_set_callbacks(RAND_DRBG *drbg, RAND_DRBG_get_entropy_fn get_entropy, RAND_DRBG_cleanup_entropy_fn cleanup_entropy, RAND_DRBG_get_nonce_fn get_nonce, diff --git a/util/private.num b/util/private.num index 90de967a3c..706da8041e 100644 --- a/util/private.num +++ b/util/private.num @@ -43,6 +43,11 @@ OSSL_STORE_open_fn datatype OSSL_STORE_post_process_info_fn datatype PROFESSION_INFO datatype PROFESSION_INFOS datatype +RAND_DRBG_cleanup_entropy_fn datatype +RAND_DRBG_cleanup_nonce_fn datatype +RAND_DRBG_get_entropy_fn datatype +RAND_DRBG_get_nonce_fn datatype +RAND_poll_cb datatype SSL_CTX_keylog_cb_func datatype SSL_client_hello_cb_fn datatype SSL_psk_client_cb_func datatype @@ -246,6 +251,7 @@ PEM_FLAG_EAY_COMPATIBLE define PEM_FLAG_ONLY_B64 define PEM_FLAG_SECURE define RAND_cleanup define deprecated 1.1.0 +RAND_DRBG_get_ex_new_index define EVP_PKEY_CTX_set_rsa_keygen_bits define SSL_COMP_free_compression_methods define deprecated 1.1.0 SSL_CTX_add0_chain_cert define -- 2.25.1