I've always loved these little feedback loops in the random subsystem, where it relies upon it's own random state to subtly change the meaning of future events.
Damien Miller <d...@mindrot.org> wrote: > On Thu, 28 Jul 2022, Damien Miller wrote: > > > On Wed, 27 Jul 2022, Theo de Raadt wrote: > > > > > + rs->rs_count += rekey_fuzz & (REKEY_BASE - 1); > > > > > > I mean, why not use % here > > > > Sure, that's reasonable. > > revised: > > Index: crypt/arc4random.c > =================================================================== > RCS file: /cvs/src/lib/libc/crypt/arc4random.c,v > retrieving revision 1.56 > diff -u -p -r1.56 arc4random.c > --- crypt/arc4random.c 28 Feb 2022 21:56:29 -0000 1.56 > +++ crypt/arc4random.c 28 Jul 2022 00:59:34 -0000 > @@ -49,6 +49,8 @@ > #define BLOCKSZ 64 > #define RSBUFSZ (16*BLOCKSZ) > > +#define REKEY_BASE (1024*1024) /* NB. should be a power of 2 */ > + > /* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */ > static struct _rs { > size_t rs_have; /* valid bytes at end of rs_buf */ > @@ -63,6 +65,8 @@ static struct _rsx { > > static inline int _rs_allocate(struct _rs **, struct _rsx **); > static inline void _rs_forkdetect(void); > +static inline void _rs_random_u32(uint32_t *); > + > #include "arc4random.h" > > static inline void _rs_rekey(u_char *dat, size_t datlen); > @@ -86,6 +90,7 @@ static void > _rs_stir(void) > { > u_char rnd[KEYSZ + IVSZ]; > + uint32_t rekey_fuzz; > > if (getentropy(rnd, sizeof rnd) == -1) > _getentropy_fail(); > @@ -100,7 +105,10 @@ _rs_stir(void) > rs->rs_have = 0; > memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf)); > > - rs->rs_count = 1600000; > + rs->rs_count = REKEY_BASE; > + /* rekey interval should not be predictable */ > + _rs_random_u32(&rekey_fuzz); > + rs->rs_count += rekey_fuzz % REKEY_BASE; > } > > static inline void