From patchwork Fri Dec 16 03:03:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Jason A. Donenfeld" X-Patchwork-Id: 9477233 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id AB0BE60827 for ; Fri, 16 Dec 2016 03:04:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9EAFA288AD for ; Fri, 16 Dec 2016 03:04:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 901FF288AF; Fri, 16 Dec 2016 03:04:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 9EEB6288AD for ; Fri, 16 Dec 2016 03:04:23 +0000 (UTC) Received: (qmail 26328 invoked by uid 550); 16 Dec 2016 03:04:07 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: kernel-hardening@lists.openwall.com Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 25673 invoked from network); 16 Dec 2016 03:03:58 -0000 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=zx2c4.com; h=from:to:cc :subject:date:message-id:in-reply-to:references; s=mail; bh=wQ/W Ip9s+Zlh9N03zEsm16X+gAY=; b=OzfrEAnebxrDu7OsezKeqbqAcO4kJjpg0/Wm OXJzx1ByO1bwzpk6V34dhK+WJKlD6m9rNZ2uJJ3SVcWWdervCgkcZk1AHeTCZ1aW rqDcPI2ITQs6oUvOwOjJ+9ibHjpdMf/aKHaYxwScOWh2rQx47CPiFrbG7TMhXPdg Q3OBQfWbBfuC5ceqyQKoRGbAm09IrGR8KIdH7r8PMdYRLZNl+fqn6liUvjVoCfRT YilFe5EH6MN+vUe2lP5YGZ1ZbPbEn7plIvQvv+okX2nU/MrocQvmZFa9gtp97u4q OY4L6AYdQ5epQ2hszSNEapOGLXlvjjQotbQMRDADj6Y+tklgEA== From: "Jason A. Donenfeld" To: Netdev , kernel-hardening@lists.openwall.com, LKML , linux-crypto@vger.kernel.org, David Laight , Ted Tso , Hannes Frederic Sowa , Linus Torvalds , Eric Biggers , Tom Herbert , George Spelvin , Vegard Nossum , ak@linux.intel.com, davem@davemloft.net, luto@amacapital.net Cc: "Jason A. Donenfeld" , Jean-Philippe Aumasson Date: Fri, 16 Dec 2016 04:03:26 +0100 Message-Id: <20161216030328.11602-4-Jason@zx2c4.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20161216030328.11602-1-Jason@zx2c4.com> References: <20161215203003.31989-1-Jason@zx2c4.com> <20161216030328.11602-1-Jason@zx2c4.com> Subject: [kernel-hardening] [PATCH v6 3/5] random: use SipHash in place of MD5 X-Virus-Scanned: ClamAV using ClamSMTP This duplicates the current algorithm for get_random_int/long, but uses siphash instead. This comes with several benefits. It's certainly faster and more cryptographically secure than MD5. This patch also separates hashed fields into three values instead of one, in order to increase diffusion. The previous MD5 algorithm used a per-cpu MD5 state, which caused successive calls to the function to chain upon each other. While it's not entirely clear that this kind of chaining is absolutely necessary when using a secure PRF like siphash, it can't hurt, and the timing of the call chain does add a degree of natural entropy. So, in keeping with this design, instead of the massive per-cpu 64-byte MD5 state, there is instead a per-cpu previously returned value for chaining. The speed benefits are substantial: | siphash | md5 | speedup | ------------------------------ get_random_long | 137130 | 415983 | 3.03x | get_random_int | 86384 | 343323 | 3.97x | Signed-off-by: Jason A. Donenfeld Cc: Jean-Philippe Aumasson Cc: Ted Tso --- drivers/char/random.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index d6876d506220..a51f0ff43f00 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -262,6 +262,7 @@ #include #include #include +#include #include #include @@ -2042,7 +2043,7 @@ struct ctl_table random_table[] = { }; #endif /* CONFIG_SYSCTL */ -static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; +static siphash_key_t random_int_secret; int random_int_secret_init(void) { @@ -2050,8 +2051,7 @@ int random_int_secret_init(void) return 0; } -static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash) - __aligned(sizeof(unsigned long)); +static DEFINE_PER_CPU(u64, get_random_int_chaining); /* * Get a random word for internal kernel use only. Similar to urandom but @@ -2061,19 +2061,16 @@ static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash) */ unsigned int get_random_int(void) { - __u32 *hash; unsigned int ret; + u64 *chaining; if (arch_get_random_int(&ret)) return ret; - hash = get_cpu_var(get_random_int_hash); - - hash[0] += current->pid + jiffies + random_get_entropy(); - md5_transform(hash, random_int_secret); - ret = hash[0]; - put_cpu_var(get_random_int_hash); - + chaining = &get_cpu_var(get_random_int_chaining); + ret = *chaining = siphash_3u64(*chaining, jiffies, random_get_entropy() + + current->pid, random_int_secret); + put_cpu_var(get_random_int_chaining); return ret; } EXPORT_SYMBOL(get_random_int); @@ -2083,19 +2080,16 @@ EXPORT_SYMBOL(get_random_int); */ unsigned long get_random_long(void) { - __u32 *hash; unsigned long ret; + u64 *chaining; if (arch_get_random_long(&ret)) return ret; - hash = get_cpu_var(get_random_int_hash); - - hash[0] += current->pid + jiffies + random_get_entropy(); - md5_transform(hash, random_int_secret); - ret = *(unsigned long *)hash; - put_cpu_var(get_random_int_hash); - + chaining = &get_cpu_var(get_random_int_chaining); + ret = *chaining = siphash_3u64(*chaining, jiffies, random_get_entropy() + + current->pid, random_int_secret); + put_cpu_var(get_random_int_chaining); return ret; } EXPORT_SYMBOL(get_random_long);