From: Tadeusz Struk <tadeusz.struk@intel.com>
To: dhowells@redhat.com
Cc: herbert@gondor.apana.org.au, tadeusz.struk@intel.com,
smueller@chronox.de, linux-api@vger.kernel.org,
marcel@holtmann.org, linux-kernel@vger.kernel.org,
keyrings@vger.kernel.org, linux-crypto@vger.kernel.org,
dwmw2@infradead.org, davem@davemloft.net
Subject: [PATCH v6 5/6] crypto: algif_akcipher - add ops_nokey
Date: Sat, 14 May 2016 21:17:13 -0700 [thread overview]
Message-ID: <20160515041713.15888.29635.stgit@tstruk-mobl1> (raw)
In-Reply-To: <20160515041645.15888.94903.stgit@tstruk-mobl1>
Similar to algif_skcipher and algif_hash, algif_akcipher needs
to prevent user space from using the interface in an improper way.
This patch adds nokey ops handlers, which do just that.
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
crypto/algif_akcipher.c | 159 +++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 152 insertions(+), 7 deletions(-)
diff --git a/crypto/algif_akcipher.c b/crypto/algif_akcipher.c
index 6342b6e..e00793d 100644
--- a/crypto/algif_akcipher.c
+++ b/crypto/algif_akcipher.c
@@ -27,6 +27,11 @@ struct akcipher_sg_list {
struct scatterlist sg[ALG_MAX_PAGES];
};
+struct akcipher_tfm {
+ struct crypto_akcipher *akcipher;
+ bool has_key;
+};
+
struct akcipher_ctx {
struct akcipher_sg_list tsgl;
struct af_alg_sgl rsgl[ALG_MAX_PAGES];
@@ -450,25 +455,151 @@ static struct proto_ops algif_akcipher_ops = {
.poll = akcipher_poll,
};
+static int akcipher_check_key(struct socket *sock)
+{
+ int err = 0;
+ struct sock *psk;
+ struct alg_sock *pask;
+ struct akcipher_tfm *tfm;
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
+
+ lock_sock(sk);
+ if (ask->refcnt)
+ goto unlock_child;
+
+ psk = ask->parent;
+ pask = alg_sk(ask->parent);
+ tfm = pask->private;
+
+ err = -ENOKEY;
+ lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
+ if (!tfm->has_key)
+ goto unlock;
+
+ if (!pask->refcnt++)
+ sock_hold(psk);
+
+ ask->refcnt = 1;
+ sock_put(psk);
+
+ err = 0;
+
+unlock:
+ release_sock(psk);
+unlock_child:
+ release_sock(sk);
+
+ return err;
+}
+
+static int akcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
+ size_t size)
+{
+ int err;
+
+ err = akcipher_check_key(sock);
+ if (err)
+ return err;
+
+ return akcipher_sendmsg(sock, msg, size);
+}
+
+static ssize_t akcipher_sendpage_nokey(struct socket *sock, struct page *page,
+ int offset, size_t size, int flags)
+{
+ int err;
+
+ err = akcipher_check_key(sock);
+ if (err)
+ return err;
+
+ return akcipher_sendpage(sock, page, offset, size, flags);
+}
+
+static int akcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
+ size_t ignored, int flags)
+{
+ int err;
+
+ err = akcipher_check_key(sock);
+ if (err)
+ return err;
+
+ return akcipher_recvmsg(sock, msg, ignored, flags);
+}
+
+static struct proto_ops algif_akcipher_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 = akcipher_sendmsg_nokey,
+ .sendpage = akcipher_sendpage_nokey,
+ .recvmsg = akcipher_recvmsg_nokey,
+ .poll = akcipher_poll,
+};
+
static void *akcipher_bind(const char *name, u32 type, u32 mask)
{
- return crypto_alloc_akcipher(name, type, mask);
+ struct akcipher_tfm *tfm;
+ struct crypto_akcipher *akcipher;
+
+ tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
+ if (!tfm)
+ return ERR_PTR(-ENOMEM);
+
+ akcipher = crypto_alloc_akcipher(name, type, mask);
+ if (IS_ERR(akcipher)) {
+ kfree(tfm);
+ return ERR_CAST(akcipher);
+ }
+
+ tfm->akcipher = akcipher;
+ return tfm;
}
static void akcipher_release(void *private)
{
- crypto_free_akcipher(private);
+ struct akcipher_tfm *tfm = private;
+ struct crypto_akcipher *akcipher = tfm->akcipher;
+
+ crypto_free_akcipher(akcipher);
+ kfree(tfm);
}
static int akcipher_setprivkey(void *private, const u8 *key,
unsigned int keylen)
{
- return crypto_akcipher_set_priv_key(private, key, keylen);
+ struct akcipher_tfm *tfm = private;
+ struct crypto_akcipher *akcipher = tfm->akcipher;
+ int err;
+
+ err = crypto_akcipher_set_priv_key(akcipher, key, keylen);
+ tfm->has_key = !err;
+ return err;
}
static int akcipher_setpubkey(void *private, const u8 *key, unsigned int keylen)
{
- return crypto_akcipher_set_pub_key(private, key, keylen);
+ struct akcipher_tfm *tfm = private;
+ struct crypto_akcipher *akcipher = tfm->akcipher;
+ int err;
+
+ err = crypto_akcipher_set_pub_key(akcipher, key, keylen);
+ tfm->has_key = !err;
+ return err;
}
static void akcipher_sock_destruct(struct sock *sk)
@@ -481,11 +612,13 @@ static void akcipher_sock_destruct(struct sock *sk)
af_alg_release_parent(sk);
}
-static int akcipher_accept_parent(void *private, struct sock *sk)
+static int akcipher_accept_parent_nokey(void *private, struct sock *sk)
{
struct akcipher_ctx *ctx;
struct alg_sock *ask = alg_sk(sk);
- unsigned int len = sizeof(*ctx) + crypto_akcipher_reqsize(private);
+ struct akcipher_tfm *tfm = private;
+ struct crypto_akcipher *akcipher = tfm->akcipher;
+ unsigned int len = sizeof(*ctx) + crypto_akcipher_reqsize(akcipher);
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
if (!ctx)
@@ -503,7 +636,7 @@ static int akcipher_accept_parent(void *private, struct sock *sk)
ask->private = ctx;
- akcipher_request_set_tfm(&ctx->req, private);
+ akcipher_request_set_tfm(&ctx->req, akcipher);
akcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
af_alg_complete, &ctx->completion);
@@ -512,13 +645,25 @@ static int akcipher_accept_parent(void *private, struct sock *sk)
return 0;
}
+static int akcipher_accept_parent(void *private, struct sock *sk)
+{
+ struct akcipher_tfm *tfm = private;
+
+ if (!tfm->has_key)
+ return -ENOKEY;
+
+ return akcipher_accept_parent_nokey(private, sk);
+}
+
static const struct af_alg_type algif_type_akcipher = {
.bind = akcipher_bind,
.release = akcipher_release,
.setkey = akcipher_setprivkey,
.setpubkey = akcipher_setpubkey,
.accept = akcipher_accept_parent,
+ .accept_nokey = akcipher_accept_parent_nokey,
.ops = &algif_akcipher_ops,
+ .ops_nokey = &algif_akcipher_ops_nokey,
.name = "akcipher",
.owner = THIS_MODULE
};
next prev parent reply other threads:[~2016-05-15 4:17 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-05 19:50 [PATCH RESEND v5 0/6] crypto: algif - add akcipher Tadeusz Struk
2016-05-05 19:50 ` [PATCH RESEND v5 1/6] crypto: AF_ALG -- add sign/verify API Tadeusz Struk
2016-05-06 10:36 ` Stephan Mueller
2016-05-05 19:50 ` [PATCH RESEND v5 2/6] crypto: AF_ALG -- add setpubkey setsockopt call Tadeusz Struk
2016-05-05 19:51 ` [PATCH RESEND v5 3/6] crypto: AF_ALG -- add asymmetric cipher interface Tadeusz Struk
2016-05-05 19:51 ` [PATCH RESEND v5 4/6] crypto: algif_akcipher - enable compilation Tadeusz Struk
2016-05-05 19:51 ` [PATCH RESEND v5 5/6] crypto: algif_akcipher - add ops_nokey Tadeusz Struk
2016-05-05 19:51 ` [PATCH RESEND v5 6/6] crypto: AF_ALG - add support for key_id Tadeusz Struk
2016-05-06 11:46 ` Stephan Mueller
2016-05-13 23:32 ` Mat Martineau
2016-05-16 14:23 ` Tadeusz Struk
2016-05-11 14:25 ` [PATCH RESEND v5 0/6] crypto: algif - add akcipher David Howells
[not found] ` <5123.1462976721-S6HVgzuS8uM4Awkfq6JHfwNdhmdF6hFW@public.gmane.org>
2016-05-15 4:16 ` [PATCH v6 " Tadeusz Struk
2016-05-15 4:16 ` [PATCH v6 1/6] crypto: AF_ALG -- add sign/verify API Tadeusz Struk
2016-05-15 4:16 ` [PATCH v6 2/6] crypto: AF_ALG -- add setpubkey setsockopt call Tadeusz Struk
2016-05-15 4:17 ` [PATCH v6 3/6] crypto: AF_ALG -- add asymmetric cipher interface Tadeusz Struk
2016-06-08 0:28 ` Mat Martineau
2016-06-08 5:31 ` Stephan Mueller
2016-06-08 19:14 ` Mat Martineau
2016-06-09 9:28 ` Stephan Mueller
2016-06-09 18:18 ` Mat Martineau
2016-06-09 18:24 ` Stephan Mueller
2016-06-09 18:27 ` Mat Martineau
[not found] ` <alpine.OSX.2.20.1606091126420.21471-zaFMaa3cLiZe6KzckbbZvYT4S9po1h25@public.gmane.org>
2016-06-09 18:36 ` Stephan Mueller
2016-06-10 14:42 ` Tadeusz Struk
2016-06-22 22:45 ` Mat Martineau
[not found] ` <alpine.OSX.2.20.1606221515040.16377-zaFMaa3cLiZe6KzckbbZvYT4S9po1h25@public.gmane.org>
2016-06-23 5:07 ` Stephan Mueller
[not found] ` <3250613.UAo0YkFYZb-gNvIQDDl/k7Ia13z/PHSgg@public.gmane.org>
2016-06-23 15:22 ` Denis Kenzior
2016-06-13 22:16 ` Andrew Zaborowski
2016-06-14 5:12 ` Stephan Mueller
[not found] ` <1759070.fi90mrsgKn-jJGQKZiSfeo1haGO/jJMPxvVK+yQ3ZXh@public.gmane.org>
2016-06-14 7:42 ` Andrew Zaborowski
2016-06-16 8:05 ` Stephan Mueller
2016-06-16 14:59 ` Andrew Zaborowski
2016-06-16 15:38 ` Stephan Mueller
2016-06-17 0:39 ` Andrew Zaborowski
2016-06-14 17:22 ` Mat Martineau
2016-06-15 7:04 ` Stephan Mueller
2016-05-15 4:17 ` [PATCH v6 4/6] crypto: algif_akcipher - enable compilation Tadeusz Struk
2016-05-15 4:17 ` Tadeusz Struk [this message]
2016-05-15 4:17 ` [PATCH v6 6/6] crypto: AF_ALG - add support for key_id Tadeusz Struk
2016-05-26 0:45 ` Mat Martineau
2016-05-31 17:44 ` Tadeusz Struk
2016-05-15 11:59 ` [PATCH v6 0/6] crypto: algif - add akcipher Stephan Mueller
2016-05-16 20:46 ` Tadeusz Struk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160515041713.15888.29635.stgit@tstruk-mobl1 \
--to=tadeusz.struk@intel.com \
--cc=davem@davemloft.net \
--cc=dhowells@redhat.com \
--cc=dwmw2@infradead.org \
--cc=herbert@gondor.apana.org.au \
--cc=keyrings@vger.kernel.org \
--cc=linux-api@vger.kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=marcel@holtmann.org \
--cc=smueller@chronox.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).