From patchwork Tue Jun 6 17:48:03 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: 9769387 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 260976035D for ; Tue, 6 Jun 2017 17:49:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 210482849E for ; Tue, 6 Jun 2017 17:49:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 156FB284E4; Tue, 6 Jun 2017 17:49:16 +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 874472849E for ; Tue, 6 Jun 2017 17:49:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751677AbdFFRsm (ORCPT ); Tue, 6 Jun 2017 13:48:42 -0400 Received: from frisell.zx2c4.com ([192.95.5.64]:38383 "EHLO frisell.zx2c4.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751670AbdFFRsk (ORCPT ); Tue, 6 Jun 2017 13:48:40 -0400 Received: by frisell.zx2c4.com (ZX2C4 Mail Server) with ESMTP id 59f5e971; Tue, 6 Jun 2017 17:48:14 +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=qA1n hj8o4yOmH47ajW2jNN1/2fA=; b=TiqbgS35zWlI70W+5EyZS8HRWOkcQiAWDg0j VjH3yGZ6F0uC82bpciW183tp9KiEMOS+5MwnlYSlvRWDUbbLFF2pcH6pfoAV8tmK 2Y72lEdx7lztz/HvdPsvh9fzqoR5MpIGzCNGX77KorvkTggTWijT37RVzf1bk7tK tUz/6cKDrHmcvBLQmEoOhlDikfmSUcJTfPzqvYF9O/zE0YJxNee6qZQ8T4rlEdEX 5deyb9kMpGMwvK6qd1dDL+6kMnQhRizA/FPgAGIgW8TLpwfb/tca9HqKSs26eqmV Ypfdll1eChljsJIgZkzq2DYJtndGRbvd4g/i1Wi6Fz83rso/ew== Received: by frisell.zx2c4.com (ZX2C4 Mail Server) with ESMTPSA id 83ad3ae2 (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256:NO); Tue, 6 Jun 2017 17:48:13 +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 , Eric Biggers Cc: "Jason A. Donenfeld" , Marcel Holtmann , Gustavo Padovan , Johan Hedberg Subject: [PATCH v4 12/13] bluetooth/smp: ensure RNG is properly seeded before ECDH use Date: Tue, 6 Jun 2017 19:48:03 +0200 Message-Id: <20170606174804.31124-13-Jason@zx2c4.com> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170606174804.31124-1-Jason@zx2c4.com> References: <20170606174804.31124-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 protocol uses lots of complex cryptography that relies on securely generated random numbers. Thus, it's important that the RNG is actually seeded before use. Fortuantely, it appears we're always operating in process context (there are many GFP_KERNEL allocations and other sleeping operations), and so we can simply demand that the RNG is seeded before we use it. We take two strategies in this commit. The first is for the library code that's called from other modules like hci or mgmt: here we just change the call to get_random_bytes_wait, and return the result of the wait to the caller, along with the other error codes of those functions like usual. Then there's the SMP protocol handler itself, which makes many many many calls to get_random_bytes during different phases. For this, rather than have to change all the calls to get_random_bytes_wait and propagate the error result, it's actually enough to just put a single call to wait_for_random_bytes() at the beginning of the handler, to ensure that all the subsequent invocations are safe, without having to actually change them. Likewise, for the random address changing function, we'd rather know early on in the function whether the RNG initialization has been interrupted, rather than later, so we call wait_for_random_bytes() at the top, so that later on the call to get_random_bytes() is acceptable. Signed-off-by: Jason A. Donenfeld Cc: Marcel Holtmann Cc: Gustavo Padovan Cc: Johan Hedberg --- net/bluetooth/hci_request.c | 6 ++++++ net/bluetooth/smp.c | 18 ++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index b5faff458d8b..4078057c4fd7 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -1406,6 +1406,12 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy, struct hci_dev *hdev = req->hdev; int err; + if (require_privacy) { + err = wait_for_random_bytes(); + if (unlikely(err)) + return err; + } + /* If privacy is enabled use a resolvable private address. If * current RPA has expired or there is something else than * the current RPA in use, then generate a new one. diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 14585edc9439..5fef1bc96f42 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -537,7 +537,9 @@ int smp_generate_rpa(struct hci_dev *hdev, const u8 irk[16], bdaddr_t *rpa) smp = chan->data; - get_random_bytes(&rpa->b[3], 3); + err = get_random_bytes_wait(&rpa->b[3], 3); + if (unlikely(err)) + return err; rpa->b[5] &= 0x3f; /* Clear two most significant bits */ rpa->b[5] |= 0x40; /* Set second most significant bit */ @@ -570,7 +572,9 @@ int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16]) } else { while (true) { /* Seed private key with random number */ - get_random_bytes(smp->local_sk, 32); + err = get_random_bytes_wait(smp->local_sk, 32); + if (unlikely(err)) + return err; /* Generate local key pair for Secure Connections */ if (!generate_ecdh_keys(smp->local_pk, smp->local_sk)) @@ -589,7 +593,9 @@ int smp_generate_oob(struct hci_dev *hdev, u8 hash[16], u8 rand[16]) SMP_DBG("OOB Public Key Y: %32phN", smp->local_pk + 32); SMP_DBG("OOB Private Key: %32phN", smp->local_sk); - get_random_bytes(smp->local_rand, 16); + err = get_random_bytes_wait(smp->local_rand, 16); + if (unlikely(err)) + return err; err = smp_f4(smp->tfm_cmac, smp->local_pk, smp->local_pk, smp->local_rand, 0, hash); @@ -2831,7 +2837,11 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) struct hci_conn *hcon = conn->hcon; struct smp_chan *smp; __u8 code, reason; - int err = 0; + int err; + + err = wait_for_random_bytes(); + if (unlikely(err)) + return err; if (skb->len < 1) return -EILSEQ;