From patchwork Wed Oct 28 01:02:51 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcel Holtmann X-Patchwork-Id: 7505911 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 2AC869F327 for ; Wed, 28 Oct 2015 01:03:06 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3877D20856 for ; Wed, 28 Oct 2015 01:03:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E809620742 for ; Wed, 28 Oct 2015 01:03:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751573AbbJ1BDC (ORCPT ); Tue, 27 Oct 2015 21:03:02 -0400 Received: from senator.holtmann.net ([87.106.208.187]:53074 "EHLO mail.holtmann.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751429AbbJ1BDB (ORCPT ); Tue, 27 Oct 2015 21:03:01 -0400 Received: from aeonflux.localdomain (unknown [58.123.138.250]) by mail.holtmann.org (Postfix) with ESMTPSA id 5562F8B339; Wed, 28 Oct 2015 02:02:57 +0100 (CET) From: Marcel Holtmann To: linux-crypto@vger.kernel.org Cc: dhowells@redhat.com Subject: [PATCH] crypto: Add support for ALG_SET_KEY_ID for skcipher Date: Wed, 28 Oct 2015 02:02:51 +0100 Message-Id: <1445994171-30914-1-git-send-email-marcel@holtmann.org> X-Mailer: git-send-email 2.4.3 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.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham 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 This adds support for a new socket options called ALG_SET_KEY_ID that allows providing the symmetric key via a key serial from the keys subsystem. NOTE: Currently we do not have a dedicated symmetric key type and using the user key type is not optional. Also lookup_user_key() is currently private to the keys subsystem and might need to be exposed to usage by the crypto subystem first. This is just a RFC and not for merging !!! Signed-off-by: Marcel Holtmann --- crypto/af_alg.c | 14 ++++++++++++++ crypto/algif_skcipher.c | 25 +++++++++++++++++++++++++ include/crypto/if_alg.h | 2 ++ include/uapi/linux/if_alg.h | 1 + 4 files changed, 42 insertions(+) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index a8e7aa3e257b..48ddbb4063aa 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -203,6 +203,7 @@ 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 = -ENOPROTOOPT; + key_serial_t keyid; lock_sock(sk); type = ask->type; @@ -225,6 +226,19 @@ static int alg_setsockopt(struct socket *sock, int level, int optname, if (!type->setauthsize) goto unlock; err = type->setauthsize(ask->private, optlen); + break; + case ALG_SET_KEY_ID: + if (sock->state == SS_CONNECTED) + goto unlock; + if (!type->setkeyid) + goto unlock; + + err = -EFAULT; + if (get_user(keyid, (key_serial_t __user *) optval)) + goto unlock; + + err = type->setkeyid(ask->private, keyid); + break; } unlock: diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 945075292bc9..5dfae3cb6e20 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include "../security/keys/internal.h" struct skcipher_sg_list { struct list_head list; @@ -764,6 +766,28 @@ static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen) return crypto_ablkcipher_setkey(private, key, keylen); } +static int skcipher_setkeyid(void *private, key_serial_t id) +{ + key_ref_t key_ref; + int err = -EPROTOTYPE; + + key_ref = lookup_user_key(id, 0, KEY_NEED_READ); + if (IS_ERR(key_ref)) + return PTR_ERR(key_ref); + + if (key_ref_to_ptr(key_ref)->type == &key_type_user) { + struct user_key_payload *upayload; + + upayload = rcu_dereference_key(key_ref_to_ptr(key_ref)); + + err = crypto_ablkcipher_setkey(private, upayload->data, + upayload->datalen); + } + + key_ref_put(key_ref); + return err; +} + static void skcipher_wait(struct sock *sk) { struct alg_sock *ask = alg_sk(sk); @@ -832,6 +856,7 @@ static const struct af_alg_type algif_type_skcipher = { .bind = skcipher_bind, .release = skcipher_release, .setkey = skcipher_setkey, + .setkeyid = skcipher_setkeyid, .accept = skcipher_accept_parent, .ops = &algif_skcipher_ops, .name = "skcipher", diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h index 018afb264ac2..f71d88162326 100644 --- a/include/crypto/if_alg.h +++ b/include/crypto/if_alg.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,7 @@ struct af_alg_type { int (*setkey)(void *private, const u8 *key, unsigned int keylen); int (*accept)(void *private, struct sock *sk); int (*setauthsize)(void *private, unsigned int authsize); + int (*setkeyid)(void *private, key_serial_t id); struct proto_ops *ops; struct module *owner; diff --git a/include/uapi/linux/if_alg.h b/include/uapi/linux/if_alg.h index d81dcca5bdd7..28cdc05695c0 100644 --- a/include/uapi/linux/if_alg.h +++ b/include/uapi/linux/if_alg.h @@ -34,6 +34,7 @@ struct af_alg_iv { #define ALG_SET_OP 3 #define ALG_SET_AEAD_ASSOCLEN 4 #define ALG_SET_AEAD_AUTHSIZE 5 +#define ALG_SET_KEY_ID 6 /* Operations */ #define ALG_OP_DECRYPT 0