This patchset adds a netlink based user configuration API for the crypto
layer, similar to the configuration API of xfrm.
The patchset is based on the current cryptodev-2.6 tree and also available
at branch 'crypto-user-config-api' of
git://git.kernel.org/pub/scm/linux/kernel/git/klassert/linux-stk.git
A userspace tool that makes use of the configuration API is temporarily
available at
http://www.kernel.org/pub/linux/kernel/people/klassert/crconf/
With this it is possible to instantiate certain algorithms by doing
crconf add driver "cbc(aes-generic)" type 4
or
crconf add driver "cbc(aes-generic)" type 4 priority 100
To remove a (form templates build and unused) algorithm with all subsequent
algorithms do
crconf del driver "cbc(aes-generic)" type 4
Finally it is possible to print the instantiated crypto algorithms
similar to /proc/crypto by doing
crconf show all
This prints the algorithm informations of all instantiated algorithms
as long as the information fits into a netlink message.
Changes from v1:
- Removed the priority update functions.
- Fix algorithm information printing when build as module.
- Update the crconf tool according to the kernel changes.
Steffen
The upcomming crypto user configuration api needs to identify
crypto instances. This patch adds a flag that is set if the
algorithm is an instance that is build from templates.
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/algapi.c | 1 +
include/linux/crypto.h | 5 +++++
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/crypto/algapi.c b/crypto/algapi.c
index c3cf1a6..6fd9bcf 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -493,6 +493,7 @@ int crypto_register_instance(struct crypto_template *tmpl,
goto err;
inst->alg.cra_module = tmpl->module;
+ inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE;
down_write(&crypto_alg_sem);
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index e5e468e..cba4d63 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -72,6 +72,11 @@
#define CRYPTO_ALG_TESTED 0x00000400
/*
+ * Set if the algorithm is an instance that is build from telplates.
+ */
+#define CRYPTO_ALG_INSTANCE 0x00000800
+
+/*
* Transform masks and values (for crt_flags).
*/
#define CRYPTO_TFM_REQ_MASK 0x000fff00
--
1.7.0.4
This patch adds a basic userspace configuration API for the crypto layer.
With this it is possible to instantiate, remove and to show crypto
algorithms from userspace.
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/Kconfig | 7 +
crypto/Makefile | 1 +
crypto/crypto_user.c | 331 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/cryptouser.h | 57 ++++++++
include/linux/netlink.h | 1 +
5 files changed, 397 insertions(+), 0 deletions(-)
create mode 100644 crypto/crypto_user.c
create mode 100644 include/linux/cryptouser.h
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 55c50cd..c05d0df 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -100,6 +100,13 @@ config CRYPTO_MANAGER2
select CRYPTO_BLKCIPHER2
select CRYPTO_PCOMP2
+config CRYPTO_USER
+ tristate "Userspace cryptographic algorithm configuration"
+ select CRYPTO_MANAGER
+ help
+ Userapace configuration for cryptographic instantiations such as
+ cbc(aes).
+
config CRYPTO_MANAGER_DISABLE_TESTS
bool "Disable run-time self tests"
default y
diff --git a/crypto/Makefile b/crypto/Makefile
index ce5a813..4c4171b 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
cryptomgr-y := algboss.o testmgr.o
obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
+obj-$(CONFIG_CRYPTO_USER) += crypto_user.o
obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
obj-$(CONFIG_CRYPTO_VMAC) += vmac.o
obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
new file mode 100644
index 0000000..4edd015
--- /dev/null
+++ b/crypto/crypto_user.c
@@ -0,0 +1,331 @@
+/*
+ * Crypto user configuration API.
+ *
+ * Copyright (C) 2011 secunet Security Networks AG
+ * Copyright (C) 2011 Steffen Klassert <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <linux/cryptouser.h>
+#include <net/netlink.h>
+#include <linux/security.h>
+#include <net/net_namespace.h>
+#include "internal.h"
+
+DEFINE_MUTEX(crypto_cfg_mutex);
+
+/* The crypto netlink socket */
+static struct sock *crypto_nlsk;
+
+struct crypto_dump_info {
+ struct sk_buff *in_skb;
+ struct sk_buff *out_skb;
+ u32 nlmsg_seq;
+ u16 nlmsg_flags;
+};
+
+static struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p)
+{
+ int match;
+ struct crypto_alg *q, *alg = NULL;
+
+ down_read(&crypto_alg_sem);
+
+ if (list_empty(&crypto_alg_list))
+ return NULL;
+
+ list_for_each_entry(q, &crypto_alg_list, cra_list) {
+
+ if ((q->cra_flags ^ p->type) & p->mask)
+ continue;
+
+ if (strlen(p->cru_driver_name))
+ match = !strcmp(q->cra_driver_name,
+ p->cru_driver_name);
+ else
+ match = !strcmp(q->cra_name, p->cru_name);
+ if (match) {
+ alg = q;
+ break;
+ }
+ }
+
+ up_read(&crypto_alg_sem);
+
+ return alg;
+}
+
+static int crypto_report_one(struct crypto_alg *alg,
+ struct crypto_report_base *rb, struct sk_buff *skb)
+{
+ memcpy(&rb->name, &alg->cra_name, sizeof(rb->name));
+ memcpy(&rb->driver_name, &alg->cra_driver_name, sizeof(rb->driver_name));
+ memcpy(&rb->module_name, module_name(alg->cra_module), CRYPTO_MAX_ALG_NAME);
+ snprintf(rb->selftest, CRYPTO_MAX_ALG_NAME, "%s",
+ (alg->cra_flags & CRYPTO_ALG_TESTED) ? "passed" : "unknown");
+
+ rb->priority = alg->cra_priority;
+ rb->refcnt = atomic_read(&alg->cra_refcnt);
+
+ return 0;
+}
+
+static int crypto_report_alg(struct crypto_alg *alg,
+ struct crypto_dump_info *info)
+{
+ struct sk_buff *in_skb = info->in_skb;
+ struct sk_buff *skb = info->out_skb;
+ struct nlmsghdr *nlh;
+ struct crypto_report_base *rb;
+ int err = 0;
+
+ nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, info->nlmsg_seq,
+ CRYPTO_MSG_GETALG, sizeof(*rb), info->nlmsg_flags);
+ if (!nlh) {
+ err = -EMSGSIZE;
+ goto out;
+ }
+
+ rb = nlmsg_data(nlh);
+
+ err = crypto_report_one(alg, rb, skb);
+ if (err) {
+ nlmsg_cancel(skb, nlh);
+ goto out;
+ }
+
+ nlmsg_end(skb, nlh);
+
+out:
+ return err;
+}
+
+static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh,
+ struct nlattr **attrs)
+{
+ struct crypto_user_alg *p = nlmsg_data(in_nlh);
+ struct crypto_alg *alg;
+ struct sk_buff *skb;
+ struct crypto_dump_info info;
+ int err;
+
+ if (!p->cru_driver_name)
+ return -EINVAL;
+
+ alg = crypto_alg_match(p);
+ if (!alg)
+ return -ENOENT;
+
+ skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ info.in_skb = in_skb;
+ info.out_skb = skb;
+ info.nlmsg_seq = in_nlh->nlmsg_seq;
+ info.nlmsg_flags = 0;
+
+ err = crypto_report_alg(alg, &info);
+ if (err)
+ return err;
+
+ return nlmsg_unicast(crypto_nlsk, skb, NETLINK_CB(in_skb).pid);
+}
+
+static int crypto_dump_report(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ struct crypto_alg *alg;
+ struct crypto_dump_info info;
+ int err;
+
+ if (cb->args[0])
+ goto out;
+
+ cb->args[0] = 1;
+
+ info.in_skb = cb->skb;
+ info.out_skb = skb;
+ info.nlmsg_seq = cb->nlh->nlmsg_seq;
+ info.nlmsg_flags = NLM_F_MULTI;
+
+ list_for_each_entry(alg, &crypto_alg_list, cra_list) {
+ err = crypto_report_alg(alg, &info);
+ if (err)
+ goto out_err;
+ }
+
+out:
+ return skb->len;
+out_err:
+ return err;
+}
+
+static int crypto_dump_report_done(struct netlink_callback *cb)
+{
+ return 0;
+}
+
+static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
+ struct nlattr **attrs)
+{
+ struct crypto_alg *alg;
+ struct crypto_user_alg *p = nlmsg_data(nlh);
+
+ alg = crypto_alg_match(p);
+ if (!alg)
+ return -ENOENT;
+
+ /* We can not unregister core algorithms such as aes-generic.
+ * We would loose the reference in the crypto_alg_list to this algorithm
+ * if we try to unregister. Unregistering such an algorithm without
+ * removing the module is not possible, so we restrict to crypto
+ * instances that are build from templates. */
+ if (!(alg->cra_flags & CRYPTO_ALG_INSTANCE))
+ return -EINVAL;
+
+ if (atomic_read(&alg->cra_refcnt) != 1)
+ return -EBUSY;
+
+ return crypto_unregister_alg(alg);
+}
+
+static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh,
+ struct nlattr **attrs)
+{
+ const char *name;
+ struct crypto_alg *alg;
+ struct crypto_user_alg *p = nlmsg_data(nlh);
+ struct nlattr *priority = attrs[CRYPTOCFGA_PRIORITY_VAL];
+
+ if (priority && !strlen(p->cru_driver_name))
+ return -EINVAL;
+
+ alg = crypto_alg_match(p);
+ if (alg)
+ return -EEXIST;
+
+ if (strlen(p->cru_driver_name))
+ name = p->cru_driver_name;
+ else
+ name = p->cru_name;
+
+ alg = crypto_alg_mod_lookup(name, p->type, p->mask);
+ if (IS_ERR(alg))
+ return PTR_ERR(alg);
+
+ down_write(&crypto_alg_sem);
+
+ if (priority)
+ alg->cra_priority = nla_get_u32(priority);
+
+ up_write(&crypto_alg_sem);
+
+ crypto_mod_put(alg);
+
+ return 0;
+}
+
+#define MSGSIZE(type) sizeof(struct type)
+
+static const int crypto_msg_min[CRYPTO_NR_MSGTYPES] = {
+ [CRYPTO_MSG_NEWALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
+ [CRYPTO_MSG_DELALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
+ [CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
+};
+
+static const struct nla_policy crypto_policy[CRYPTOCFGA_MAX+1] = {
+ [CRYPTOCFGA_PRIORITY_VAL] = { .type = NLA_U32},
+};
+
+#undef MSGSIZE
+
+static struct crypto_link {
+ int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **);
+ int (*dump)(struct sk_buff *, struct netlink_callback *);
+ int (*done)(struct netlink_callback *);
+} crypto_dispatch[CRYPTO_NR_MSGTYPES] = {
+ [CRYPTO_MSG_NEWALG - CRYPTO_MSG_BASE] = { .doit = crypto_add_alg},
+ [CRYPTO_MSG_DELALG - CRYPTO_MSG_BASE] = { .doit = crypto_del_alg},
+ [CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE] = { .doit = crypto_report,
+ .dump = crypto_dump_report,
+ .done = crypto_dump_report_done},
+};
+
+static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+{
+ struct nlattr *attrs[CRYPTOCFGA_MAX+1];
+ struct crypto_link *link;
+ int type, err;
+
+ type = nlh->nlmsg_type;
+ if (type > CRYPTO_MSG_MAX)
+ return -EINVAL;
+
+ type -= CRYPTO_MSG_BASE;
+ link = &crypto_dispatch[type];
+
+ if (security_netlink_recv(skb, CAP_NET_ADMIN))
+ return -EPERM;
+
+ if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
+ (nlh->nlmsg_flags & NLM_F_DUMP))) {
+ if (link->dump == NULL)
+ return -EINVAL;
+
+ return netlink_dump_start(crypto_nlsk, skb, nlh,
+ link->dump, link->done, 0);
+ }
+
+ err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX,
+ crypto_policy);
+ if (err < 0)
+ return err;
+
+ if (link->doit == NULL)
+ return -EINVAL;
+
+ return link->doit(skb, nlh, attrs);
+}
+
+static void crypto_netlink_rcv(struct sk_buff *skb)
+{
+ mutex_lock(&crypto_cfg_mutex);
+ netlink_rcv_skb(skb, &crypto_user_rcv_msg);
+ mutex_unlock(&crypto_cfg_mutex);
+}
+
+static int __init crypto_user_init(void)
+{
+ crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO,
+ 0, crypto_netlink_rcv,
+ NULL, THIS_MODULE);
+ if (!crypto_nlsk)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void __exit crypto_user_exit(void)
+{
+ netlink_kernel_release(crypto_nlsk);
+}
+
+module_init(crypto_user_init);
+module_exit(crypto_user_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Steffen Klassert <[email protected]>");
+MODULE_DESCRIPTION("Crypto userspace configuration API");
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
new file mode 100644
index 0000000..3245081
--- /dev/null
+++ b/include/linux/cryptouser.h
@@ -0,0 +1,57 @@
+/*
+ * Crypto user configuration API.
+ *
+ * Copyright (C) 2011 secunet Security Networks AG
+ * Copyright (C) 2011 Steffen Klassert <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/* Netlink configuration messages. */
+enum {
+ CRYPTO_MSG_BASE = 0x10,
+ CRYPTO_MSG_NEWALG = 0x10,
+ CRYPTO_MSG_DELALG,
+ CRYPTO_MSG_GETALG,
+ __CRYPTO_MSG_MAX
+};
+#define CRYPTO_MSG_MAX (__CRYPTO_MSG_MAX - 1)
+#define CRYPTO_NR_MSGTYPES (CRYPTO_MSG_MAX + 1 - CRYPTO_MSG_BASE)
+
+/* Netlink message attributes. */
+enum crypto_attr_type_t {
+ CRYPTOCFGA_UNSPEC,
+ CRYPTOCFGA_PRIORITY_VAL, /* __u32 */
+ __CRYPTOCFGA_MAX
+
+#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
+};
+
+struct crypto_user_alg {
+ char cru_name[CRYPTO_MAX_ALG_NAME];
+ char cru_driver_name[CRYPTO_MAX_ALG_NAME];
+ __u32 type;
+ __u32 mask;
+};
+
+#define CRYPTO_MAX_NAME CRYPTO_MAX_ALG_NAME
+
+struct crypto_report_base {
+ char name[CRYPTO_MAX_ALG_NAME];
+ char driver_name[CRYPTO_MAX_ALG_NAME];
+ char module_name[CRYPTO_MAX_NAME];
+ char selftest[CRYPTO_MAX_NAME];
+ int priority;
+ int refcnt;
+};
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 2e17c5d..464ace0 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -25,6 +25,7 @@
#define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */
#define NETLINK_ECRYPTFS 19
#define NETLINK_RDMA 20
+#define NETLINK_CRYPTO 21 /* Crypto layer */
#define MAX_LINKS 32
--
1.7.0.4
We add a report function pointer to struct crypto_type. This function
pointer is used from the crypto userspace configuration API to report
crypto algorithms to userspace.
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/crypto_user.c | 8 ++++++++
include/crypto/algapi.h | 2 ++
2 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 4edd015..cb3a722 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -81,7 +81,15 @@ static int crypto_report_one(struct crypto_alg *alg,
rb->priority = alg->cra_priority;
rb->refcnt = atomic_read(&alg->cra_refcnt);
+ if (alg->cra_type && alg->cra_type->report) {
+ if (alg->cra_type->report(skb, alg))
+ goto nla_put_failure;
+ }
+
return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
}
static int crypto_report_alg(struct crypto_alg *alg,
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index 59c3e5b..ecc721d 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -15,6 +15,7 @@
#include <linux/crypto.h>
#include <linux/list.h>
#include <linux/kernel.h>
+#include <linux/skbuff.h>
struct module;
struct rtattr;
@@ -26,6 +27,7 @@ struct crypto_type {
int (*init)(struct crypto_tfm *tfm, u32 type, u32 mask);
int (*init_tfm)(struct crypto_tfm *tfm);
void (*show)(struct seq_file *m, struct crypto_alg *alg);
+ int (*report)(struct sk_buff *skb, struct crypto_alg *alg);
struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask);
unsigned int type;
--
1.7.0.4
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/crypto_user.c | 13 +++++++++++++
include/linux/cryptouser.h | 6 ++++++
2 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index cb3a722..68d405d 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -81,11 +81,24 @@ static int crypto_report_one(struct crypto_alg *alg,
rb->priority = alg->cra_priority;
rb->refcnt = atomic_read(&alg->cra_refcnt);
+ if (alg->cra_flags & CRYPTO_ALG_LARVAL) {
+ struct crypto_report_larval rl;
+
+ snprintf(rl.type, CRYPTO_MAX_ALG_NAME, "%s", "larval");
+ rl.flags = alg->cra_flags;
+
+ NLA_PUT(skb, CRYPTOCFGA_REPORT_LARVAL,
+ sizeof(struct crypto_report_larval), &rl);
+
+ goto out;
+ }
+
if (alg->cra_type && alg->cra_type->report) {
if (alg->cra_type->report(skb, alg))
goto nla_put_failure;
}
+out:
return 0;
nla_put_failure:
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
index 3245081..d77b16c 100644
--- a/include/linux/cryptouser.h
+++ b/include/linux/cryptouser.h
@@ -33,6 +33,7 @@ enum {
enum crypto_attr_type_t {
CRYPTOCFGA_UNSPEC,
CRYPTOCFGA_PRIORITY_VAL, /* __u32 */
+ CRYPTOCFGA_REPORT_LARVAL, /* struct crypto_report_larval */
__CRYPTOCFGA_MAX
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
@@ -55,3 +56,8 @@ struct crypto_report_base {
int priority;
int refcnt;
};
+
+struct crypto_report_larval {
+ char type[CRYPTO_MAX_NAME];
+ __u32 flags;
+};
--
1.7.0.4
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/shash.c | 21 +++++++++++++++++++++
include/linux/cryptouser.h | 7 +++++++
2 files changed, 28 insertions(+), 0 deletions(-)
diff --git a/crypto/shash.c b/crypto/shash.c
index 76f74b9..140c337 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -17,6 +17,8 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
+#include <linux/cryptouser.h>
+#include <net/netlink.h>
#include "internal.h"
@@ -522,6 +524,24 @@ static unsigned int crypto_shash_extsize(struct crypto_alg *alg)
return alg->cra_ctxsize;
}
+static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ struct crypto_report_shash rshash;
+ struct shash_alg *salg = __crypto_shash_alg(alg);
+
+ snprintf(rshash.type, CRYPTO_MAX_ALG_NAME, "%s", "shash");
+ rshash.blocksize = alg->cra_blocksize;
+ rshash.digestsize = salg->digestsize;
+
+ NLA_PUT(skb, CRYPTOCFGA_REPORT_SHASH,
+ sizeof(struct crypto_report_shash), &rshash);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg)
@@ -541,6 +561,7 @@ static const struct crypto_type crypto_shash_type = {
#ifdef CONFIG_PROC_FS
.show = crypto_shash_show,
#endif
+ .report = crypto_shash_report,
.maskclear = ~CRYPTO_ALG_TYPE_MASK,
.maskset = CRYPTO_ALG_TYPE_MASK,
.type = CRYPTO_ALG_TYPE_SHASH,
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
index d77b16c..8f07bab 100644
--- a/include/linux/cryptouser.h
+++ b/include/linux/cryptouser.h
@@ -34,6 +34,7 @@ enum crypto_attr_type_t {
CRYPTOCFGA_UNSPEC,
CRYPTOCFGA_PRIORITY_VAL, /* __u32 */
CRYPTOCFGA_REPORT_LARVAL, /* struct crypto_report_larval */
+ CRYPTOCFGA_REPORT_SHASH, /* struct crypto_report_shash */
__CRYPTOCFGA_MAX
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
@@ -61,3 +62,9 @@ struct crypto_report_larval {
char type[CRYPTO_MAX_NAME];
__u32 flags;
};
+
+struct crypto_report_shash {
+ char type[CRYPTO_MAX_NAME];
+ unsigned int blocksize;
+ unsigned int digestsize;
+};
--
1.7.0.4
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/ahash.c | 23 +++++++++++++++++++++++
include/linux/cryptouser.h | 8 ++++++++
2 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/crypto/ahash.c b/crypto/ahash.c
index f669822..83827cc 100644
--- a/crypto/ahash.c
+++ b/crypto/ahash.c
@@ -21,6 +21,8 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
+#include <linux/cryptouser.h>
+#include <net/netlink.h>
#include "internal.h"
@@ -397,6 +399,26 @@ static unsigned int crypto_ahash_extsize(struct crypto_alg *alg)
return sizeof(struct crypto_shash *);
}
+static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ struct crypto_report_ahash rahash;
+
+ snprintf(rahash.type, CRYPTO_MAX_ALG_NAME, "%s", "ahash");
+ snprintf(rahash.async, CRYPTO_MAX_ALG_NAME, "%s",
+ alg->cra_flags & CRYPTO_ALG_ASYNC ? "yes" : "no");
+
+ rahash.blocksize = alg->cra_blocksize;
+ rahash.digestsize = __crypto_hash_alg_common(alg)->digestsize;
+
+ NLA_PUT(skb, CRYPTOCFGA_REPORT_AHASH,
+ sizeof(struct crypto_report_ahash), &rahash);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg)
@@ -415,6 +437,7 @@ const struct crypto_type crypto_ahash_type = {
#ifdef CONFIG_PROC_FS
.show = crypto_ahash_show,
#endif
+ .report = crypto_ahash_report,
.maskclear = ~CRYPTO_ALG_TYPE_MASK,
.maskset = CRYPTO_ALG_TYPE_AHASH_MASK,
.type = CRYPTO_ALG_TYPE_AHASH,
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
index 8f07bab..cfe6156 100644
--- a/include/linux/cryptouser.h
+++ b/include/linux/cryptouser.h
@@ -35,6 +35,7 @@ enum crypto_attr_type_t {
CRYPTOCFGA_PRIORITY_VAL, /* __u32 */
CRYPTOCFGA_REPORT_LARVAL, /* struct crypto_report_larval */
CRYPTOCFGA_REPORT_SHASH, /* struct crypto_report_shash */
+ CRYPTOCFGA_REPORT_AHASH, /* struct crypto_report_ahash */
__CRYPTOCFGA_MAX
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
@@ -68,3 +69,10 @@ struct crypto_report_shash {
unsigned int blocksize;
unsigned int digestsize;
};
+
+struct crypto_report_ahash {
+ char type[CRYPTO_MAX_NAME];
+ char async[CRYPTO_MAX_NAME];
+ unsigned int blocksize;
+ unsigned int digestsize;
+};
--
1.7.0.4
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/blkcipher.c | 25 +++++++++++++++++++++++++
include/linux/cryptouser.h | 10 ++++++++++
2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index 7a72192..2572d26 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -24,6 +24,8 @@
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/cryptouser.h>
+#include <net/netlink.h>
#include "internal.h"
@@ -492,6 +494,28 @@ static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
return crypto_init_blkcipher_ops_async(tfm);
}
+static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ struct crypto_report_blkcipher rblkcipher;
+
+ snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "blkcipher");
+ snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
+ alg->cra_blkcipher.geniv ?: "<default>");
+
+ rblkcipher.blocksize = alg->cra_blocksize;
+ rblkcipher.min_keysize = alg->cra_blkcipher.min_keysize;
+ rblkcipher.max_keysize = alg->cra_blkcipher.max_keysize;
+ rblkcipher.ivsize = alg->cra_blkcipher.ivsize;
+
+ NLA_PUT(skb, CRYPTOCFGA_REPORT_BLKCIPHER,
+ sizeof(struct crypto_report_blkcipher), &rblkcipher);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg)
@@ -511,6 +535,7 @@ const struct crypto_type crypto_blkcipher_type = {
#ifdef CONFIG_PROC_FS
.show = crypto_blkcipher_show,
#endif
+ .report = crypto_blkcipher_report,
};
EXPORT_SYMBOL_GPL(crypto_blkcipher_type);
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
index cfe6156..c59109f 100644
--- a/include/linux/cryptouser.h
+++ b/include/linux/cryptouser.h
@@ -36,6 +36,7 @@ enum crypto_attr_type_t {
CRYPTOCFGA_REPORT_LARVAL, /* struct crypto_report_larval */
CRYPTOCFGA_REPORT_SHASH, /* struct crypto_report_shash */
CRYPTOCFGA_REPORT_AHASH, /* struct crypto_report_ahash */
+ CRYPTOCFGA_REPORT_BLKCIPHER, /* struct crypto_report_blkcipher */
__CRYPTOCFGA_MAX
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
@@ -76,3 +77,12 @@ struct crypto_report_ahash {
unsigned int blocksize;
unsigned int digestsize;
};
+
+struct crypto_report_blkcipher {
+ char type[CRYPTO_MAX_NAME];
+ char geniv[CRYPTO_MAX_NAME];
+ unsigned int blocksize;
+ unsigned int min_keysize;
+ unsigned int max_keysize;
+ unsigned int ivsize;
+};
--
1.7.0.4
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/ablkcipher.c | 27 +++++++++++++++++++++++++++
include/linux/cryptouser.h | 11 +++++++++++
2 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
index fdc67d3..60f5c01 100644
--- a/crypto/ablkcipher.c
+++ b/crypto/ablkcipher.c
@@ -23,6 +23,8 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
+#include <linux/cryptouser.h>
+#include <net/netlink.h>
#include <crypto/scatterwalk.h>
@@ -381,6 +383,30 @@ static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type,
return 0;
}
+static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ struct crypto_report_ablkcipher rablkcipher;
+
+ snprintf(rablkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "ablkcipher");
+ snprintf(rablkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
+ alg->cra_ablkcipher.geniv ?: "<default>");
+ snprintf(rablkcipher.async, CRYPTO_MAX_ALG_NAME, "%s",
+ alg->cra_flags & CRYPTO_ALG_ASYNC ? "yes" : "no");
+
+ rablkcipher.blocksize = alg->cra_blocksize;
+ rablkcipher.min_keysize = alg->cra_ablkcipher.min_keysize;
+ rablkcipher.max_keysize = alg->cra_ablkcipher.max_keysize;
+ rablkcipher.ivsize = alg->cra_ablkcipher.ivsize;
+
+ NLA_PUT(skb, CRYPTOCFGA_REPORT_ABLKCIPHER,
+ sizeof(struct crypto_report_ablkcipher), &rablkcipher);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
@@ -403,6 +429,7 @@ const struct crypto_type crypto_ablkcipher_type = {
#ifdef CONFIG_PROC_FS
.show = crypto_ablkcipher_show,
#endif
+ .report = crypto_ablkcipher_report,
};
EXPORT_SYMBOL_GPL(crypto_ablkcipher_type);
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
index c59109f..c0023cf 100644
--- a/include/linux/cryptouser.h
+++ b/include/linux/cryptouser.h
@@ -37,6 +37,7 @@ enum crypto_attr_type_t {
CRYPTOCFGA_REPORT_SHASH, /* struct crypto_report_shash */
CRYPTOCFGA_REPORT_AHASH, /* struct crypto_report_ahash */
CRYPTOCFGA_REPORT_BLKCIPHER, /* struct crypto_report_blkcipher */
+ CRYPTOCFGA_REPORT_ABLKCIPHER, /* struct crypto_report_ablkcipher */
__CRYPTOCFGA_MAX
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
@@ -86,3 +87,13 @@ struct crypto_report_blkcipher {
unsigned int max_keysize;
unsigned int ivsize;
};
+
+struct crypto_report_ablkcipher {
+ char type[CRYPTO_MAX_NAME];
+ char async[CRYPTO_MAX_NAME];
+ char geniv[CRYPTO_MAX_NAME];
+ unsigned int blocksize;
+ unsigned int min_keysize;
+ unsigned int max_keysize;
+ unsigned int ivsize;
+};
--
1.7.0.4
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/ablkcipher.c | 25 +++++++++++++++++++++++++
include/linux/cryptouser.h | 1 +
2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
index 60f5c01..45ed1c3 100644
--- a/crypto/ablkcipher.c
+++ b/crypto/ablkcipher.c
@@ -459,6 +459,30 @@ static int crypto_init_givcipher_ops(struct crypto_tfm *tfm, u32 type,
return 0;
}
+static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ struct crypto_report_ablkcipher rablkcipher;
+
+ snprintf(rablkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "givcipher");
+ snprintf(rablkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
+ alg->cra_ablkcipher.geniv ?: "<built-in>");
+ snprintf(rablkcipher.async, CRYPTO_MAX_ALG_NAME, "%s",
+ alg->cra_flags & CRYPTO_ALG_ASYNC ? "yes" : "no");
+
+ rablkcipher.blocksize = alg->cra_blocksize;
+ rablkcipher.min_keysize = alg->cra_ablkcipher.min_keysize;
+ rablkcipher.max_keysize = alg->cra_ablkcipher.max_keysize;
+ rablkcipher.ivsize = alg->cra_ablkcipher.ivsize;
+
+ NLA_PUT(skb, CRYPTOCFGA_REPORT_GIVCIPHER,
+ sizeof(struct crypto_report_ablkcipher), &rablkcipher);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg)
@@ -481,6 +505,7 @@ const struct crypto_type crypto_givcipher_type = {
#ifdef CONFIG_PROC_FS
.show = crypto_givcipher_show,
#endif
+ .report = crypto_givcipher_report,
};
EXPORT_SYMBOL_GPL(crypto_givcipher_type);
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
index c0023cf..2e67da6 100644
--- a/include/linux/cryptouser.h
+++ b/include/linux/cryptouser.h
@@ -38,6 +38,7 @@ enum crypto_attr_type_t {
CRYPTOCFGA_REPORT_AHASH, /* struct crypto_report_ahash */
CRYPTOCFGA_REPORT_BLKCIPHER, /* struct crypto_report_blkcipher */
CRYPTOCFGA_REPORT_ABLKCIPHER, /* struct crypto_report_ablkcipher */
+ CRYPTOCFGA_REPORT_GIVCIPHER, /* struct crypto_report_ablkcipher */
__CRYPTOCFGA_MAX
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
--
1.7.0.4
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/aead.c | 27 +++++++++++++++++++++++++++
include/linux/cryptouser.h | 10 ++++++++++
2 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/crypto/aead.c b/crypto/aead.c
index 6729e8f..17fec4a 100644
--- a/crypto/aead.c
+++ b/crypto/aead.c
@@ -21,6 +21,8 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
+#include <linux/cryptouser.h>
+#include <net/netlink.h>
#include "internal.h"
@@ -109,6 +111,30 @@ static int crypto_init_aead_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
return 0;
}
+static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ struct crypto_report_aead raead;
+ struct aead_alg *aead = &alg->cra_aead;
+
+ snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "aead");
+ snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s",
+ aead->geniv ?: "<built-in>");
+ snprintf(raead.async, CRYPTO_MAX_ALG_NAME, "%s",
+ alg->cra_flags & CRYPTO_ALG_ASYNC ? "yes" : "no");
+
+ raead.blocksize = alg->cra_blocksize;
+ raead.maxauthsize = aead->maxauthsize;
+ raead.ivsize = aead->ivsize;
+
+ NLA_PUT(skb, CRYPTOCFGA_REPORT_AEAD,
+ sizeof(struct crypto_report_aead), &raead);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
@@ -130,6 +156,7 @@ const struct crypto_type crypto_aead_type = {
#ifdef CONFIG_PROC_FS
.show = crypto_aead_show,
#endif
+ .report = crypto_aead_report,
};
EXPORT_SYMBOL_GPL(crypto_aead_type);
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
index 2e67da6..c41acbd 100644
--- a/include/linux/cryptouser.h
+++ b/include/linux/cryptouser.h
@@ -39,6 +39,7 @@ enum crypto_attr_type_t {
CRYPTOCFGA_REPORT_BLKCIPHER, /* struct crypto_report_blkcipher */
CRYPTOCFGA_REPORT_ABLKCIPHER, /* struct crypto_report_ablkcipher */
CRYPTOCFGA_REPORT_GIVCIPHER, /* struct crypto_report_ablkcipher */
+ CRYPTOCFGA_REPORT_AEAD, /* struct crypto_report_aead */
__CRYPTOCFGA_MAX
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
@@ -98,3 +99,12 @@ struct crypto_report_ablkcipher {
unsigned int max_keysize;
unsigned int ivsize;
};
+
+struct crypto_report_aead {
+ char type[CRYPTO_MAX_NAME];
+ char async[CRYPTO_MAX_NAME];
+ char geniv[CRYPTO_MAX_NAME];
+ unsigned int blocksize;
+ unsigned int maxauthsize;
+ unsigned int ivsize;
+};
--
1.7.0.4
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/aead.c | 25 +++++++++++++++++++++++++
include/linux/cryptouser.h | 1 +
2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/crypto/aead.c b/crypto/aead.c
index 17fec4a..ee5e060 100644
--- a/crypto/aead.c
+++ b/crypto/aead.c
@@ -192,6 +192,30 @@ static int crypto_init_nivaead_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
return 0;
}
+static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ struct crypto_report_aead raead;
+ struct aead_alg *aead = &alg->cra_aead;
+
+ snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "nivaead");
+ snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s", aead->geniv);
+ snprintf(raead.async, CRYPTO_MAX_ALG_NAME, "%s",
+ alg->cra_flags & CRYPTO_ALG_ASYNC ? "yes" : "no");
+
+ raead.blocksize = alg->cra_blocksize;
+ raead.maxauthsize = aead->maxauthsize;
+ raead.ivsize = aead->ivsize;
+
+ NLA_PUT(skb, CRYPTOCFGA_REPORT_NIVAEAD,
+ sizeof(struct crypto_report_aead), &raead);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
+
static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg)
@@ -213,6 +237,7 @@ const struct crypto_type crypto_nivaead_type = {
#ifdef CONFIG_PROC_FS
.show = crypto_nivaead_show,
#endif
+ .report = crypto_nivaead_report,
};
EXPORT_SYMBOL_GPL(crypto_nivaead_type);
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
index c41acbd..ecd13ec 100644
--- a/include/linux/cryptouser.h
+++ b/include/linux/cryptouser.h
@@ -40,6 +40,7 @@ enum crypto_attr_type_t {
CRYPTOCFGA_REPORT_ABLKCIPHER, /* struct crypto_report_ablkcipher */
CRYPTOCFGA_REPORT_GIVCIPHER, /* struct crypto_report_ablkcipher */
CRYPTOCFGA_REPORT_AEAD, /* struct crypto_report_aead */
+ CRYPTOCFGA_REPORT_NIVAEAD, /* struct crypto_report_aead */
__CRYPTOCFGA_MAX
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
--
1.7.0.4
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/pcompress.c | 18 ++++++++++++++++++
include/linux/cryptouser.h | 5 +++++
2 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/crypto/pcompress.c b/crypto/pcompress.c
index f7c4a7d..e9801f0 100644
--- a/crypto/pcompress.c
+++ b/crypto/pcompress.c
@@ -24,6 +24,8 @@
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/string.h>
+#include <linux/cryptouser.h>
+#include <net/netlink.h>
#include <crypto/compress.h>
#include <crypto/internal/compress.h>
@@ -46,6 +48,21 @@ static int crypto_pcomp_init_tfm(struct crypto_tfm *tfm)
return 0;
}
+static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ struct crypto_report_comp rpcomp;
+
+ snprintf(rpcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "pcomp");
+
+ NLA_PUT(skb, CRYPTOCFGA_REPORT_PCOMPRESS,
+ sizeof(struct crypto_report_comp), &rpcomp);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg)
@@ -60,6 +77,7 @@ static const struct crypto_type crypto_pcomp_type = {
#ifdef CONFIG_PROC_FS
.show = crypto_pcomp_show,
#endif
+ .report = crypto_pcomp_report,
.maskclear = ~CRYPTO_ALG_TYPE_MASK,
.maskset = CRYPTO_ALG_TYPE_MASK,
.type = CRYPTO_ALG_TYPE_PCOMPRESS,
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
index ecd13ec..d9dae98 100644
--- a/include/linux/cryptouser.h
+++ b/include/linux/cryptouser.h
@@ -41,6 +41,7 @@ enum crypto_attr_type_t {
CRYPTOCFGA_REPORT_GIVCIPHER, /* struct crypto_report_ablkcipher */
CRYPTOCFGA_REPORT_AEAD, /* struct crypto_report_aead */
CRYPTOCFGA_REPORT_NIVAEAD, /* struct crypto_report_aead */
+ CRYPTOCFGA_REPORT_PCOMPRESS, /* struct crypto_report_comp */
__CRYPTOCFGA_MAX
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
@@ -109,3 +110,7 @@ struct crypto_report_aead {
unsigned int maxauthsize;
unsigned int ivsize;
};
+
+struct crypto_report_comp {
+ char type[CRYPTO_MAX_NAME];
+};
--
1.7.0.4
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/rng.c | 20 ++++++++++++++++++++
include/linux/cryptouser.h | 6 ++++++
2 files changed, 26 insertions(+), 0 deletions(-)
diff --git a/crypto/rng.c b/crypto/rng.c
index 45229ae..feb7de0 100644
--- a/crypto/rng.c
+++ b/crypto/rng.c
@@ -21,6 +21,8 @@
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/cryptouser.h>
+#include <net/netlink.h>
static DEFINE_MUTEX(crypto_default_rng_lock);
struct crypto_rng *crypto_default_rng;
@@ -58,6 +60,23 @@ static int crypto_init_rng_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
return 0;
}
+static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ struct crypto_report_rng rrng;
+
+ snprintf(rrng.type, CRYPTO_MAX_ALG_NAME, "%s", "rng");
+
+ rrng.seedsize = alg->cra_rng.seedsize;
+
+ NLA_PUT(skb, CRYPTOCFGA_REPORT_RNG,
+ sizeof(struct crypto_report_rng), &rrng);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg)
@@ -78,6 +97,7 @@ const struct crypto_type crypto_rng_type = {
#ifdef CONFIG_PROC_FS
.show = crypto_rng_show,
#endif
+ .report = crypto_rng_report,
};
EXPORT_SYMBOL_GPL(crypto_rng_type);
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
index d9dae98..761e9df 100644
--- a/include/linux/cryptouser.h
+++ b/include/linux/cryptouser.h
@@ -42,6 +42,7 @@ enum crypto_attr_type_t {
CRYPTOCFGA_REPORT_AEAD, /* struct crypto_report_aead */
CRYPTOCFGA_REPORT_NIVAEAD, /* struct crypto_report_aead */
CRYPTOCFGA_REPORT_PCOMPRESS, /* struct crypto_report_comp */
+ CRYPTOCFGA_REPORT_RNG, /* struct crypto_report_rng */
__CRYPTOCFGA_MAX
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
@@ -114,3 +115,8 @@ struct crypto_report_aead {
struct crypto_report_comp {
char type[CRYPTO_MAX_NAME];
};
+
+struct crypto_report_rng {
+ char type[CRYPTO_MAX_NAME];
+ unsigned int seedsize;
+};
--
1.7.0.4
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/crypto_user.c | 29 +++++++++++++++++++++++++++++
include/linux/cryptouser.h | 8 ++++++++
2 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 68d405d..9d10d2f 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -69,6 +69,25 @@ static struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p)
return alg;
}
+static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ struct crypto_report_cipher rcipher;
+
+ snprintf(rcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "cipher");
+
+ rcipher.blocksize = alg->cra_blocksize;
+ rcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
+ rcipher.max_keysize = alg->cra_cipher.cia_max_keysize;
+
+ NLA_PUT(skb, CRYPTOCFGA_REPORT_CIPHER,
+ sizeof(struct crypto_report_cipher), &rcipher);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
static int crypto_report_one(struct crypto_alg *alg,
struct crypto_report_base *rb, struct sk_buff *skb)
{
@@ -96,6 +115,16 @@ static int crypto_report_one(struct crypto_alg *alg,
if (alg->cra_type && alg->cra_type->report) {
if (alg->cra_type->report(skb, alg))
goto nla_put_failure;
+
+ goto out;
+ }
+
+ switch (alg->cra_flags & (CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_LARVAL)) {
+ case CRYPTO_ALG_TYPE_CIPHER:
+ if (crypto_report_cipher(skb, alg))
+ goto nla_put_failure;
+
+ break;
}
out:
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
index 761e9df..4af8222 100644
--- a/include/linux/cryptouser.h
+++ b/include/linux/cryptouser.h
@@ -43,6 +43,7 @@ enum crypto_attr_type_t {
CRYPTOCFGA_REPORT_NIVAEAD, /* struct crypto_report_aead */
CRYPTOCFGA_REPORT_PCOMPRESS, /* struct crypto_report_comp */
CRYPTOCFGA_REPORT_RNG, /* struct crypto_report_rng */
+ CRYPTOCFGA_REPORT_CIPHER, /* struct crypto_report_cipher */
__CRYPTOCFGA_MAX
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
@@ -84,6 +85,13 @@ struct crypto_report_ahash {
unsigned int digestsize;
};
+struct crypto_report_cipher {
+ char type[CRYPTO_MAX_ALG_NAME];
+ unsigned int blocksize;
+ unsigned int min_keysize;
+ unsigned int max_keysize;
+};
+
struct crypto_report_blkcipher {
char type[CRYPTO_MAX_NAME];
char geniv[CRYPTO_MAX_NAME];
--
1.7.0.4
Signed-off-by: Steffen Klassert <[email protected]>
---
crypto/crypto_user.c | 21 +++++++++++++++++++++
include/linux/cryptouser.h | 1 +
2 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 9d10d2f..2cc3694 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -88,6 +88,22 @@ nla_put_failure:
return -EMSGSIZE;
}
+static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg)
+{
+ struct crypto_report_comp rcomp;
+
+ snprintf(rcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "compression");
+
+ NLA_PUT(skb, CRYPTOCFGA_REPORT_COMPRESS,
+ sizeof(struct crypto_report_comp), &rcomp);
+
+ return 0;
+
+nla_put_failure:
+ return -EMSGSIZE;
+}
+
+
static int crypto_report_one(struct crypto_alg *alg,
struct crypto_report_base *rb, struct sk_buff *skb)
{
@@ -125,6 +141,11 @@ static int crypto_report_one(struct crypto_alg *alg,
goto nla_put_failure;
break;
+ case CRYPTO_ALG_TYPE_COMPRESS:
+ if (crypto_report_comp(skb, alg))
+ goto nla_put_failure;
+
+ break;
}
out:
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h
index 4af8222..56992c1 100644
--- a/include/linux/cryptouser.h
+++ b/include/linux/cryptouser.h
@@ -44,6 +44,7 @@ enum crypto_attr_type_t {
CRYPTOCFGA_REPORT_PCOMPRESS, /* struct crypto_report_comp */
CRYPTOCFGA_REPORT_RNG, /* struct crypto_report_rng */
CRYPTOCFGA_REPORT_CIPHER, /* struct crypto_report_cipher */
+ CRYPTOCFGA_REPORT_COMPRESS, /* struct crypto_report_comp */
__CRYPTOCFGA_MAX
#define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1)
--
1.7.0.4
On Wed, Aug 17, 2011 at 02:10:13PM +0200, Steffen Klassert wrote:
>
> +struct crypto_user_alg {
> + char cru_name[CRYPTO_MAX_ALG_NAME];
> + char cru_driver_name[CRYPTO_MAX_ALG_NAME];
> + __u32 type;
> + __u32 mask;
> +};
> +
> +#define CRYPTO_MAX_NAME CRYPTO_MAX_ALG_NAME
> +
> +struct crypto_report_base {
> + char name[CRYPTO_MAX_ALG_NAME];
> + char driver_name[CRYPTO_MAX_ALG_NAME];
> + char module_name[CRYPTO_MAX_NAME];
> + char selftest[CRYPTO_MAX_NAME];
> + int priority;
> + int refcnt;
> +};
We should use one structure for both creating algorithms and
querying them. User-space can leave the query fields blank
when creating them.
On another note, all fields specified when creating an algorithm
should be returned when querying/reporting. This is so that
we can recreate the exact configuration after dumping.
Also, instead of returning selftest as a string, a single bit
would suffice. So I'd suggest turning it into flags of type
__u32.
In fact, let's turn the other two int fields into __u32 too.
Sorry for not pointing this out earlier. But we need to get this
right the first time as we'll be stuck with the interface for
ever.
Cheers,
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
On Mon, Aug 22, 2011 at 02:59:01PM +0800, Herbert Xu wrote:
> On Wed, Aug 17, 2011 at 02:10:13PM +0200, Steffen Klassert wrote:
> >
> > +struct crypto_user_alg {
> > + char cru_name[CRYPTO_MAX_ALG_NAME];
> > + char cru_driver_name[CRYPTO_MAX_ALG_NAME];
> > + __u32 type;
> > + __u32 mask;
> > +};
> > +
> > +#define CRYPTO_MAX_NAME CRYPTO_MAX_ALG_NAME
> > +
> > +struct crypto_report_base {
> > + char name[CRYPTO_MAX_ALG_NAME];
> > + char driver_name[CRYPTO_MAX_ALG_NAME];
> > + char module_name[CRYPTO_MAX_NAME];
> > + char selftest[CRYPTO_MAX_NAME];
> > + int priority;
> > + int refcnt;
> > +};
>
> We should use one structure for both creating algorithms and
> querying them. User-space can leave the query fields blank
> when creating them.
Do you think about merging the two structures above and to
keep the algorithm specific structures separate, or to
merge all of them to one big structure?
I think we would be most flexible if we would merge the two
structures above and keep the algorithm specific structures
separate.
>
> On another note, all fields specified when creating an algorithm
> should be returned when querying/reporting. This is so that
> we can recreate the exact configuration after dumping.
Yes, indeed.
>
> Also, instead of returning selftest as a string, a single bit
> would suffice. So I'd suggest turning it into flags of type
> __u32.
Ok.
>
> In fact, let's turn the other two int fields into __u32 too.
>
Ok.
On Mon, Aug 29, 2011 at 10:18:18AM +0200, Steffen Klassert wrote:
> On Mon, Aug 22, 2011 at 02:59:01PM +0800, Herbert Xu wrote:
> > On Wed, Aug 17, 2011 at 02:10:13PM +0200, Steffen Klassert wrote:
> > >
> > > +struct crypto_user_alg {
> > > + char cru_name[CRYPTO_MAX_ALG_NAME];
> > > + char cru_driver_name[CRYPTO_MAX_ALG_NAME];
> > > + __u32 type;
> > > + __u32 mask;
> > > +};
> > > +
> > > +#define CRYPTO_MAX_NAME CRYPTO_MAX_ALG_NAME
> > > +
> > > +struct crypto_report_base {
> > > + char name[CRYPTO_MAX_ALG_NAME];
> > > + char driver_name[CRYPTO_MAX_ALG_NAME];
> > > + char module_name[CRYPTO_MAX_NAME];
> > > + char selftest[CRYPTO_MAX_NAME];
> > > + int priority;
> > > + int refcnt;
> > > +};
> >
> > We should use one structure for both creating algorithms and
> > querying them. User-space can leave the query fields blank
> > when creating them.
>
> Do you think about merging the two structures above and to
> keep the algorithm specific structures separate, or to
> merge all of them to one big structure?
>
> I think we would be most flexible if we would merge the two
> structures above and keep the algorithm specific structures
> separate.
As long as we maintain the ability to replay queried results
it should be fine. That is, by sending the result of a dump
to another system you should be able to recreate the original
configuration state.
Thanks,
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt