linux-api.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tadeusz Struk <tadeusz.struk@intel.com>
To: herbert@gondor.apana.org.au
Cc: tadeusz.struk@intel.com, smueller@chronox.de,
	linux-api@vger.kernel.org, marcel@holtmann.org,
	linux-kernel@vger.kernel.org, dhowells@redhat.com,
	keyrings@vger.kernel.org, linux-crypto@vger.kernel.org,
	dwmw2@infradead.org, davem@davemloft.net
Subject: [PATCH v3 7/7] crypto: AF_ALG - add support for key_id
Date: Tue, 29 Mar 2016 17:57:34 -0700	[thread overview]
Message-ID: <20160330005734.25410.28829.stgit@tstruk-mobl1> (raw)
In-Reply-To: <20160330005649.25410.70508.stgit@tstruk-mobl1>

This patch adds support for asymmetric key type to AF_ALG.
It will work as follows: A new PF_ALG socket options are
added on top of existing ALG_SET_KEY and ALG_SET_PUBKEY, namely
ALG_SET_KEY_ID and ALG_SET_PUBKEY_ID for setting public and
private keys respectively. When these new options will be used
the user, instead of providing the key material, will provide a
key id and the key itself will be obtained from kernel keyring
subsystem. The user will use the standard tools (keyctl tool
or the keyctl syscall) for key instantiation and to obtain the
key id. The key id can also be obtained by reading the
/proc/keys file.

When a key is found, the request_key() function
returns the requested key. Next the asymmetric key subtype will be
used to obtain the public_key, which can be either a public key
or a private key. The key is then verified using the new
key info public_key_query_sw_key query, to check whether or not the key
can be accessed by software. In case when the key is kept
in hardware (TPM) then the function will return -ENOKEY error code.

If the key can be accesses by software then the key payload
will be passed to the akcipher pf_alg subtype.
AF_ALG code will then call crypto API functions, either the
crypto_akcipher_set_priv_key or the crypto_akcipher_set_pub_key,
depending on the used option. Subsequently the asymmetric key
will be freed and return code returned back to the user.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
---
 crypto/af_alg.c             |   50 ++++++++++++++++++++++++++++++++++++++++---
 include/uapi/linux/if_alg.h |    2 ++
 2 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 24dc082..9d109bc 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -22,6 +22,8 @@
 #include <linux/net.h>
 #include <linux/rwsem.h>
 #include <linux/security.h>
+#include <crypto/public_key.h>
+#include <keys/asymmetric-type.h>
 
 struct alg_type_list {
 	const struct af_alg_type *type;
@@ -201,8 +203,40 @@ unlock:
 	return err;
 }
 
+static int alg_setkey_id(void *private, const u8 *key, unsigned int keylen,
+			 int (*setkey)(void *private, const u8 *key,
+				       unsigned int keylen))
+{
+	struct key *keyring;
+	struct public_key *pkey;
+	char key_name[12];
+	u32 keyid = *((u32 *)key);
+	int err;
+
+	sprintf(key_name, "id:%08x", keyid);
+	keyring = request_key(&key_type_asymmetric, key_name, NULL);
+
+	err = -ENOKEY;
+	if (IS_ERR(keyring))
+		goto out;
+
+	pkey = keyring->payload.data[asym_crypto];
+	if (!pkey)
+		goto out_put_key;
+
+	if (!public_key_query_sw_key(pkey))
+		goto out_put_key;
+
+	err = setkey(private, pkey->key, pkey->keylen);
+
+out_put_key:
+	key_put(keyring);
+out:
+	return err;
+}
+
 static int alg_setkey(struct sock *sk, char __user *ukey,
-		      unsigned int keylen,
+		      unsigned int keylen, bool key_id,
 		      int (*setkey)(void *private, const u8 *key,
 				    unsigned int keylen))
 {
@@ -221,7 +255,8 @@ static int alg_setkey(struct sock *sk, char __user *ukey,
 	if (copy_from_user(key, ukey, keylen))
 		goto out;
 
-	err = setkey(ask->private, key, keylen);
+	err = key_id ? alg_setkey_id(ask->private, key, keylen, setkey) :
+		       setkey(ask->private, key, keylen);
 
 out:
 	sock_kzfree_s(sk, key, keylen);
@@ -236,6 +271,8 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
 	struct alg_sock *ask = alg_sk(sk);
 	const struct af_alg_type *type;
 	int err = -EBUSY;
+	bool key_id = ((optname == ALG_SET_PUBKEY_ID) ||
+		       (optname == ALG_SET_KEY_ID));
 
 	lock_sock(sk);
 	if (ask->refcnt)
@@ -249,16 +286,21 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
 
 	switch (optname) {
 	case ALG_SET_KEY:
+	case ALG_SET_KEY_ID:
 		if (sock->state == SS_CONNECTED)
 			goto unlock;
+		/* ALG_SET_KEY_ID is only for akcipher */
+		if (!strcmp(type->name, "akcipher") && key_id)
+			goto unlock;
 
-		err = alg_setkey(sk, optval, optlen, type->setkey);
+		err = alg_setkey(sk, optval, optlen, key_id, type->setkey);
 		break;
 	case ALG_SET_PUBKEY:
+	case ALG_SET_PUBKEY_ID:
 		if (sock->state == SS_CONNECTED)
 			goto unlock;
 
-		err = alg_setkey(sk, optval, optlen, type->setpubkey);
+		err = alg_setkey(sk, optval, optlen, key_id, type->setpubkey);
 		break;
 	case ALG_SET_AEAD_AUTHSIZE:
 		if (sock->state == SS_CONNECTED)
diff --git a/include/uapi/linux/if_alg.h b/include/uapi/linux/if_alg.h
index 02e6162..0379766 100644
--- a/include/uapi/linux/if_alg.h
+++ b/include/uapi/linux/if_alg.h
@@ -35,6 +35,8 @@ struct af_alg_iv {
 #define ALG_SET_AEAD_ASSOCLEN		4
 #define ALG_SET_AEAD_AUTHSIZE		5
 #define ALG_SET_PUBKEY			6
+#define ALG_SET_PUBKEY_ID		7
+#define ALG_SET_KEY_ID			8
 
 /* Operations */
 #define ALG_OP_DECRYPT			0

  parent reply	other threads:[~2016-03-30  0:57 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-30  0:56 [PATCH v3 0/7] crypto: algif - add akcipher Tadeusz Struk
2016-03-30  0:56 ` [PATCH v3 1/7] crypto: AF_ALG -- add sign/verify API Tadeusz Struk
2016-03-30  0:57 ` [PATCH v3 2/7] crypto: AF_ALG -- add setpubkey setsockopt call Tadeusz Struk
2016-03-30  0:57 ` [PATCH v3 3/7] crypto: AF_ALG -- add asymmetric cipher interface Tadeusz Struk
2016-03-30  0:57 ` [PATCH v3 4/7] crypto: algif_akcipher - enable compilation Tadeusz Struk
2016-03-30  0:57 ` [PATCH v3 5/7] crypto: algif_akcipher - add ops_nokey Tadeusz Struk
2016-03-30  0:57 ` [PATCH v3 6/7] crypto: KEYS - add public_key info query Tadeusz Struk
2016-03-30  0:57 ` Tadeusz Struk [this message]
2016-03-30  1:49   ` [PATCH v3 7/7] crypto: AF_ALG - add support for key_id kbuild test robot
     [not found]     ` <201603300916.Og5tA3rF%fengguang.wu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2016-03-30  2:52       ` Tadeusz Struk
2016-03-30  2:22   ` kbuild test robot
2016-03-30  2:46   ` kbuild test robot
2016-03-30 16:31 ` David Howells
2016-03-30 16:45   ` David Woodhouse
2016-03-30 16:45   ` David Woodhouse
2016-03-30 17:19   ` 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=20160330005734.25410.28829.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).