From patchwork Fri Feb 26 11:44:09 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milan Broz X-Patchwork-Id: 8436111 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Original-To: patchwork-linux-crypto@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 2154E9F52D for ; Fri, 26 Feb 2016 11:44:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1E91A2020F for ; Fri, 26 Feb 2016 11:44:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 01C752037C for ; Fri, 26 Feb 2016 11:44:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751124AbcBZLo1 (ORCPT ); Fri, 26 Feb 2016 06:44:27 -0500 Received: from mail-wm0-f65.google.com ([74.125.82.65]:33699 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751185AbcBZLoZ (ORCPT ); Fri, 26 Feb 2016 06:44:25 -0500 Received: by mail-wm0-f65.google.com with SMTP id c200so8620256wme.0; Fri, 26 Feb 2016 03:44:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=YpkjftRGttvugDFgbW6tOR/Yo+h/h4nA4Vvao2nYfSA=; b=B5U8dq/OdcW6TRPSgtMQrtxX337tDqson+AboVh7E/k6p6HlAvBj0vsexYJgLRRMe5 drxOiPv4qZIYNJPSCL3mH8bJPyyotngrjhlYUAEn6Z4+U5Sof/xRwpwBLL4d4KwVQ68l mOPSfDt68J3Srt/bjq04+Wsm4B6cpqUENsGNRlnFGi1XhwlJv4P8AByl+9zpOMYBl/Qa b65ipeaq98dY4LbBzgsfsYJgMCJZKCb1BRFMbGzicVg0K+rG9F+SkdLM57xEA0wC51Gx 1zZ66IL2Lnje8oZWEurtVeReV4SxgwnFwMtLg8vx8RqqfaD/Br2veeQ7ubxmvxMFvvLt xe7w== 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; bh=YpkjftRGttvugDFgbW6tOR/Yo+h/h4nA4Vvao2nYfSA=; b=Ch3u6UrMnEa2H/m1OqOwLKkjMeiRKqJp9gnZFuaFCbxhLeg5m17hcckXd6Y0nkBfea h9ppUSDHQxXJu2QOOJ39lU0W8lGFyxpbu1LkcLabLcKUe5kM5cAms2ERG/AtrSTEVLky oeCjo/obbw6Hb1o0IRJeIYpaJk9QwKwq0+K1QX7SDToyQQylZusoGx+/YMQAVGs96EJ0 wvYh19FP/NUAy3EsSjU9A5kB8Y9mE0rP4ybKhpAtZfEJ9gfCGsuDzqvxfLYVmqC1F5pY XKJ+wB3XmPD6kKO6ja7OLVHF/ws8ANf1Esi/PcYJfzR5gihMNrkOm5VU4hBhruygTjB5 Kmqw== X-Gm-Message-State: AD7BkJKgfoYhG4aemmJ/D5hWRAsFcLZ4eq9/s6/+qxqROYnOPR7HUpIjDbSM/xRSNTCV+g== X-Received: by 10.194.86.130 with SMTP id p2mr1160307wjz.93.1456487064258; Fri, 26 Feb 2016 03:44:24 -0800 (PST) Received: from merlot.mazyland.net (hector.fi.muni.cz. [147.251.42.24]) by smtp.gmail.com with ESMTPSA id j10sm12058768wjb.46.2016.02.26.03.44.23 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 26 Feb 2016 03:44:23 -0800 (PST) From: Milan Broz To: linux-crypto@vger.kernel.org Cc: stable@vger.kernel.org, Herbert Xu Subject: [PATCH 2/4] crypto: algif_skcipher - Add nokey compatibility path Date: Fri, 26 Feb 2016 12:44:09 +0100 Message-Id: <1456487051-14652-2-git-send-email-gmazyland@gmail.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1456487051-14652-1-git-send-email-gmazyland@gmail.com> References: <56D0361B.8040301@gmail.com> <1456487051-14652-1-git-send-email-gmazyland@gmail.com> Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, 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 From: Herbert Xu commit a0fa2d037129a9849918a92d91b79ed6c7bd2818 upstream. This patch adds a compatibility path to support old applications that do acept(2) before setkey. Cc: stable@vger.kernel.org Signed-off-by: Herbert Xu --- crypto/algif_skcipher.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 144 insertions(+), 5 deletions(-) diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 1c9879d..566df2c 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -755,6 +755,99 @@ static struct proto_ops algif_skcipher_ops = { .poll = skcipher_poll, }; +static int skcipher_check_key(struct socket *sock) +{ + int err; + struct sock *psk; + struct alg_sock *pask; + struct skcipher_tfm *tfm; + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + + if (ask->refcnt) + return 0; + + psk = ask->parent; + pask = alg_sk(ask->parent); + tfm = pask->private; + + err = -ENOKEY; + lock_sock(psk); + if (!tfm->has_key) + goto unlock; + + if (!pask->refcnt++) + sock_hold(psk); + + ask->refcnt = 1; + sock_put(psk); + + err = 0; + +unlock: + release_sock(psk); + + return err; +} + +static int skcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg, + size_t size) +{ + int err; + + err = skcipher_check_key(sock); + if (err) + return err; + + return skcipher_sendmsg(sock, msg, size); +} + +static ssize_t skcipher_sendpage_nokey(struct socket *sock, struct page *page, + int offset, size_t size, int flags) +{ + int err; + + err = skcipher_check_key(sock); + if (err) + return err; + + return skcipher_sendpage(sock, page, offset, size, flags); +} + +static int skcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg, + size_t ignored, int flags) +{ + int err; + + err = skcipher_check_key(sock); + if (err) + return err; + + return skcipher_recvmsg(sock, msg, ignored, flags); +} + +static struct proto_ops algif_skcipher_ops_nokey = { + .family = PF_ALG, + + .connect = sock_no_connect, + .socketpair = sock_no_socketpair, + .getname = sock_no_getname, + .ioctl = sock_no_ioctl, + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, + .getsockopt = sock_no_getsockopt, + .mmap = sock_no_mmap, + .bind = sock_no_bind, + .accept = sock_no_accept, + .setsockopt = sock_no_setsockopt, + + .release = af_alg_release, + .sendmsg = skcipher_sendmsg_nokey, + .sendpage = skcipher_sendpage_nokey, + .recvmsg = skcipher_recvmsg_nokey, + .poll = skcipher_poll, +}; + static void *skcipher_bind(const char *name, u32 type, u32 mask) { struct skcipher_tfm *tfm; @@ -804,7 +897,7 @@ static void skcipher_wait(struct sock *sk) msleep(100); } -static void skcipher_sock_destruct(struct sock *sk) +static void skcipher_sock_destruct_common(struct sock *sk) { struct alg_sock *ask = alg_sk(sk); struct skcipher_ctx *ctx = ask->private; @@ -816,10 +909,33 @@ static void skcipher_sock_destruct(struct sock *sk) skcipher_free_sgl(sk); sock_kzfree_s(sk, ctx->iv, crypto_ablkcipher_ivsize(tfm)); sock_kfree_s(sk, ctx, ctx->len); +} + +static void skcipher_sock_destruct(struct sock *sk) +{ + skcipher_sock_destruct_common(sk); af_alg_release_parent(sk); } -static int skcipher_accept_parent(void *private, struct sock *sk) +static void skcipher_release_parent_nokey(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + + if (!ask->refcnt) { + sock_put(ask->parent); + return; + } + + af_alg_release_parent(sk); +} + +static void skcipher_sock_destruct_nokey(struct sock *sk) +{ + skcipher_sock_destruct_common(sk); + skcipher_release_parent_nokey(sk); +} + +static int skcipher_accept_parent_common(void *private, struct sock *sk) { struct skcipher_ctx *ctx; struct alg_sock *ask = alg_sk(sk); @@ -827,9 +943,6 @@ static int skcipher_accept_parent(void *private, struct sock *sk) struct crypto_ablkcipher *skcipher = tfm->skcipher; unsigned int len = sizeof(*ctx) + crypto_ablkcipher_reqsize(skcipher); - if (!tfm->has_key) - return -ENOKEY; - ctx = sock_kmalloc(sk, len, GFP_KERNEL); if (!ctx) return -ENOMEM; @@ -863,12 +976,38 @@ static int skcipher_accept_parent(void *private, struct sock *sk) return 0; } +static int skcipher_accept_parent(void *private, struct sock *sk) +{ + struct skcipher_tfm *tfm = private; + + if (!tfm->has_key) + return -ENOKEY; + + return skcipher_accept_parent_common(private, sk); +} + +static int skcipher_accept_parent_nokey(void *private, struct sock *sk) +{ + int err; + + err = skcipher_accept_parent_common(private, sk); + if (err) + goto out; + + sk->sk_destruct = skcipher_sock_destruct_nokey; + +out: + return err; +} + static const struct af_alg_type algif_type_skcipher = { .bind = skcipher_bind, .release = skcipher_release, .setkey = skcipher_setkey, .accept = skcipher_accept_parent, + .accept_nokey = skcipher_accept_parent_nokey, .ops = &algif_skcipher_ops, + .ops_nokey = &algif_skcipher_ops_nokey, .name = "skcipher", .owner = THIS_MODULE };