diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-03-01 10:04:18 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2017-03-06 22:24:33 +0100 |
commit | 995a82a08d4b303daee05ae816ba0fbc96d38249 (patch) | |
tree | 11994914b15c21999adab67390b697c06217ade7 /doc | |
parent | cb4a61f7b933e395aec53f8922195dd42de875ea (diff) | |
download | gnutls-995a82a08d4b303daee05ae816ba0fbc96d38249.tar.gz |
doc: updated the PRNG documentation to utilize two PRNG instances
Also move the random generator discussion to internals section.
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'doc')
-rw-r--r-- | doc/cha-crypto.texi | 104 | ||||
-rw-r--r-- | doc/cha-internals.texi | 118 |
2 files changed, 120 insertions, 102 deletions
diff --git a/doc/cha-crypto.texi b/doc/cha-crypto.texi index 06c3c5ca98..567233afac 100644 --- a/doc/cha-crypto.texi +++ b/doc/cha-crypto.texi @@ -108,108 +108,8 @@ function. It allows obtaining random data of various levels. @showenumdesc{gnutls_rnd_level_t,The random number levels.} @showfuncdesc{gnutls_rnd} -@subsection Inner workings - -The random number levels map to three CHACHA-based random generators which -are initially seeded using the OS random device, e.g., @code{/dev/urandom} -or @code{getrandom()}. These random generators are unique per thread, and -are automatically re-seeded when a fork is detected. - -The reason the CHACHA cipher was selected for the GnuTLS' PRNG is the fact -that CHACHA is considered a secure and fast stream cipher, and is already -defined for use in TLS protocol. As such, the utilization of it would -not stress the CPU caches, and would allow for better performance on busy -servers, irrespective of their architecture (e.g., even if AES is not -available with an optimized instruction set). - -The generators are unique per thread to allow lock-free operation. That -induces a cost of around 140-bytes for the state of the generators per -thread, on threads that would utilize @funcref{gnutls_rnd}. At the same time -it allows fast and lock-free access to the generators. That benefits servers -which utilize more than 4 threads, while imposes no cost on single threaded -processes. - -On the first call to @funcref{gnutls_rnd} they are seeded with three independent -keys obtained from the OS random device. Their seed is used to output a fixed amount -of bytes. The lower the level of the random generator the more bytes the -generator will output without reseeding, providing it better performance. -For the @code{GNUTLS_RND_KEY} and @code{GNUTLS_RND_RANDOM} levels, a -re-seed xor's data obtained from the OS random device with the old key, -while the @code{GNUTLS_RND_NONCE} levels utilizes -the generator of the @code{GNUTLS_RND_RANDOM} level to obtain a new seed -(which is also combined with the old key to produce the new). -That is, the @code{GNUTLS_RND_NONCE} -level is re-seeded using the @code{GNUTLS_RND_RANDOM}, and -@code{GNUTLS_RND_RANDOM}, @code{GNUTLS_RND_KEY} using the system random -generator. - -@subsection Defense against PRNG attacks - -This section describes the counter-measures available in the Pseudo-random number generator (PRNG) -of GnuTLS for known attacks as described in @xcite{PRNGATTACKS}. Note that, the attacks on a PRNG such as -state-compromise, assume a quite powerful adversary which has in practice -access to the PRNG state. - -@subsubheading Cryptanalytic - -To defend against cryptanalytic attacks GnuTLS' PRNG is a stream cipher -designed to defend against the same attacks. As such, GnuTLS' PRNG strength -with regards to this attack relies on the underlying crypto block, -which at the time of writing is CHACHA. That is easily replaceable in -the future if required. - -@subsubheading Input-based attacks - -These attacks assume that the attacker can influence the input that is used -to form the state of the PRNG. To counter these attacks GnuTLS does not -gather input from the system environment but rather relies on the OS -provided random generator. That is the @code{/dev/urandom} or -@code{getentropy}/@code{getrandom} system calls. As such, GnuTLS' PRNG -is as strong as the system random generator can ensure with regards to -input-based attacks. - -@subsubheading State-compromise: Backtracking - -A backtracking attack, assumes that an adversary obtains at some point of time -access to the generator state, and wants to recover past bytes. As the -GnuTLS generator is fine-tuned to provide multiple levels, such an attack -mainly concerns levels @code{GNUTLS_RND_RANDOM} and @code{GNUTLS_RND_KEY}, -since @code{GNUTLS_RND_NONCE} is intended to output non-secret data. -The @code{GNUTLS_RND_RANDOM} generator at the time of writing can output -16kb prior to being re-seeded thus this is its upper bound for previously -generated data recovered using this attack. That assumes that the state -of the system random generator is unknown to the attacker - -That attack reflects a real world scenario where application's memory is -temporarily compromised, while kernel's memory is inaccessible. - -@subsubheading State-compromise: Permanent Compromise Attack - -A permanent compromise attack implies that once an attacker compromises the -state of GnuTLS' random generator on specific time, all future and past -outputs from the generator can be compromised. For past outputs the -previous paragraph applies. For future outputs, both the @code{GNUTLS_RND_RANDOM} -and the @code{GNUTLS_RND_KEY} with recover on 16kb or 1kb respectively -have been generated. The @code{GNUTLS_RND_NONCE} level generator -will recover after several megabytes of output is generated. -As the nonce level is intended for non-secret but unpredictable output, -the above is a compromise to improve performance. - -@subsubheading State-compromise: Iterative guessing - -This attack assumes that after an attacker obtained the PRNG state -at some point, is able to recover the state at a later time by observing -outputs of the PRNG. That is countered by switching the key to generators -using a combination of a fresh key and the old one (using XOR), at -re-seed time. All levels are immune to such attack. - -@subsubheading State-compromise: Meet-in-the-Middle - -This attack assumes that the attacker obtained the PRNG state at -two distinct times, and being able to recover the state at the third time -after observing the output of the PRNG. Given the approach described -on the above paragraph, all levels are immune to such attack. - +See @ref{Random Number Generators-internals} for more information +on the random number generator operation. @node Overriding algorithms @section Overriding algorithms diff --git a/doc/cha-internals.texi b/doc/cha-internals.texi index 2f71ee2d96..a9fe2ddce4 100644 --- a/doc/cha-internals.texi +++ b/doc/cha-internals.texi @@ -13,6 +13,7 @@ happens inside the black box. * TLS Authentication Methods:: * TLS Extension Handling:: * Cryptographic Backend:: +* Random Number Generators-internals:: @end menu @node The TLS Protocol @@ -516,3 +517,120 @@ For asymmetric or public keys, GnuTLS supports PKCS #11 which allows operation without access to long term keys, in addition to CPU offloading. For more information see @ref{Hardware security modules and abstract key types}. + +@node Random Number Generators-internals +@section Random Number Generators + +@subheading Inner workings + +The random number generator levels in @code{gnutls_rnd_level_t} map to two CHACHA-based random generators which +are initially seeded using the OS random device, e.g., @code{/dev/urandom} +or @code{getrandom()}. These random generators are unique per thread, and +are automatically re-seeded when a fork is detected. + +The reason the CHACHA cipher was selected for the GnuTLS' PRNG is the fact +that CHACHA is considered a secure and fast stream cipher, and is already +defined for use in TLS protocol. As such, the utilization of it would +not stress the CPU caches, and would allow for better performance on busy +servers, irrespective of their architecture (e.g., even if AES is not +available with an optimized instruction set). + +The generators are unique per thread to allow lock-free operation. That +induces a cost of around 140-bytes for the state of the generators per +thread, on threads that would utilize @funcref{gnutls_rnd}. At the same time +it allows fast and lock-free access to the generators. That benefits servers +which utilize more than 4 threads, while imposes no cost on single threaded +processes. + +On the first call to @funcref{gnutls_rnd} the generators are seeded with two independent +keys obtained from the OS random device. Their seed is used to output a fixed amount +of bytes before re-seeding; the number of bytes output varies per generator. +The lower the level of the random generator the more bytes the +generator will output without re-seeding, providing it better performance. +For the @code{GNUTLS_RND_KEY} and @code{GNUTLS_RND_RANDOM} levels, a +re-seed mixes data obtained from the OS random device with the previous key, +while the @code{GNUTLS_RND_NONCE} level utilizes +the generator of the @code{GNUTLS_RND_RANDOM} level to obtain a new seed +(which is similarly mixed with the old key to produce the new). +That is, the @code{GNUTLS_RND_NONCE} +level is re-seeded using the @code{GNUTLS_RND_RANDOM}, and +@code{GNUTLS_RND_RANDOM}, @code{GNUTLS_RND_KEY} using the system random +generator. + +The PRNG used to provide the @code{GNUTLS_RND_RANDOM} and +@code{GNUTLS_RND_KEY} levels is identical. +However, the use of @code{GNUTLS_RND_KEY} level enforces +a re-seed on the PRNG, to ensure that the recovery of the PRNG state +is not sufficient to recover previously generated values. + + +@subheading Defense against PRNG attacks + +This section describes the counter-measures available in the Pseudo-random number generator (PRNG) +of GnuTLS for known attacks as described in @xcite{PRNGATTACKS}. Note that, the attacks on a PRNG such as +state-compromise, assume a quite powerful adversary which has in practice +access to the PRNG state. + +@subsubheading Cryptanalytic + +To defend against cryptanalytic attacks GnuTLS' PRNG is a stream cipher +designed to defend against the same attacks. As such, GnuTLS' PRNG strength +with regards to this attack relies on the underlying crypto block, +which at the time of writing is CHACHA. That is easily replaceable in +the future if attacks are found to be possible in that cipher. + +@subsubheading Input-based attacks + +These attacks assume that the attacker can influence the input that is used +to form the state of the PRNG. To counter these attacks GnuTLS does not +gather input from the system environment but rather relies on the OS +provided random generator. That is the @code{/dev/urandom} or +@code{getentropy}/@code{getrandom} system calls. As such, GnuTLS' PRNG +is as strong as the system random generator can assure with regards to +input-based attacks. + +@subsubheading State-compromise: Backtracking + +A backtracking attack, assumes that an adversary obtains at some point of time +access to the generator state, and wants to recover past bytes. As the +GnuTLS generator is fine-tuned to provide multiple levels, such an attack +mainly concerns levels @code{GNUTLS_RND_RANDOM} and @code{GNUTLS_RND_KEY}, +since @code{GNUTLS_RND_NONCE} is intended to output non-secret data. +The @code{GNUTLS_RND_RANDOM} generator at the time of writing can output +16kb prior to being re-seeded thus this is its upper bound for previously +generated data recovered using this attack. That assumes that the state +of the system random generator is unknown to the attacker, and we carry that +assumption on the next paragraphs. The usage of @code{GNUTLS_RND_KEY} level +ensures that no backtracking is possible for all output data, by re-keying +the PRNG using its own output. + +Such an attack reflects the real world scenario where application's memory is +temporarily compromised, while the kernel's memory is inaccessible. + +@subsubheading State-compromise: Permanent Compromise Attack + +A permanent compromise attack implies that once an attacker compromises the +state of GnuTLS' random generator at a specific time, future and past +outputs from the generator are compromised. For past outputs the +previous paragraph applies. For future outputs, both the @code{GNUTLS_RND_RANDOM} +and the @code{GNUTLS_RND_KEY} will recover after 16kb of data have been generated. +The @code{GNUTLS_RND_NONCE} level generator +will recover after several megabytes of output is generated. +That threatens the unpredictability of the output of the nonce level, in a +scenario like that, and is compromise to improve operational performance. + +@subsubheading State-compromise: Iterative guessing + +This attack assumes that after an attacker obtained the PRNG state +at some point, is able to recover the state at a later time by observing +outputs of the PRNG. That is countered by switching the key to generators +using a combination of a fresh key and the old one (using XOR), at +re-seed time. All levels are immune to such attack after a re-seed. + +@subsubheading State-compromise: Meet-in-the-Middle + +This attack assumes that the attacker obtained the PRNG state at +two distinct times, and being able to recover the state at the third time +after observing the output of the PRNG. Given the approach described +on the above paragraph, all levels are immune to such attack. + |