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 PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Thu, 17 Jul 2014 11:22:17 -0700 From: Andy Lutomirski <luto@...capital.net> To: kvm@...r.kernel.org, "H. Peter Anvin" <hpa@...or.com>, Theodore Ts'o <tytso@....edu>, linux-kernel@...r.kernel.org, Kees Cook <keescook@...omium.org>, x86@...nel.org Cc: Daniel Borkmann <dborkman@...hat.com>, Srivatsa Vaddagiri <vatsa@...ux.vnet.ibm.com>, Raghavendra K T <raghavendra.kt@...ux.vnet.ibm.com>, Gleb Natapov <gleb@...nel.org>, Paolo Bonzini <pbonzini@...hat.com>, bsd@...hat.com, Andrew Honig <ahonig@...gle.com>, Andy Lutomirski <luto@...capital.net> Subject: [PATCH v4 2/5] random: Add and use arch_get_rng_seed Currently, init_std_data contains its own logic for using arch random sources. This logic is a bit strange: it reads one long of arch random data per byte of internal state. 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, requesting one bit per bit of internal state being seeded. Assuming the arch sources are perfect, this is the right thing to do. They're not, though, so the followup patch attempts to implement the correct logic on x86. Signed-off-by: Andy Lutomirski <luto@...capital.net> --- 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..a17065e 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, longs = (bits_per_source + BITS_PER_LONG - 1) / BITS_PER_LONG; + + for (i = 0; i < longs; i++) { + 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 linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists