From patchwork Tue Jun 6 00:50:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Jason A. Donenfeld" X-Patchwork-Id: 9767793 X-Patchwork-Delegate: herbert@gondor.apana.org.au 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 5DBF06034B for ; Tue, 6 Jun 2017 00:54:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 537FB27F8F for ; Tue, 6 Jun 2017 00:54:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3DE3D2845E; Tue, 6 Jun 2017 00:54:19 +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=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B64B127F8F for ; Tue, 6 Jun 2017 00:54:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751294AbdFFAv1 (ORCPT ); Mon, 5 Jun 2017 20:51:27 -0400 Received: from frisell.zx2c4.com ([192.95.5.64]:57707 "EHLO frisell.zx2c4.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751194AbdFFAvZ (ORCPT ); Mon, 5 Jun 2017 20:51:25 -0400 Received: by frisell.zx2c4.com (ZX2C4 Mail Server) with ESMTP id 78326675; Tue, 6 Jun 2017 00:51:09 +0000 (UTC) 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=JuxD nzJcgnwltFCKTQkK5UfccUM=; b=kgLalxDFmjgBXDMfyNC1DC7mjOWsIpfmmDJR cRRoPoabAnrRmCFCYn59stvvbNxnQdufwv07P8uifsE7WKkKE2DZiA8jG+8RW9sH rY9RP41cc68A5ykxTVQp8L0My9Ha3EahcX2MY3cMw/0CcP0DjkRil8NprrvvKDb8 8QrShknHSYTIpuzvsmBH8N1IfLyg68KSOCSjY17Squnao/z6Px4q2aL+pbU2vmKF fJZRxfUMC/hhbr1WfkrvV/Oh8fMzBWMWBjOBd7UJNIcb/hpJuDuBr2p7MUvyxaql lXqY5bLeneg3+r0cZhkSFTWVbOxUrgxt5hKn0BKmMYy16Hj+mA== Received: by frisell.zx2c4.com (ZX2C4 Mail Server) with ESMTPSA id 3fb88a8f (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256:NO); Tue, 6 Jun 2017 00:51:08 +0000 (UTC) From: "Jason A. Donenfeld" To: Theodore Ts'o , Linux Crypto Mailing List , LKML , kernel-hardening@lists.openwall.com, Greg Kroah-Hartman , David Miller Cc: "Jason A. Donenfeld" Subject: [PATCH v3 01/13] random: add synchronous API for the urandom pool Date: Tue, 6 Jun 2017 02:50:56 +0200 Message-Id: <20170606005108.5646-2-Jason@zx2c4.com> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170606005108.5646-1-Jason@zx2c4.com> References: <20170606005108.5646-1-Jason@zx2c4.com> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This enables users of get_random_{bytes,u32,u64,int,long} to wait until the pool is ready before using this function, in case they actually want to have reliable randomness. Signed-off-by: Jason A. Donenfeld --- drivers/char/random.c | 41 +++++++++++++++++++++++++++++++---------- include/linux/random.h | 1 + 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index 0ab024918907..035a5d7c06bd 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -844,11 +844,6 @@ static void crng_reseed(struct crng_state *crng, struct entropy_store *r) spin_unlock_irqrestore(&primary_crng.lock, flags); } -static inline void crng_wait_ready(void) -{ - wait_event_interruptible(crng_init_wait, crng_ready()); -} - static void _extract_crng(struct crng_state *crng, __u8 out[CHACHA20_BLOCK_SIZE]) { @@ -1466,7 +1461,10 @@ static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf, * number of good random numbers, suitable for key generation, seeding * TCP sequence numbers, etc. It does not rely on the hardware random * number generator. For random bytes direct from the hardware RNG - * (when available), use get_random_bytes_arch(). + * (when available), use get_random_bytes_arch(). In order to ensure + * that the randomness provided by this function is okay, the function + * wait_for_random_bytes() should be called and return 0 at least once + * at any point prior. */ void get_random_bytes(void *buf, int nbytes) { @@ -1496,6 +1494,24 @@ void get_random_bytes(void *buf, int nbytes) EXPORT_SYMBOL(get_random_bytes); /* + * Wait for the urandom pool to be seeded and thus guaranteed to supply + * cryptographically secure random numbers. This applies to: the /dev/urandom + * device, the get_random_bytes function, and the get_random_{u32,u64,int,long} + * family of functions. Using any of these functions without first calling + * this function forfeits the guarantee of security. + * + * Returns: 0 if the urandom pool has been seeded. + * -ERESTARTSYS if the function was interrupted by a signal. + */ +int wait_for_random_bytes(void) +{ + if (likely(crng_ready())) + return 0; + return wait_event_interruptible(crng_init_wait, crng_ready()); +} +EXPORT_SYMBOL(wait_for_random_bytes); + +/* * Add a callback function that will be invoked when the nonblocking * pool is initialised. * @@ -1849,6 +1865,8 @@ const struct file_operations urandom_fops = { SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, unsigned int, flags) { + int ret; + if (flags & ~(GRND_NONBLOCK|GRND_RANDOM)) return -EINVAL; @@ -1861,9 +1879,9 @@ SYSCALL_DEFINE3(getrandom, char __user *, buf, size_t, count, if (!crng_ready()) { if (flags & GRND_NONBLOCK) return -EAGAIN; - crng_wait_ready(); - if (signal_pending(current)) - return -ERESTARTSYS; + ret = wait_for_random_bytes(); + if (unlikely(ret)) + return ret; } return urandom_read(NULL, buf, count, NULL); } @@ -2023,7 +2041,10 @@ struct batched_entropy { /* * Get a random word for internal kernel use only. The quality of the random * number is either as good as RDRAND or as good as /dev/urandom, with the - * goal of being quite fast and not depleting entropy. + * goal of being quite fast and not depleting entropy. In order to ensure + * that the randomness provided by this function is okay, the function + * wait_for_random_bytes() should be called and return 0 at least once + * at any point prior. */ static DEFINE_PER_CPU(struct batched_entropy, batched_entropy_u64); u64 get_random_u64(void) diff --git a/include/linux/random.h b/include/linux/random.h index ed5c3838780d..e29929347c95 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -34,6 +34,7 @@ extern void add_input_randomness(unsigned int type, unsigned int code, extern void add_interrupt_randomness(int irq, int irq_flags) __latent_entropy; extern void get_random_bytes(void *buf, int nbytes); +extern int wait_for_random_bytes(void); extern int add_random_ready_callback(struct random_ready_callback *rdy); extern void del_random_ready_callback(struct random_ready_callback *rdy); extern void get_random_bytes_arch(void *buf, int nbytes);