From patchwork Mon Sep 18 12:58:07 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lubomir Rintel X-Patchwork-Id: 814907 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.infradead.org (client-ip=65.50.211.133; helo=bombadil.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="jk8ttvfW"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3xwmLr6rD9z9s7c for ; Mon, 18 Sep 2017 23:00:04 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=ujMmwg5BwAbV6OaddPSgJcEUKX6kdlxkSdalRYbAJiI=; b=jk8 ttvfWHzKFafw1/VbwHSY73B4LSNmYUSA2n6u8TDKqDSkqlyGfTlnT3VU5/bdm+q9YAX5tOsZqXr4O v6lZEn4boTMcEbwGvCQxFlr6SK05bqq3PdvrGvNJPkEPOeT5u55IFo4L4dPHAfq+iJDjKM3K90R6M WkLGZ7aVQYHyhBtURH3hiv6bSD3CF7zAznUQjmmL9Gbb3DGDltdzfre1PIPl6coylispleuGb/SWw foRH7vIDjOcmvLM3D8SfotxrbUTpvR4JZ9ARjIAFIMRrjJ0inLIAoUpAWuBb7hCq7K1qRHXSSJ6Oa DLI95ywQGturXRAIyNHAVcfZeUh5KDA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dtve0-0003XM-KC; Mon, 18 Sep 2017 12:59:24 +0000 Received: from shell.v3.sk ([92.60.52.57]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dtvda-0003TB-Qq for hostap@lists.infradead.org; Mon, 18 Sep 2017 12:59:01 +0000 Received: from localhost (localhost [127.0.0.1]) by zimbra.v3.sk (Postfix) with ESMTP id 9667E91230 for ; Mon, 18 Sep 2017 14:58:32 +0200 (CEST) Received: from shell.v3.sk ([127.0.0.1]) by localhost (zimbra.v3.sk [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id rKL7CUxXhyhX; Mon, 18 Sep 2017 14:58:23 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by zimbra.v3.sk (Postfix) with ESMTP id B20B991236; Mon, 18 Sep 2017 14:58:22 +0200 (CEST) X-Virus-Scanned: amavisd-new at zimbra.v3.sk Received: from shell.v3.sk ([127.0.0.1]) by localhost (zimbra.v3.sk [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id vfyBdu1SXjWk; Mon, 18 Sep 2017 14:58:20 +0200 (CEST) Received: from belphegor.brq.redhat.com (nat-pool-brq-t.redhat.com [213.175.37.10]) by zimbra.v3.sk (Postfix) with ESMTPSA id 3C4E791232; Mon, 18 Sep 2017 14:58:20 +0200 (CEST) From: Lubomir Rintel To: hostap@lists.infradead.org Subject: [PATCH] crypto: add option to use getrandom() Date: Mon, 18 Sep 2017 14:58:07 +0200 Message-Id: <20170918125807.27940-1-lkundrak@v3.sk> X-Mailer: git-send-email 2.13.5 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170918_055859_195055_37DFE16C X-CRM114-Status: GOOD ( 16.02 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Lubomir Rintel MIME-Version: 1.0 Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org According to random(4) manual, /dev/random is essentially deprecated on Linux for quite some time: The /dev/random interface is considered a legacy interface, and /dev/urandom is preferred and sufficient in all use cases, with the exception of applications which require randomness during early boot time; for these applications, getrandom(2) must be used instead, because it will block until the entropy pool is initialized. An attempt to use it would cause unnecessary blocking on machines without a good hwrng even when it shouldn't be needed. Since Linux 3.17, a getrandom(2) call is available that will block only until the randomness pool has been seeded. It is probably not a good default yet as it requires a fairly recent kernel and glibc (3.17 and 2.25 respectively). Signed-off-by: Lubomir Rintel --- hostapd/Makefile | 3 +++ hostapd/defconfig | 5 ++++ src/crypto/random.c | 67 ++++++++++++++++++++++++++++++++++-------------- wpa_supplicant/Makefile | 3 +++ wpa_supplicant/defconfig | 5 ++++ 5 files changed, 64 insertions(+), 19 deletions(-) diff --git a/hostapd/Makefile b/hostapd/Makefile index c54de3917..842fe97b5 100644 --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -1026,6 +1026,9 @@ CFLAGS += -DCONFIG_ECC endif ifdef CONFIG_NO_RANDOM_POOL +ifdef CONFIG_GETRANDOM +CFLAGS += -DCONFIG_GETRANDOM +endif CFLAGS += -DCONFIG_NO_RANDOM_POOL else OBJS += ../src/crypto/random.o diff --git a/hostapd/defconfig b/hostapd/defconfig index 26be9f8d4..a2e2b998b 100644 --- a/hostapd/defconfig +++ b/hostapd/defconfig @@ -252,6 +252,11 @@ CONFIG_IPV6=y # requirements described above. #CONFIG_NO_RANDOM_POOL=y +# Should we attempt to use the getrandom(2) call that provides more reliable +# yet secure randomness source than /dev/random on Linux 3.17 and newer. +# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. +#CONFIG_GETRANDOM=y + # Should we use poll instead of select? Select is used by default. #CONFIG_ELOOP_POLL=y diff --git a/src/crypto/random.c b/src/crypto/random.c index fb9241762..5cb852853 100644 --- a/src/crypto/random.c +++ b/src/crypto/random.c @@ -25,6 +25,9 @@ #include "utils/includes.h" #ifdef __linux__ #include +#ifdef CONFIG_GETRANDOM +#include +#endif /* CONFIG_GETRANDOM */ #endif /* __linux__ */ #include "utils/common.h" @@ -229,30 +232,49 @@ int random_pool_ready(void) return 1; /* Already initialized - good to continue */ /* - * Try to fetch some more data from the kernel high quality - * /dev/random. There may not be enough data available at this point, + * Try to fetch some more data from the kernel high quality RNG + * There may not be enough data available at this point, * so use non-blocking read to avoid blocking the application * completely. */ - fd = open("/dev/random", O_RDONLY | O_NONBLOCK); - if (fd < 0) { - wpa_printf(MSG_ERROR, "random: Cannot open /dev/random: %s", - strerror(errno)); - return -1; - } - res = read(fd, dummy_key + dummy_key_avail, - sizeof(dummy_key) - dummy_key_avail); +#ifdef CONFIG_GETRANDOM + res = getrandom(dummy_key + dummy_key_avail, + sizeof(dummy_key) - dummy_key_avail, GRND_NONBLOCK); if (res < 0) { - wpa_printf(MSG_ERROR, "random: Cannot read from /dev/random: " - "%s", strerror(errno)); - res = 0; + if (errno == ENOSYS) { + wpa_printf(MSG_DEBUG, "random: getrandom() not supported, falling " + "back to /dev/random"); + } else { + wpa_printf(MSG_ERROR, "random: no data from getrandom(): " + "%s", strerror(errno)); + res = 0; + } } - wpa_printf(MSG_DEBUG, "random: Got %u/%u bytes from " - "/dev/random", (unsigned) res, +#else + res = -1; +#endif /* CONFIG_GETRANDOM */ + if (res < 0) { + fd = open("/dev/random", O_RDONLY | O_NONBLOCK); + if (fd < 0) { + wpa_printf(MSG_ERROR, "random: Cannot open /dev/random: %s", + strerror(errno)); + return -1; + } + + res = read(fd, dummy_key + dummy_key_avail, + sizeof(dummy_key) - dummy_key_avail); + if (res < 0) { + wpa_printf(MSG_ERROR, "random: Cannot read from /dev/random: " + "%s", strerror(errno)); + res = 0; + } + close(fd); + } + + wpa_printf(MSG_DEBUG, "random: Got %u/%u random bytes", (unsigned) res, (unsigned) (sizeof(dummy_key) - dummy_key_avail)); dummy_key_avail += res; - close(fd); if (dummy_key_avail == sizeof(dummy_key)) { if (own_pool_ready < MIN_READY_MARK) @@ -262,7 +284,7 @@ int random_pool_ready(void) } wpa_printf(MSG_INFO, "random: Only %u/%u bytes of strong " - "random data available from /dev/random", + "random data available", (unsigned) dummy_key_avail, (unsigned) sizeof(dummy_key)); if (own_pool_ready >= MIN_READY_MARK || @@ -272,8 +294,8 @@ int random_pool_ready(void) return 1; } - wpa_printf(MSG_INFO, "random: Not enough entropy pool available for " - "secure operations"); + wpa_printf(MSG_INFO, "random: Not enough entropy pool available " + "from for secure operations"); return 0; #else /* __linux__ */ /* TODO: could do similar checks on non-Linux platforms */ @@ -415,6 +437,13 @@ void random_init(const char *entropy_file) if (random_fd >= 0) return; +#ifdef CONFIG_GETRANDOM + if (getrandom(NULL, 0, GRND_NONBLOCK) == 0 || errno != ENOSYS) { + wpa_printf(MSG_INFO, "random: getrandom() support available"); + return; + } +#endif /* CONFIG_GETRANDOM */ + random_fd = open("/dev/random", O_RDONLY | O_NONBLOCK); if (random_fd < 0) { wpa_printf(MSG_ERROR, "random: Cannot open /dev/random: %s", diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index b62b898d6..f629fc200 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -1476,6 +1476,9 @@ endif ifdef CONFIG_NO_RANDOM_POOL CFLAGS += -DCONFIG_NO_RANDOM_POOL else +ifdef CONFIG_GETRANDOM +CFLAGS += -DCONFIG_GETRANDOM +endif OBJS += ../src/crypto/random.o endif diff --git a/wpa_supplicant/defconfig b/wpa_supplicant/defconfig index 1797ad359..c35272eb2 100644 --- a/wpa_supplicant/defconfig +++ b/wpa_supplicant/defconfig @@ -456,6 +456,11 @@ CONFIG_PEERKEY=y # that meet the requirements described above. #CONFIG_NO_RANDOM_POOL=y +# Should we attempt to use the getrandom(2) call that provides more reliable +# yet secure randomness source than /dev/random on Linux 3.17 and newer. +# Requires glibc 2.25 to build, falls back to /dev/random if unavailable. +#CONFIG_GETRANDOM=y + # IEEE 802.11n (High Throughput) support (mainly for AP mode) #CONFIG_IEEE80211N=y