lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220522214457.37108-1-Jason@zx2c4.com>
Date:   Sun, 22 May 2022 23:44:57 +0200
From:   "Jason A. Donenfeld" <Jason@...c4.com>
To:     Linus Torvalds <torvalds@...ux-foundation.org>
Cc:     linux-kernel@...r.kernel.org
Subject: [GIT PULL] random number generator updates for 5.19-rc1

Hi Linus,

Please pull the following random number generator updates for 5.19-rc1. These
updates continue to refine the work began in 5.17 and 5.18 of modernizing the
RNG's crypto and streamlining and documenting its code. New for 5.19, the
updates aim to improve entropy collection methods and make some initial
decisions regarding the "premature next" problem and our threat model. The
cloc utility now reports that random.c is 931 lines of code and 466 lines of
comments, not that basic metrics like that mean all that much, but at the very
least it tells you that this is very much a manageable driver now.

Here's a summary of the various patches in this pull:

- The random_get_entropy() function now always returns something at least
  minimally useful. This is the primary entropy source in most collectors,
  which in the best case expands to something like RDTSC, but prior to this
  change, in the worst case it would just return 0, contributing nothing. For
  5.19, additional architectures are wired up, and architectures that are
  entirely missing a cycle counter now have a generic fallback path, which
  uses the highest resolution clock available from the timekeeping subsystem.
  Some of those clocks can actually be quite good, despite the CPU not having
  a cycle counter of its own, and going off-core for a stamp is generally
  thought to increase jitter, something positive from the perspective of
  entropy gathering. Done very early on in the development cycle, this has
  been sitting in next getting some testing for a while now and has relevant
  acks from the archs, so it should be pretty well tested and fine, but is
  nonetheless the thing I'll be keeping my eye on most closely.

- Of particular note with the random_get_entropy() improvements is MIPS,
  which, on CPUs that lack the c0 count register, will now combine the
  high-speed but short-cycle c0 random register with the lower-speed but
  long-cycle generic fallback path.

- With random_get_entropy() now always returning something useful, the
  interrupt handler now collects entropy in a consistent construction.

- Rather than comparing two samples of random_get_entropy() for the jitter
  dance, the algorithm now tests many samples, and uses the amount of
  differing ones to determine whether or not jitter entropy is usable and how
  laborious it must be. The problem with comparing only two samples was that
  if the cycle counter was extremely slow, but just so happened to be on the
  cusp of a change, the slowness wouldn't be detected. Taking many samples
  fixes that to some degree. This, combined with the other improvements to
  random_get_entropy(), should make future unification of /dev/random and
  /dev/urandom maybe more possible. At the very least, were we to attempt it
  again today (we're not), it wouldn't break any of Guenter's test rigs that
  broke when we tried it with 5.18. So, not today, but perhaps down the road,
  that's something we can revisit.

- We attempt to reseed the RNG immediately upon waking up from system suspend
  or hibernation, making use of the various timestamps about suspend time and
  such available, as well as the usual inputs such as RDRAND when available.

- Batched randomness now falls back to ordinary randomness before the RNG is
  initialized. This provides more consistent guarantees to the types of random
  numbers being returned by the various accessors.

- The "pre-init injection" code is now gone for good. I suspect you in
  particular will be happy to read that, as I recall you expressing your
  distaste for it a few months ago. Instead, to avoid a "premature first"
  issue, while still allowing for maximal amount of entropy availability
  during system boot, the first 128 bits of estimated entropy are used
  immediately as it arrives, with the next 128 bits being buffered. And, as
  before, after the RNG has been fully initialized, it winds up reseeding
  anyway a few seconds later in most cases. This resulted in a pretty big
  simplification of the initialization code and let us remove various ad-hoc
  mechanisms like the ugly crng_pre_init_inject().

- The RNG no longer pretends to handle the "premature next" security model,
  something that various academics and other RNG designs have tried to care
  about in the past. After an interesting mailing list thread, these issues
  are thought to be a) mainly academic and not practical at all, and b)
  actively harming the real security of the RNG by delaying new entropy
  additions after a potential compromise, making a potentially bad situation
  even worse. As well, in the first place, our RNG never even properly handled
  the premature next issue, so removing an incomplete solution to a fake
  problem was particularly nice.  This allowed for numerous other
  simplifications in the code, which is a lot cleaner as a consequence. If you
  didn't see it before, https://lore.kernel.org/lkml/YmlMGx6+uigkGiZ0@zx2c4.com/
  may be a thread worth skimming through.

- While the interrupt handler received a separate code path years ago that
  avoids locks by using per-cpu data structures and a faster mixing algorithm,
  in order to reduce interrupt latency, input and disk events that are
  triggered in hardirq handlers were still hitting locks and more expensive
  algorithms. Those are now redirected to use the faster per-cpu data
  structures.

- Rather than having the fake-crypto almost-siphash-based random32
  implementation be used right and left, and in many places where
  cryptographically secure randomness is desirable, the batched entropy code
  is now fast enough to replace that.

- As usual, numerous code quality and documentation cleanups. For example, the
  initialization state machine now uses enum symbolic constants instead of
  just hard coding numbers everywhere.

- Since the RNG initializes once, and then is always initialized thereafter, a
  pretty heavy amount of code used during that initialization is never used
  again. It is now completely cordoned off using static branches and it winds
  up in the .text.unlikely section so that it doesn't reduce cache compactness
  after the RNG is ready.

- A variety of functions meant for waiting on the RNG to be initialized were
  only used by vsprintf, and in not a particularly optimal way. Replacing that
  usage with a more ordinary setup made it possible to remove those functions.

- A cleanup of how we warn userspace about the use of uninitialized
  /dev/urandom and uninitialized get_random_bytes() usage. Interestingly, with
  the change you merged for 5.18 that attempts to use jitter (but does not
  block if it can't), the majority of users should never see those warnings
  for /dev/urandom at all now, and the one for in-kernel usage is mainly a
  debug thing.

- The file_operations struct for /dev/[u]random now implements .read_iter and
  .write_iter instead of .read and .write, allowing it to also implement
  .splice_read and .splice_write, which makes splice(2) work again after it
  was broken here (and in many other places in the tree) during the set_fs()
  removal. This was a bit of a last minute arrival from Jens that hasn't had
  as much time to bake, so I'll be keeping my eye on this as well, but it
  seems fairly ordinary. Unfortunately, read_iter() is around 3% slower than
  read() in my tests, which I'm not thrilled about. But Jens and Al, spurred
  by this observation, seem to be making progress in removing the bottlenecks
  on the iter paths in the VFS layer in general, which should remove the
  performance gap for all drivers.

- Assorted other bug fixes, cleanups, and optimizations.

- A small SipHash cleanup. Note: Greg has an SPDX SipHash patch in his tree
  that changes the same files, which git should handle automatically, but
  heads up in case there's merge trouble.

Regards,
Jason

The following changes since commit c5eb0a61238dd6faf37f58c9ce61c9980aaffd7a:

  Linux 5.18-rc6 (2022-05-08 13:54:17 -0700)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/crng/random.git tags/random-5.19-rc1-for-linus

for you to fetch changes up to 1ce6c8d68f8ac587f54d0a271ac594d3d51f3efb:

  random: check for signals after page of pool writes (2022-05-22 22:34:31 +0200)

----------------------------------------------------------------
Random number generator updates for Linux 5.19-rc1.
----------------------------------------------------------------

Jason A. Donenfeld (46):
      random: fix sysctl documentation nits
      init: call time_init() before rand_initialize()
      ia64: define get_cycles macro for arch-override
      s390: define get_cycles macro for arch-override
      parisc: define get_cycles macro for arch-override
      alpha: define get_cycles macro for arch-override
      powerpc: define get_cycles macro for arch-override
      openrisc: start CPU timer early in boot
      timekeeping: Add raw clock fallback for random_get_entropy()
      m68k: use fallback for random_get_entropy() instead of zero
      riscv: use fallback for random_get_entropy() instead of zero
      mips: use fallback for random_get_entropy() instead of just c0 random
      arm: use fallback for random_get_entropy() instead of zero
      nios2: use fallback for random_get_entropy() instead of zero
      x86/tsc: Use fallback for random_get_entropy() instead of zero
      um: use fallback for random_get_entropy() instead of zero
      sparc: use fallback for random_get_entropy() instead of zero
      xtensa: use fallback for random_get_entropy() instead of zero
      random: insist on random_get_entropy() existing in order to simplify
      random: vary jitter iterations based on cycle counter speed
      random: mix in timestamps and reseed on system restore
      random: do not use batches when !crng_ready()
      random: use first 128 bits of input as fast init
      random: do not pretend to handle premature next security model
      random: order timer entropy functions below interrupt functions
      random: do not use input pool from hard IRQs
      random: help compiler out with fast_mix() by using simpler arguments
      siphash: use one source of truth for siphash permutations
      random32: use real rng for non-deterministic randomness
      random: use symbolic constants for crng_init states
      random: avoid initializing twice in credit race
      random: move initialization out of reseeding hot path
      random: remove ratelimiting for in-kernel unseeded randomness
      random: use proper jiffies comparison macro
      random: handle latent entropy and command line from random_init()
      random: credit architectural init the exact amount
      random: use static branch for crng_ready()
      random: remove extern from functions in header
      random: use proper return types on get_random_{int,long}_wait()
      random: make consistent use of buf and len
      random: move initialization functions out of hot pages
      random: remove get_random_bytes_arch() and add rng_has_arch_random()
      random: remove mostly unused async readiness notifier
      random: move randomize_page() into mm where it belongs
      random: unify batched entropy implementations
      random: check for signals after page of pool writes

Jens Axboe (3):
      random: convert to using fops->read_iter()
      random: convert to using fops->write_iter()
      random: wire up fops->splice_{read,write}_iter()

 Documentation/admin-guide/sysctl/kernel.rst |    8 +-
 arch/alpha/include/asm/timex.h              |    1 +
 arch/arm/include/asm/timex.h                |    1 +
 arch/ia64/include/asm/timex.h               |    1 +
 arch/m68k/include/asm/timex.h               |    2 +-
 arch/mips/include/asm/timex.h               |   17 +-
 arch/nios2/include/asm/timex.h              |    3 +
 arch/openrisc/include/asm/timex.h           |    1 +
 arch/openrisc/kernel/head.S                 |    9 +
 arch/parisc/include/asm/timex.h             |    3 +-
 arch/powerpc/include/asm/timex.h            |    1 +
 arch/riscv/include/asm/timex.h              |    2 +-
 arch/s390/include/asm/timex.h               |    1 +
 arch/sparc/include/asm/timex_32.h           |    4 +-
 arch/um/include/asm/timex.h                 |    9 +-
 arch/x86/include/asm/timex.h                |    9 +
 arch/x86/include/asm/tsc.h                  |    7 +-
 arch/xtensa/include/asm/timex.h             |    6 +-
 drivers/char/random.c                       | 1346 +++++++++++----------------
 include/linux/mm.h                          |    1 +
 include/linux/prandom.h                     |   61 +-
 include/linux/random.h                      |   90 +-
 include/linux/siphash.h                     |   28 +
 include/linux/timex.h                       |    8 +
 init/main.c                                 |   13 +-
 kernel/time/timekeeping.c                   |   15 +
 kernel/time/timer.c                         |    2 -
 lib/Kconfig.debug                           |    3 +-
 lib/random32.c                              |  347 +------
 lib/siphash.c                               |   32 +-
 lib/vsprintf.c                              |   67 +-
 mm/util.c                                   |   32 +
 net/core/dev.c                              |    3 -
 net/ipv4/devinet.c                          |    4 +-
 net/ipv6/addrconf.c                         |    2 -
 35 files changed, 784 insertions(+), 1355 deletions(-)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ