Commit bdda8303 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'random-5.18-rc5-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/crng/random

Pull random number generator fixes from Jason Donenfeld:

 - Eric noticed that the memmove() in crng_fast_key_erasure() was bogus,
   so this has been changed to a memcpy() and the confusing situation
   clarified with a detailed comment.

 - [Half]SipHash documentation updates from Bagas and Eric, after Eric
   pointed out that the use of HalfSipHash in random.c made a bit of the
   text potentially misleading.

* tag 'random-5.18-rc5-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/crng/random:
  Documentation: siphash: disambiguate HalfSipHash algorithm from hsiphash functions
  Documentation: siphash: enclose HalfSipHash usage example in the literal block
  Documentation: siphash: convert danger note to warning for HalfSipHash
  random: document crng_fast_key_erasure() destination possibility
parents bd383b8e 5a7e470e
Loading
Loading
Loading
Loading
+28 −18
Original line number Diff line number Diff line
@@ -121,26 +121,36 @@ even scarier, uses an easily brute-forcable 64-bit key (with a 32-bit output)
instead of SipHash's 128-bit key. However, this may appeal to some
high-performance `jhash` users.

Danger!

Do not ever use HalfSipHash except for as a hashtable key function, and only
then when you can be absolutely certain that the outputs will never be
transmitted out of the kernel. This is only remotely useful over `jhash` as a
means of mitigating hashtable flooding denial of service attacks.

Generating a HalfSipHash key
============================
HalfSipHash support is provided through the "hsiphash" family of functions.

.. warning::
   Do not ever use the hsiphash functions except for as a hashtable key
   function, and only then when you can be absolutely certain that the outputs
   will never be transmitted out of the kernel. This is only remotely useful
   over `jhash` as a means of mitigating hashtable flooding denial of service
   attacks.

On 64-bit kernels, the hsiphash functions actually implement SipHash-1-3, a
reduced-round variant of SipHash, instead of HalfSipHash-1-3. This is because in
64-bit code, SipHash-1-3 is no slower than HalfSipHash-1-3, and can be faster.
Note, this does *not* mean that in 64-bit kernels the hsiphash functions are the
same as the siphash ones, or that they are secure; the hsiphash functions still
use a less secure reduced-round algorithm and truncate their outputs to 32
bits.

Generating a hsiphash key
=========================

Keys should always be generated from a cryptographically secure source of
random numbers, either using get_random_bytes or get_random_once:
random numbers, either using get_random_bytes or get_random_once::

	hsiphash_key_t key;
	get_random_bytes(&key, sizeof(key));

If you're not deriving your key from here, you're doing it wrong.

Using the HalfSipHash functions
===============================
Using the hsiphash functions
============================

There are two variants of the function, one that takes a list of integers, and
one that takes a buffer::
@@ -183,7 +193,7 @@ You may then iterate like usual over the returned hash bucket.
Performance
===========

HalfSipHash is roughly 3 times slower than JenkinsHash. For many replacements,
this will not be a problem, as the hashtable lookup isn't the bottleneck. And
in general, this is probably a good sacrifice to make for the security and DoS
resistance of HalfSipHash.
hsiphash() is roughly 3 times slower than jhash(). For many replacements, this
will not be a problem, as the hashtable lookup isn't the bottleneck. And in
general, this is probably a good sacrifice to make for the security and DoS
resistance of hsiphash().
+8 −1
Original line number Diff line number Diff line
@@ -318,6 +318,13 @@ static void crng_reseed(bool force)
 * the resultant ChaCha state to the user, along with the second
 * half of the block containing 32 bytes of random data that may
 * be used; random_data_len may not be greater than 32.
 *
 * The returned ChaCha state contains within it a copy of the old
 * key value, at index 4, so the state should always be zeroed out
 * immediately after using in order to maintain forward secrecy.
 * If the state cannot be erased in a timely manner, then it is
 * safer to set the random_data parameter to &chacha_state[4] so
 * that this function overwrites it before returning.
 */
static void crng_fast_key_erasure(u8 key[CHACHA_KEY_SIZE],
				  u32 chacha_state[CHACHA_STATE_WORDS],
@@ -333,7 +340,7 @@ static void crng_fast_key_erasure(u8 key[CHACHA_KEY_SIZE],
	chacha20_block(chacha_state, first_block);

	memcpy(key, first_block, CHACHA_KEY_SIZE);
	memmove(random_data, first_block + CHACHA_KEY_SIZE, random_data_len);
	memcpy(random_data, first_block + CHACHA_KEY_SIZE, random_data_len);
	memzero_explicit(first_block, sizeof(first_block));
}