Re: [PATCH v5 2/5] random: Add and use arch_get_rng_seed
On Wed, Jul 23, 2014 at 09:57:28PM -0700, Andy Lutomirski wrote: > Currently, init_std_data contains its own logic for using arch > random sources. This replaces that logic with a generic function > arch_get_rng_seed that allows arch code to supply its own logic. > The default implementation tries arch_get_random_seed_long and > arch_get_random_long individually. > > The only functional change here is that random_get_entropy() is used > unconditionally instead of being used only when the arch sources > fail. This may add a tiny amount of security. > > Signed-off-by: Andy Lutomirski Acked-by: Theodore Ts'o - Ted -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 2/5] random: Add and use arch_get_rng_seed
On Wed, Jul 23, 2014 at 9:57 PM, Andy Lutomirski wrote: > Currently, init_std_data contains its own logic for using arch > random sources. This replaces that logic with a generic function > arch_get_rng_seed that allows arch code to supply its own logic. > The default implementation tries arch_get_random_seed_long and > arch_get_random_long individually. > > The only functional change here is that random_get_entropy() is used > unconditionally instead of being used only when the arch sources > fail. This may add a tiny amount of security. tytso, are you okay with this approach? I'd be happy to rework this if you prefer some other way of doing it. --Andy > > Signed-off-by: Andy Lutomirski > --- > drivers/char/random.c | 14 +++--- > include/linux/random.h | 40 > 2 files changed, 51 insertions(+), 3 deletions(-) > > diff --git a/drivers/char/random.c b/drivers/char/random.c > index 0a7ac0a..be7a94e 100644 > --- a/drivers/char/random.c > +++ b/drivers/char/random.c > @@ -1236,6 +1236,10 @@ void get_random_bytes_arch(void *buf, int nbytes) > } > EXPORT_SYMBOL(get_random_bytes_arch); > > +static void seed_entropy_store(void *ctx, u32 data) > +{ > + mix_pool_bytes((struct entropy_store *)ctx, &data, sizeof(data), > NULL); > +} > > /* > * init_std_data - initialize pool with system data > @@ -1251,15 +1255,19 @@ static void init_std_data(struct entropy_store *r) > int i; > ktime_t now = ktime_get_real(); > unsigned long rv; > + char log_prefix[128]; > > r->last_pulled = jiffies; > mix_pool_bytes(r, &now, sizeof(now), NULL); > for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) { > - if (!arch_get_random_seed_long(&rv) && > - !arch_get_random_long(&rv)) > - rv = random_get_entropy(); > + rv = random_get_entropy(); > mix_pool_bytes(r, &rv, sizeof(rv), NULL); > } > + > + sprintf(log_prefix, "random: seeded %s pool", r->name); > + arch_get_rng_seed(r, seed_entropy_store, 8 * r->poolinfo->poolbytes, > + log_prefix); > + > mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL); > } > > diff --git a/include/linux/random.h b/include/linux/random.h > index 57fbbff..81a6145 100644 > --- a/include/linux/random.h > +++ b/include/linux/random.h > @@ -106,6 +106,46 @@ static inline int arch_has_random_seed(void) > } > #endif > > +#ifndef __HAVE_ARCH_GET_RNG_SEED > + > +/** > + * arch_get_rng_seed() - get architectural rng seed data > + * @ctx: context for the seed function > + * @seed: function to call for each u32 obtained > + * @bits_per_source: number of bits from each source to try to use > + * @log_prefix: beginning of log output (may be NULL) > + * > + * Synchronously load some architectural entropy or other best-effort > + * random seed data. An arch-specific implementation should be no worse > + * than this generic implementation. If the arch code does something > + * interesting, it may log something of the form "log_prefix with > + * 8 bits of stuff". > + * > + * No arch-specific implementation should be any worse than the generic > + * implementation. > + */ > +static inline void arch_get_rng_seed(void *ctx, > +void (*seed)(void *ctx, u32 data), > +int bits_per_source, > +const char *log_prefix) > +{ > + int i; > + > + for (i = 0; i < bits_per_source; i += 8 * sizeof(long)) { > + unsigned long rv; > + > + if (arch_get_random_seed_long(&rv) || > + arch_get_random_long(&rv)) { > + seed(ctx, (u32)rv); > +#if BITS_PER_LONG > 32 > + seed(ctx, (u32)(rv >> 32)); > +#endif > + } > + } > +} > + > +#endif /* __HAVE_ARCH_GET_RNG_SEED */ > + > /* Pseudo random number generator from numerical recipes. */ > static inline u32 next_pseudo_random32(u32 seed) > { > -- > 1.9.3 > -- Andy Lutomirski AMA Capital Management, LLC -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 2/5] random: Add and use arch_get_rng_seed
Currently, init_std_data contains its own logic for using arch random sources. This replaces that logic with a generic function arch_get_rng_seed that allows arch code to supply its own logic. The default implementation tries arch_get_random_seed_long and arch_get_random_long individually. The only functional change here is that random_get_entropy() is used unconditionally instead of being used only when the arch sources fail. This may add a tiny amount of security. Signed-off-by: Andy Lutomirski --- drivers/char/random.c | 14 +++--- include/linux/random.h | 40 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 0a7ac0a..be7a94e 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1236,6 +1236,10 @@ void get_random_bytes_arch(void *buf, int nbytes) } EXPORT_SYMBOL(get_random_bytes_arch); +static void seed_entropy_store(void *ctx, u32 data) +{ + mix_pool_bytes((struct entropy_store *)ctx, &data, sizeof(data), NULL); +} /* * init_std_data - initialize pool with system data @@ -1251,15 +1255,19 @@ static void init_std_data(struct entropy_store *r) int i; ktime_t now = ktime_get_real(); unsigned long rv; + char log_prefix[128]; r->last_pulled = jiffies; mix_pool_bytes(r, &now, sizeof(now), NULL); for (i = r->poolinfo->poolbytes; i > 0; i -= sizeof(rv)) { - if (!arch_get_random_seed_long(&rv) && - !arch_get_random_long(&rv)) - rv = random_get_entropy(); + rv = random_get_entropy(); mix_pool_bytes(r, &rv, sizeof(rv), NULL); } + + sprintf(log_prefix, "random: seeded %s pool", r->name); + arch_get_rng_seed(r, seed_entropy_store, 8 * r->poolinfo->poolbytes, + log_prefix); + mix_pool_bytes(r, utsname(), sizeof(*(utsname())), NULL); } diff --git a/include/linux/random.h b/include/linux/random.h index 57fbbff..81a6145 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -106,6 +106,46 @@ static inline int arch_has_random_seed(void) } #endif +#ifndef __HAVE_ARCH_GET_RNG_SEED + +/** + * arch_get_rng_seed() - get architectural rng seed data + * @ctx: context for the seed function + * @seed: function to call for each u32 obtained + * @bits_per_source: number of bits from each source to try to use + * @log_prefix: beginning of log output (may be NULL) + * + * Synchronously load some architectural entropy or other best-effort + * random seed data. An arch-specific implementation should be no worse + * than this generic implementation. If the arch code does something + * interesting, it may log something of the form "log_prefix with + * 8 bits of stuff". + * + * No arch-specific implementation should be any worse than the generic + * implementation. + */ +static inline void arch_get_rng_seed(void *ctx, +void (*seed)(void *ctx, u32 data), +int bits_per_source, +const char *log_prefix) +{ + int i; + + for (i = 0; i < bits_per_source; i += 8 * sizeof(long)) { + unsigned long rv; + + if (arch_get_random_seed_long(&rv) || + arch_get_random_long(&rv)) { + seed(ctx, (u32)rv); +#if BITS_PER_LONG > 32 + seed(ctx, (u32)(rv >> 32)); +#endif + } + } +} + +#endif /* __HAVE_ARCH_GET_RNG_SEED */ + /* Pseudo random number generator from numerical recipes. */ static inline u32 next_pseudo_random32(u32 seed) { -- 1.9.3 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html