From patchwork Thu Aug 14 05:43:55 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Lutomirski X-Patchwork-Id: 4722351 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CD378C0338 for ; Thu, 14 Aug 2014 05:46:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E5ABE201B9 for ; Thu, 14 Aug 2014 05:46:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 092D32017E for ; Thu, 14 Aug 2014 05:46:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752512AbaHNFoU (ORCPT ); Thu, 14 Aug 2014 01:44:20 -0400 Received: from mail-pd0-f174.google.com ([209.85.192.174]:54429 "EHLO mail-pd0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750963AbaHNFoR (ORCPT ); Thu, 14 Aug 2014 01:44:17 -0400 Received: by mail-pd0-f174.google.com with SMTP id fp1so963002pdb.33 for ; Wed, 13 Aug 2014 22:44:17 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=aa/o+es8FWUqEOpQJ+AxBD60ZdzMUCym68xMB083k50=; b=HXAAED3EU4Oy4uOY3mtN9nuk2/lzbNuRCqrd6quvCAUHSgfL/r6NEl6bo+CeNAxnBd 2hUqnFNE/jMua9oE5J4RasOEUFpjei15rtyjmSIywFkpLQjWnEd9yv7u0XnXugChNU5c msQaQCXml8ab0oe0v2143w04t0eeIDXMdLTqIAJRxRgFJCvJS7h/OLbl536tyK/8Voaq kl+z+BscTJBSLregl43uiDGUiikyPSx6FHUPA9aUvDJapnHvIBH+eFGsK/6ErewgvmNe pKIk5KlAuNmJO4seqWWBLILhO3kxhMZi071yyT/IH0onpK9UMNRnwftZkxDjDqKL1HTv A1WA== X-Gm-Message-State: ALoCoQmUhW3PzfO/pfOuoC4rDk6RNBrgAtL1a6QO+kR+zHX26mCsNKt3CwamOHDlaXVNENJj1r37 X-Received: by 10.70.90.161 with SMTP id bx1mr6778675pdb.150.1407995057165; Wed, 13 Aug 2014 22:44:17 -0700 (PDT) Received: from localhost ([2001:5a8:4:83c0:9507:378f:a1b0:22f]) by mx.google.com with ESMTPSA id w7sm3954987pbs.74.2014.08.13.22.44.13 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 13 Aug 2014 22:44:15 -0700 (PDT) From: Andy Lutomirski To: kvm@vger.kernel.org, "H. Peter Anvin" , Theodore Ts'o , linux-kernel@vger.kernel.org, Kees Cook , x86@kernel.org Cc: Daniel Borkmann , Srivatsa Vaddagiri , Raghavendra K T , Gleb Natapov , Paolo Bonzini , Andrew Honig , Andy Lutomirski Subject: [PATCH v6 1/7] random: Add and use arch_rng_init Date: Wed, 13 Aug 2014 22:43:55 -0700 Message-Id: <25547b897a7dd34173773e5ee0860720fefcc191.1407994704.git.luto@amacapital.net> X-Mailer: git-send-email 1.9.3 In-Reply-To: References: In-Reply-To: References: Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently, init_std_data contains its own logic for using arch random sources. This replaces that logic with a generic function arch_rng_init 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. Acked-by: Theodore Ts'o 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 71529e1..7673e60 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1246,6 +1246,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 @@ -1261,15 +1265,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_rng_init(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..c8d692e 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_RNG_INIT + +/** + * arch_rng_init() - 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_rng_init(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_RNG_INIT */ + /* Pseudo random number generator from numerical recipes. */ static inline u32 next_pseudo_random32(u32 seed) {