summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/doc/api_ref/rng.rst
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/botan/doc/api_ref/rng.rst')
-rw-r--r--comm/third_party/botan/doc/api_ref/rng.rst281
1 files changed, 281 insertions, 0 deletions
diff --git a/comm/third_party/botan/doc/api_ref/rng.rst b/comm/third_party/botan/doc/api_ref/rng.rst
new file mode 100644
index 0000000000..01c27f73cf
--- /dev/null
+++ b/comm/third_party/botan/doc/api_ref/rng.rst
@@ -0,0 +1,281 @@
+.. _random_number_generators:
+
+Random Number Generators
+========================================
+
+.. cpp:class:: RandomNumberGenerator
+
+ The base class for all RNG objects, is declared in ``rng.h``.
+
+ .. cpp:function:: void randomize(uint8_t* output_array, size_t length)
+
+ Places *length* random bytes into the provided buffer.
+
+ .. cpp:function:: void randomize_with_input(uint8_t* data, size_t length, \
+ const uint8_t* extra_input, size_t extra_input_len)
+
+ Like randomize, but first incorporates the additional input field into the
+ state of the RNG. The additional input could be anything which
+ parameterizes this request. Not all RNG types accept additional inputs,
+ the value will be silently ignored when not supported.
+
+ .. cpp:function:: void randomize_with_ts_input(uint8_t* data, size_t length)
+
+ Creates a buffer with some timestamp values and calls ``randomize_with_input``
+
+ .. note::
+
+ When RDRAND is enabled and available at runtime, instead of timestamps
+ the output of RDRAND is used as the additional data.
+
+ .. cpp:function:: uint8_t next_byte()
+
+ Generates a single random byte and returns it. Note that calling this
+ function several times is much slower than calling ``randomize`` once to
+ produce multiple bytes at a time.
+
+ .. cpp:function:: void add_entropy(const uint8_t* data, size_t length)
+
+ Incorporates provided data into the state of the PRNG, if at all possible.
+ This works for most RNG types, including the system and TPM RNGs. But if
+ the RNG doesn't support this operation, the data is dropped, no error is
+ indicated.
+
+ .. cpp:function:: bool accepts_input() const
+
+ This function returns ``false`` if it is known that this RNG object cannot
+ accept external inputs. In this case, any calls to
+ :cpp:func:`RandomNumberGenerator::add_entropy` will be ignored.
+
+ .. cpp:function:: void reseed_from_rng(RandomNumberGenerator& rng, \
+ size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS)
+
+ Reseed by calling ``rng`` to acquire ``poll_bits`` data.
+
+
+RNG Types
+----------------------------------------
+
+Several different RNG types are implemented. Some access hardware RNGs, which
+are only available on certain platforms. Others are mostly useful in specific
+situations.
+
+Generally prefer using the system RNG, or if not available use ``AutoSeeded_RNG``
+which is intended to provide best possible behavior in a userspace PRNG.
+
+System_RNG
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+On systems which support it, in ``system_rng.h`` you can access a shared
+reference to a process global instance of the system PRNG (using interfaces such
+as ``/dev/urandom``, ``getrandom``, ``arc4random``, or ``RtlGenRandom``):
+
+.. cpp:function:: RandomNumberGenerator& system_rng()
+
+ Returns a reference to the system RNG
+
+There is also a wrapper class ``System_RNG`` which simply invokes on
+the return value of ``system_rng()``. This is useful in situations where
+you may sometimes want to use the system RNG and a userspace RNG in others,
+for example::
+
+ std::unique_ptr<Botan::RandomNumberGenerator> rng;
+ #if defined(BOTAN_HAS_SYSTEM_RNG)
+ rng.reset(new System_RNG);
+ #else
+ rng.reset(new AutoSeeded_RNG);
+ #endif
+
+Unlike nearly any other object in Botan it is acceptable to share a single
+instance of ``System_RNG`` between threads, because the underlying RNG is itself
+thread safe due to being serialized by a mutex in the kernel itself.
+
+AutoSeeded_RNG
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+AutoSeeded_RNG is type naming a 'best available' userspace PRNG. The
+exact definition of this has changed over time and may change in the
+future, fortunately there is no compatibility concerns when changing
+any RNG since the only expectation is it produces bits
+indistinguishable from random.
+
+.. note:: Starting in 2.16.0, AutoSeeded_RNG uses an internal lock and so is
+ safe to share among threads. However if possible it is still better to
+ use a RNG per thread as otherwise the RNG object needlessly creates a
+ point of contention. In previous versions, the RNG does not have an
+ internal lock and all access to it must be serialized.
+
+The current version uses HMAC_DRBG with either SHA-384 or SHA-256. The
+initial seed is generated either by the system PRNG (if available) or
+a default set of entropy sources. These are also used for periodic
+reseeding of the RNG state.
+
+HMAC_DRBG
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+HMAC DRBG is a random number generator designed by NIST and specified
+in SP 800-90A. It seems to be the most conservative generator of the
+NIST approved options.
+
+It can be instantiated with any HMAC but is typically used with
+SHA-256, SHA-384, or SHA-512, as these are the hash functions approved
+for this use by NIST.
+
+HMAC_DRBG's constructors are:
+
+.. cpp:class:: HMAC_DRBG
+
+ .. cpp:function:: HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, \
+ RandomNumberGenerator& underlying_rng, \
+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, \
+ size_t max_number_of_bytes_per_request = 64 * 1024)
+
+ Creates a DRBG which will automatically reseed as required by making
+ calls to ``underlying_rng`` either after being invoked
+ ``reseed_interval`` times, or if use of ``fork`` system call is
+ detected.
+
+ You can disable automatic reseeding by setting ``reseed_interval`` to
+ zero, in which case ``underlying_rng`` will only be invoked in the case
+ of ``fork``.
+
+ The specification of HMAC DRBG requires that each invocation produce no
+ more than 64 kibibytes of data. However, the RNG interface allows
+ producing arbitrary amounts of data in a single request. To accommodate
+ this, ``HMAC_DRBG`` treats requests for more data as if they were
+ multiple requests each of (at most) the maximum size. You can specify a
+ smaller maximum size with ``max_number_of_bytes_per_request``. There is
+ normally no reason to do this.
+
+ .. cpp:function:: HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, \
+ Entropy_Sources& entropy_sources, \
+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, \
+ size_t max_number_of_bytes_per_request = 64 * 1024)
+
+ Like above function, but instead of an RNG taking a set of entropy
+ sources to seed from as required.
+
+ .. cpp:function:: HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, \
+ RandomNumberGenerator& underlying_rng, \
+ Entropy_Sources& entropy_sources, \
+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, \
+ size_t max_number_of_bytes_per_request = 64 * 1024)
+
+ Like above function, but taking both an RNG and a set of entropy
+ sources to seed from as required.
+
+ .. cpp:function:: HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf)
+
+ Creates an unseeded DRBG. You must explicitly provide seed data later
+ on in order to use this RNG. This is primarily useful for deterministic
+ key generation.
+
+ Since no source of data is available to automatically reseed, automatic
+ reseeding is disabled when this constructor is used. If the RNG object
+ detects that ``fork`` system call was used without it being
+ subsequently reseeded, it will throw an exception.
+
+ .. cpp:function:: HMAC_DRBG(const std::string& hmac_hash)
+
+ Like the constructor just taking a PRF, except instead of a PRF object,
+ a string specifying what hash to use with HMAC is provided.
+
+ChaCha_RNG
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+This is a very fast userspace PRNG based on ChaCha20 and HMAC(SHA-256). The key
+for ChaCha is derived by hashing entropy inputs with HMAC. Then the ChaCha
+keystream generator is run, first to generate the new HMAC key (used for any
+future entropy additions), then the desired RNG outputs.
+
+This RNG composes two primitives thought to be secure (ChaCha and HMAC) in a
+simple and well studied way (the extract-then-expand paradigm), but is still an
+ad-hoc and non-standard construction. It is included because it is roughly 20x
+faster then HMAC_DRBG (basically running as fast as ChaCha can generate
+keystream bits), and certain applications need access to a very fast RNG.
+
+One thing applications using ``ChaCha_RNG`` need to be aware of is that for
+performance reasons, no backtracking resistance is implemented in the RNG
+design. An attacker who recovers the ``ChaCha_RNG`` state can recover the output
+backwards in time to the last rekey and forwards to the next rekey.
+
+An explicit reseeding (:cpp:func:`RandomNumberGenerator::add_entropy`) or
+providing any input to the RNG
+(:cpp:func:`RandomNumberGenerator::randomize_with_ts_input`,
+:cpp:func:`RandomNumberGenerator::randomize_with_input`) is sufficient to cause
+a reseeding. Or, if a RNG or entropy source was provided to the ``ChaCha_RNG``
+constructor, then reseeding will be performed automatically after a certain
+interval of requests.
+
+Processor_RNG
+^^^^^^^^^^^^^^^^^
+
+This RNG type directly invokes a CPU instruction capable of generating
+a cryptographically secure random number. On x86 it uses ``rdrand``,
+on POWER ``darn``. If the relevant instruction is not available, the
+constructor of the class will throw at runtime. You can test
+beforehand by checking the result of ``Processor_RNG::available()``.
+
+TPM_RNG
+^^^^^^^^^^^^^^^^^
+
+This RNG type allows using the RNG exported from a TPM chip.
+
+PKCS11_RNG
+^^^^^^^^^^^^^^^^^
+
+This RNG type allows using the RNG exported from a hardware token accessed via PKCS11.
+
+Entropy Sources
+---------------------------------
+
+An ``EntropySource`` is an abstract representation of some method of
+gather "real" entropy. This tends to be very system dependent. The
+*only* way you should use an ``EntropySource`` is to pass it to a PRNG
+that will extract entropy from it -- never use the output directly for
+any kind of key or nonce generation!
+
+``EntropySource`` has a pair of functions for getting entropy from
+some external source, called ``fast_poll`` and ``slow_poll``. These
+pass a buffer of bytes to be written; the functions then return how
+many bytes of entropy were gathered.
+
+Note for writers of ``EntropySource`` subclasses: it isn't necessary
+to use any kind of cryptographic hash on your output. The data
+produced by an EntropySource is only used by an application after it
+has been hashed by the ``RandomNumberGenerator`` that asked for the
+entropy, thus any hashing you do will be wasteful of both CPU cycles
+and entropy.
+
+The following entropy sources are currently used:
+
+ * The system RNG (``arc4random``, ``/dev/urandom``, or ``RtlGenRandom``).
+ * RDRAND and RDSEED are used if available, but not counted as contributing entropy
+ * ``/dev/random`` and ``/dev/urandom``. This may be redundant with the system RNG
+ * ``getentropy``, only used on OpenBSD currently
+ * ``/proc`` walk: read files in ``/proc``. Last ditch protection against
+ flawed system RNG.
+ * Win32 stats: takes snapshot of current system processes. Last ditch
+ protection against flawed system RNG.
+
+Fork Safety
+---------------------------------
+
+On Unix platforms, the ``fork()`` and ``clone()`` system calls can
+be used to spawn a new child process. Fork safety ensures that the
+child process doesn't see the same output of random bytes as the
+parent process. Botan tries to ensure fork safety by feeding the
+process ID into the internal state of the random generator and by
+automatically reseeding the random generator if the process ID
+changed between two requests of random bytes. However, this does
+not protect against PID wrap around. The process ID is usually
+implemented as a 16 bit integer. In this scenario, a process will
+spawn a new child process, which exits the parent process and
+spawns a new child process himself. If the PID wrapped around, the
+second child process may get assigned the process ID of it's
+grandparent and the fork safety can not be ensured.
+
+Therefore, it is strongly recommended to explicitly reseed any
+userspace random generators after forking a new process. If this is
+not possible in your application, prefer using the system PRNG
+instead.