Parallel IPsec v3
Steffen Klassert
maintainercover Parallel IPsec v3
This patchset adds the 'pcrypt' parallel crypto template. With this template it is possible to process the crypto requests of a transform in parallel without getting request reorder. This is in particular interesting for IPsec.
The parallel crypto template is based on a generic parallelization/serialization method. This method uses the remote softirq invocation infrastructure for parallelization and serialization. With this method data objects can be processed in parallel, starting at some given point.
After doing some expensive operations in parallel, it is possible to serialize again. The parallelized data objects return after serialization in the order as they were before the parallelization. In the case of IPsec, this makes it possible to run the expensive parts in parallel without getting packet reordering.
Changes from v2:
- The xfrm netlink configuration code is dropped,
this will be an extra patchset.
- Add generic aead wrapper interface to be able to wrap an aead algorithm with an arbitrary crypto template.
- Convert pcrypt to use the generic aead wrapper.
- Add support for aead algorithms to eseqiv.
- Add support for the pcrypt aead wrapper to authenc. It's now possible to choose for pcrypt as the default authenc wrapper with a module parameter.
- Patchset applies to linux-2.6 git current.
Changes from v1:
- cpu_chainiv is dropped, pcrypt uses eseqiv as it's IV generator now.
- Add a xfrm netlink message to be able to choose for pcrypt from userspace.
- Use pcrypt just if it is selected from userspace.
- Patchset applies to 2.6.30-rc3
Steffen
Steffen Klassert
maintainerRFC PATCH 1/5 padata: generic interface for parallel processing
This patch introduces an interface to process data objects in parallel. On request it is possible to serialize again. The parallelized objects return after serialization in the same order as they were before the parallelization.
--- include/linux/interrupt.h | 3 +- include/linux/padata.h | 116 +++++++++++ kernel/Makefile | 2 +- kernel/padata.c | 490 +++++++++++++++++++++++++++++++++++++++++++++ kernel/softirq.c | 2 +- 5 files changed, 610 insertions(+), 3 deletions(-) create mode 100644 include/linux/padata.h create mode 100644 kernel/padata.c
include/linux/interrupt.h +2 -1
@@ -338,7 +338,8 @@ enumTASKLET_SOFTIRQ ,SCHED_SOFTIRQ ,HRTIMER_SOFTIRQ , -RCU_SOFTIRQ ,/* Preferable RCU should always be the last softirq */ +PADATA_SOFTIRQ , +RCU_SOFTIRQ ,/* Preferable RCU should always be the last softirq */ NR_SOFTIRQS };
include/linux/padata.h new file +116 -0
116 lines not on this page · raw message
kernel/Makefile +1 -1
@@ -40,7 +40,7 @@ obj-$(CONFIG_RT_MUTEXES) += rtmutex.o obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o obj-$(CONFIG_RT_MUTEX_TESTER) += rtmutex-tester.o obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o -obj-$(CONFIG_USE_GENERIC_SMP_HELPERS) += smp.o +obj-$(CONFIG_USE_GENERIC_SMP_HELPERS) += smp.o padata.o ifneq ($(CONFIG_SMP),y) obj-y += up.o endif
kernel/padata.c new file +490 -0
490 lines not on this page · raw message
kernel/softirq.c +1 -1
@@ -56,7 +56,7 @@ static DEFINE_PER_CPU(struct task_struct *, ksoftirqd);char *softirq_to_name[NR_SOFTIRQS ] = {"HI" ,"TIMER" ,"NET_TX" ,"NET_RX" ,"BLOCK" , -"TASKLET" ,"SCHED" ,"HRTIMER" ,"RCU" +"TASKLET" ,"SCHED" ,"HRTIMER" ,"PADATA" ,"RCU" };/*
Signature · 1 line
1.5.4.2
Steffen Klassert
maintainerRFC PATCH 2/5 aead: Add generic aead wrapper interface
In reply to Steffen KlassertThis patch adds an interface to wrap aead algorithms with an arbitrary crypto template. This is useful to make a certain version of an aead algorithm the system default of that algorithm.
--- crypto/aead.c | 286 +++++++++++++++++++++++++++++++++++++++- include/crypto/internal/aead.h | 8 + include/linux/crypto.h | 10 +- 3 files changed, 295 insertions(+), 9 deletions(-)
crypto/aead.c +279 -7
@@ -286,6 +286,7 @@ struct crypto_instance *aead_geniv_alloc(struct crypto_template *tmpl, inst->alg.cra_aead.ivsize = alg->cra_aead.ivsize; inst->alg.cra_aead.maxauthsize = alg->cra_aead.maxauthsize; inst->alg.cra_aead.geniv = alg->cra_aead.geniv; + inst->alg.cra_aead.wrapper = alg->cra_aead.wrapper; inst->alg.cra_aead.setkey = alg->cra_aead.setkey; inst->alg.cra_aead.setauthsize = alg->cra_aead.setauthsize;
@@ -407,6 +408,262 @@ out:return err; } +static int crypto_init_wrapaead_ops (struct crypto_tfm *tfm,u32 type,u32 mask) +{ +struct aead_alg *alg = &tfm->__crt_alg->cra_aead; +struct aead_tfm *crt = &tfm->crt_aead; + +if (max (alg->maxauthsize, alg->ivsize) >PAGE_SIZE /8 ) +return -EINVAL ; + + crt->setkey = alg->setkey; + crt->encrypt = alg->encrypt; + crt->decrypt = alg->decrypt; + crt->givencrypt = alg->givencrypt ?: no_givcrypt; + crt->givdecrypt = alg->givdecrypt ?: no_givcrypt; + crt->base =__crypto_aead_cast (tfm); + crt->ivsize = alg->ivsize; + crt->authsize = alg->maxauthsize; + +return 0 ; +} + +static void crypto_wrapaead_show (struct seq_file *m,struct crypto_alg *alg) + __attribute__ ((unused)); +static void crypto_wrapaead_show (struct seq_file *m,struct crypto_alg *alg) +{ +struct aead_alg *aead = &alg->cra_aead; + +seq_printf (m,"type : wrapped aead\n" ); +seq_printf (m,"async : %s\n" , alg->cra_flags &CRYPTO_ALG_ASYNC ? +"yes" :"no" ); +seq_printf (m,"blocksize : %u\n" , alg->cra_blocksize); +seq_printf (m,"ivsize : %u\n" , aead->ivsize); +seq_printf (m,"maxauthsize : %u\n" , aead->maxauthsize); +seq_printf (m,"geniv : %s\n" , aead->geniv ?:"<built-in>" ); +seq_printf (m,"wrapper : %s\n" , alg->cra_flags &CRYPTO_ALG_WRAP ? + aead->wrapper :"<built-in>" ); +} + +const struct crypto_type crypto_wrapaead_type = { + .ctxsize = crypto_aead_ctxsize, + .init = crypto_init_wrapaead_ops, +#ifdef CONFIG_PROC_FS + .show = crypto_wrapaead_show, +#endif +}; +EXPORT_SYMBOL_GPL (crypto_wrapaead_type); + +static int crypto_grab_wrapaead (struct crypto_aead_spawn *spawn, +const char *name,u32 type,u32 mask) +{ +struct crypto_alg *alg; +int err; + + type &= ~(CRYPTO_ALG_TYPE_MASK |CRYPTO_ALG_WRAP ); + type |=CRYPTO_ALG_TYPE_AEAD ; + mask |=CRYPTO_ALG_TYPE_MASK |CRYPTO_ALG_WRAP ; + + alg =crypto_alg_mod_lookup (name, type, mask); +if (IS_ERR (alg)) +return PTR_ERR (alg); + + err =crypto_init_spawn (&spawn->base, alg, spawn->base.inst, mask); +crypto_mod_put (alg); +return err; +} + +struct crypto_instance *aead_wrap_alloc (struct crypto_template *tmpl, +struct rtattr **tb, +unsigned int ctx_size,u32 type, +u32 mask) +{ +const char *name; +struct crypto_aead_spawn *spawn; +struct crypto_attr_type *algt; +struct crypto_instance *inst; +struct crypto_alg *alg; +int err; + + algt =crypto_get_attr_type (tb); + err =PTR_ERR (algt); +if (IS_ERR (algt)) +return ERR_PTR (err); + +if ((algt->type ^ (CRYPTO_ALG_TYPE_AEAD |CRYPTO_ALG_WRAP )) & + algt->mask) +return ERR_PTR (-EINVAL ); + + name =crypto_attr_alg_name (tb[1 ]); + err =PTR_ERR (name); +if (IS_ERR (name)) +return ERR_PTR (err); + + inst =kzalloc (sizeof (*inst) + ctx_size,GFP_KERNEL ); +if (!inst) +return ERR_PTR (-ENOMEM ); + + spawn =crypto_instance_ctx (inst); + +/* Ignore async algorithms if necessary. */ + mask |=crypto_requires_sync (algt->type, algt->mask); + +crypto_set_aead_spawn (spawn, inst); + err =crypto_grab_wrapaead (spawn, name, type, mask); +if (err) + goto err_free_inst; + + alg =crypto_aead_spawn_alg (spawn); + + err = -EINVAL ; +if (alg->cra_type != &crypto_aead_type) + goto err_drop_alg; + +if (algt->mask &CRYPTO_ALG_WRAP ) { +if (strcmp (tmpl->name, alg->cra_aead.wrapper)) + goto err_drop_alg; + +memcpy (inst->alg.cra_name, alg->cra_name,CRYPTO_MAX_ALG_NAME ); +memcpy (inst->alg.cra_driver_name, alg->cra_driver_name, +CRYPTO_MAX_ALG_NAME ); + }else { + err = -ENAMETOOLONG ; +if (snprintf (inst->alg.cra_name,CRYPTO_MAX_ALG_NAME , +"%s(%s)" , tmpl->name, alg->cra_name) >= +CRYPTO_MAX_ALG_NAME ) + goto err_drop_alg; +if (snprintf (inst->alg.cra_driver_name,CRYPTO_MAX_ALG_NAME , +"%s(%s)" , tmpl->name, alg->cra_driver_name) >= +CRYPTO_MAX_ALG_NAME ) + goto err_drop_alg; + } + + inst->alg.cra_flags =CRYPTO_ALG_TYPE_AEAD |CRYPTO_ALG_WRAP ; + inst->alg.cra_flags |= alg->cra_flags + & (CRYPTO_ALG_GENIV |CRYPTO_ALG_ASYNC ); + inst->alg.cra_blocksize = alg->cra_blocksize; + inst->alg.cra_alignmask = alg->cra_alignmask; + inst->alg.cra_aead.ivsize = alg->cra_aead.ivsize; + inst->alg.cra_aead.maxauthsize = alg->cra_aead.maxauthsize; + inst->alg.cra_type = &crypto_wrapaead_type; + inst->alg.cra_aead.wrapper = alg->cra_aead.wrapper; + inst->alg.cra_aead.geniv = alg->cra_aead.geniv; + inst->alg.cra_priority = alg->cra_priority +100 ; + +out: +return inst; + +err_drop_alg: +crypto_drop_aead (spawn); +err_free_inst: +kfree (inst); + inst =ERR_PTR (err); + goto out; +} +EXPORT_SYMBOL_GPL (aead_wrap_alloc); + +void aead_wrap_free (struct crypto_instance *inst) +{ +crypto_drop_aead (crypto_instance_ctx (inst)); +kfree (inst); +} +EXPORT_SYMBOL_GPL (aead_wrap_free); + +int aead_wrap_init (struct crypto_tfm *tfm) +{ +struct crypto_instance *inst =crypto_tfm_alg_instance (tfm); +struct crypto_aead *aead; + + aead =crypto_spawn_aead (crypto_instance_ctx (inst)); +if (IS_ERR (aead)) +return PTR_ERR (aead); + + tfm->crt_aead.base = aead; + tfm->crt_aead.reqsize +=crypto_aead_reqsize (aead); + +return 0 ; +} +EXPORT_SYMBOL_GPL (aead_wrap_init); + +void aead_wrap_exit (struct crypto_tfm *tfm) +{ +crypto_free_aead (tfm->crt_aead.base); +} +EXPORT_SYMBOL_GPL (aead_wrap_exit); + +static int crypto_wrapaead_default (struct crypto_alg *alg,u32 type,u32 mask) +{ +struct rtattr *tb[3 ]; +struct { +struct rtattr attr; +struct crypto_attr_type data; + } ptype; +struct { +struct rtattr attr; +struct crypto_attr_alg data; + } palg; +struct crypto_template *tmpl; +struct crypto_instance *inst; +struct crypto_alg *larval; +const char *wrapper; +int err; + + larval =crypto_larval_lookup (alg->cra_driver_name, +CRYPTO_ALG_TYPE_AEAD |CRYPTO_ALG_WRAP , +CRYPTO_ALG_TYPE_MASK |CRYPTO_ALG_WRAP ); + err =PTR_ERR (larval); +if (IS_ERR (larval)) + goto out; + + err = -EAGAIN ; +if (!crypto_is_larval (larval)) + goto drop_larval; + + ptype.attr.rta_len =sizeof (ptype); + ptype.attr.rta_type =CRYPTOA_TYPE ; + ptype.data.type = type |CRYPTO_ALG_WRAP ; + ptype.data.mask = mask |CRYPTO_ALG_WRAP ; + tb[0 ] = &ptype.attr; + + palg.attr.rta_len =sizeof (palg); + palg.attr.rta_type =CRYPTOA_ALG ; +/* Must use the exact name to locate ourselves. */ +memcpy (palg.data.name, alg->cra_driver_name,CRYPTO_MAX_ALG_NAME ); + tb[1 ] = &palg.attr; + + tb[2 ] =NULL ; + + wrapper = alg->cra_aead.wrapper; + + tmpl =crypto_lookup_template (wrapper); + err = -ENOENT ; +if (!tmpl) + goto kill_larval; + + inst = tmpl->alloc (tb); + err =PTR_ERR (inst); +if (IS_ERR (inst)) + goto put_tmpl; + +if ((err =crypto_register_instance (tmpl, inst))) { + tmpl->free (inst); + goto put_tmpl; + } + +/* Redo the lookup to use the instance we just registered. */ + err = -EAGAIN ; + +put_tmpl: +crypto_tmpl_put (tmpl); +kill_larval: +crypto_larval_kill (larval); +drop_larval: +crypto_mod_put (larval); +out: +crypto_mod_put (alg); +return err; +} +static struct crypto_alg *crypto_lookup_aead (const char *name,u32 type,u32 mask) {
@@ -416,10 +673,13 @@ static struct crypto_alg *crypto_lookup_aead(const char *name, u32 type,if (IS_ERR (alg))return alg; -if (alg->cra_type == &crypto_aead_type) +if (alg->cra_type == &crypto_wrapaead_type)return alg; -if (!alg->cra_aead.ivsize) +if ((alg->cra_type == &crypto_aead_type) && !alg->cra_aead.wrapper) +return alg; + +if (!alg->cra_aead.ivsize && !alg->cra_aead.wrapper)return alg;crypto_mod_put (alg);
@@ -428,7 +688,7 @@ static struct crypto_alg *crypto_lookup_aead(const char *name, u32 type,if (IS_ERR (alg))return alg; -if (alg->cra_type == &crypto_aead_type) { +if (alg->cra_type == &crypto_wrapaead_type) {if ((alg->cra_flags ^ type ^ ~mask) &CRYPTO_ALG_TESTED ) {crypto_mod_put (alg); alg =ERR_PTR (-ENOENT );
@@ -436,6 +696,18 @@ static struct crypto_alg *crypto_lookup_aead(const char *name, u32 type,return alg; } +if (alg->cra_type == &crypto_aead_type) { +if ((alg->cra_flags ^ type ^ ~mask) &CRYPTO_ALG_TESTED ) { +crypto_mod_put (alg); + alg =ERR_PTR (-ENOENT ); + } + +if (!alg->cra_aead.wrapper) +return alg; + +return ERR_PTR (crypto_wrapaead_default (alg, type, mask)); + } +BUG_ON (!alg->cra_aead.ivsize);return ERR_PTR (crypto_nivaead_default (alg, type, mask));
@@ -447,9 +719,9 @@ int crypto_grab_aead(struct crypto_aead_spawn *spawn, const char *name,struct crypto_alg *alg;int err; - type &= ~(CRYPTO_ALG_TYPE_MASK |CRYPTO_ALG_GENIV ); + type &= ~(CRYPTO_ALG_TYPE_MASK |CRYPTO_ALG_GENIV |CRYPTO_ALG_WRAP ); type |=CRYPTO_ALG_TYPE_AEAD ; - mask &= ~(CRYPTO_ALG_TYPE_MASK |CRYPTO_ALG_GENIV ); + mask &= ~(CRYPTO_ALG_TYPE_MASK |CRYPTO_ALG_GENIV |CRYPTO_ALG_WRAP ); mask |=CRYPTO_ALG_TYPE_MASK ; alg =crypto_lookup_aead (name, type, mask);
@@ -467,9 +739,9 @@ struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask)struct crypto_tfm *tfm;int err; - type &= ~(CRYPTO_ALG_TYPE_MASK |CRYPTO_ALG_GENIV ); + type &= ~(CRYPTO_ALG_TYPE_MASK |CRYPTO_ALG_GENIV |CRYPTO_ALG_WRAP ); type |=CRYPTO_ALG_TYPE_AEAD ; - mask &= ~(CRYPTO_ALG_TYPE_MASK |CRYPTO_ALG_GENIV ); + mask &= ~(CRYPTO_ALG_TYPE_MASK |CRYPTO_ALG_GENIV |CRYPTO_ALG_WRAP ); mask |=CRYPTO_ALG_TYPE_MASK ;for (;;) {
include/crypto/internal/aead.h +8 -0
@@ -65,6 +65,14 @@ static inline struct crypto_aead *aead_geniv_base(struct crypto_aead *geniv)return crypto_aead_crt (geniv)->base; } +struct crypto_instance *aead_wrap_alloc (struct crypto_template *tmpl, +struct rtattr **tb, +unsigned int ctx_size,u32 type, +u32 mask); +void aead_wrap_free (struct crypto_instance *inst); +int aead_wrap_init (struct crypto_tfm *tfm); +void aead_wrap_exit (struct crypto_tfm *tfm); +static inline void *aead_givcrypt_reqctx (struct aead_givcrypt_request *req) {return aead_request_ctx (&req->areq);
include/linux/crypto.h +8 -2
@@ -71,6 +71,8 @@#define CRYPTO_ALG_TESTED 0x00000400 +#define CRYPTO_ALG_WRAP 0x00000800 +/* * Transform masks and values (for crt_flags). */
@@ -242,6 +244,7 @@ struct aead_alg {int (*givdecrypt)(struct aead_givcrypt_request *req);const char *geniv; +const char *wrapper;unsigned int ivsize;unsigned int maxauthsize;
@@ -881,9 +884,12 @@ static inline unsigned int crypto_aead_reqsize(struct crypto_aead *tfm) }static inline void aead_request_set_tfm (struct aead_request *req, -struct crypto_aead *tfm) +struct crypto_aead *aead) { - req->base.tfm =crypto_aead_tfm (crypto_aead_crt (tfm)->base); +struct crypto_tfm *tfm =crypto_aead_tfm (aead); + + req->base.tfm = tfm->__crt_alg->cra_flags &CRYPTO_ALG_WRAP ? + tfm :crypto_aead_tfm (crypto_aead_crt (aead)->base); } static inline struct aead_request *aead_request_alloc(struct crypto_aead *tfm,
Signature · 1 line
1.5.4.2
Herbert Xu
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 5 lines · Steffen Klassert
This patch adds an interface to wrap aead algorithms with an arbitrary crypto template. This is useful to make a certain version of an aead algorithm the system default of that algorithm.
Signed-off-by Steffen Klassert <[email protected]>
Sorry for the late response, but rather than making ad-hoc user interfaces like this, I'd like this to be part of the crypto user- space API where you should be able to configure the priorities of each implementation which determines the system default.
Do we really need this patch right now? If not I think it could be removed from this set so the others can go in first.
Thanks,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtHerbert Xu
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
In reply to Steffen KlassertQuoted 5 lines · Steffen Klassert
This patch adds an interface to wrap aead algorithms with an arbitrary crypto template. This is useful to make a certain version of an aead algorithm the system default of that algorithm.
Signed-off-by Steffen Klassert <[email protected]>
Hmm, it seems that this patch is completely intertwined into the rest of the patches so we can't just kill it. Can you elaborate on the rationale behind this wrap work? I'm curious to find out what we gain by this over the much simpler patch you had in your previous set.
Thanks,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtSteffen Klassert
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 7 lines · Herbert Xu
Hmm, it seems that this patch is completely intertwined into the rest of the patches so we can't just kill it. Can you elaborate on the rationale behind this wrap work? I'm curious to find out what we gain by this over the much simpler patch you had in your previous set.
The reason for the wrap work is to have a possibility to choose a certain version of an algorithm as the system default. The advantage e.g. for pcrypt is that we can turn over the whole system to pcrypt, or we can choose for pcrypt by the algorithm name if we want to use it just for a subset of transforms. In particular we have a possibility to use pcrypt without touching other subsystems (like networking) and userspace tools for now.
Herbert Xu
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 8 lines · Steffen Klassert
The reason for the wrap work is to have a possibility to choose a certain version of an algorithm as the system default. The advantage e.g. for pcrypt is that we can turn over the whole system to pcrypt, or we can choose for pcrypt by the algorithm name if we want to use it just for a subset of transforms. In particular we have a possibility to use pcrypt without touching other subsystems (like networking) and userspace tools for now.
Yes but what you're creating is a user-space API. IMHO we don't want to have ad-hoc APIs such as this scattered around the place. pcrypt is certainly not the only algorithm that needs to be able to decide whether it should serve as the system default.
So what I suggest is that you make pcrypt take a higher priority for now, so that it always is the default once instantiated. After all if you instantiate it then you probably want to use it as the default.
We can then work on the generic user-space API to control crypto API algorithms, in particular, allow the user to change their priorities so as to determine the system default.
This has been on my todo list for years, but it has never risen to the top. What I have in mind is a netlink protocol not unlike xfrm which controls crypto algorithm properties (and queries them so we can obsolete /proc/crypto).
Thanks,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtSteffen Klassert
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 10 lines · Herbert Xu
Quoted 8 lines · Steffen Klassert
The reason for the wrap work is to have a possibility to choose a certain version of an algorithm as the system default. The advantage e.g. for pcrypt is that we can turn over the whole system to pcrypt, or we can choose for pcrypt by the algorithm name if we want to use it just for a subset of transforms. In particular we have a possibility to use pcrypt without touching other subsystems (like networking) and userspace tools for now.
Quoted 4 lines
Yes but what you're creating is a user-space API. IMHO we don't want to have ad-hoc APIs such as this scattered around the place. pcrypt is certainly not the only algorithm that needs to be able to decide whether it should serve as the system default.
Hm, I have not considered this as an user-space API. It just adds the possibility to wrap an arbitrary crypto template arround a given aead type algorithm, similar than aead_geniv wraps a IV generator template arround a nivaead type algorithm.
The thing that connects this to user-space is the authenc patch by adding the possibility to set a wrapper name with a module parameter. This is probaply such an ad-hoc API that you want to avoid, right?
Quoted 5 lines
So what I suggest is that you make pcrypt take a higher priority for now, so that it always is the default once instantiated. After all if you instantiate it then you probably want to use it as the default.
Yes, in fact the instantiating is my problem. E.g. esp asks for an authenc(...,...) algorithm, so the crypto manager tries to instantiate a template with name authenc. If I don't want to touch the network subsystem I can't change the name to pcrypt(authenc(...,...)) easy. So one solution was to add a default wrapper template arround authenc that will be instantiated along with authenc.
I'm not insisting on that wap work. I just want to have a easy possibility to instantiate pcrypt on the users choice for now, at best without the need to touch other subsystems.
Herbert Xu
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 6 lines · Steffen Klassert
Quoted 5 lines
So what I suggest is that you make pcrypt take a higher priority for now, so that it always is the default once instantiated. After all if you instantiate it then you probably want to use it as the default.
Quoted 6 lines
Yes, in fact the instantiating is my problem. E.g. esp asks for an
authenc(...,...)algorithm, so the crypto manager tries to instantiate a template with name authenc. If I don't want to touch the network subsystem I can't change the name to pcrypt(authenc(...,...)) easy. So one solution was to add a default wrapper template arround authenc that will be instantiated along with authenc.
I see. How about if we let tcrypt test algorithms by name, e.g., something like
modprobe tcrypt alg='pcrypt(authenc(hmac(sha1),cbc(aes))'
which would simply call crypto_has_alg on the string alg?
That should instantiate alg, and test it too if there are vectors.
This is a new interface too, but at least it pretends to be generic :)
Cheers,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtSteffen Klassert
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 6 lines · Herbert Xu
I see. How about if we let tcrypt test algorithms by name, e.g., something like
modprobe tcrypt alg='pcrypt(authenc(hmac(sha1),cbc(aes))'
I'm not that sure whether this does what I want.
If pcrypt has cra_name = pcrypt(authenc(hmac(sha1),cbc(aes))) this would instatiate this algorithm, but esp wants an algorithm with cra_name = authenc(hmac(sha1),cbc(aes)).
These names are not matching, so __crypto_alg_lookup() will not choose for the pcrypt version regardless of the higher priority.
Setting cra_name = authenc(hmac(sha1),cbc(aes)) for pcrypt seems to be not possible too, because pcrypt needs authenc as an underlain algorithm and the system will not load two aead algorithms with the same name. This was one of the reasons why I added a wrapper to authenc that is instantiated along with authenc.
Is this the case or do I miss something?
Herbert Xu
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 8 lines · Steffen Klassert
Quoted 6 lines · Herbert Xu
I see. How about if we let tcrypt test algorithms by name, e.g., something like
modprobe tcrypt alg='pcrypt(authenc(hmac(sha1),cbc(aes))'
Quoted 7 lines
I'm not that sure whether this does what I want.
If pcrypt has
cra_name= pcrypt(authenc(hmac(sha1),cbc(aes))) this would instatiate this algorithm, but esp wants an algorithm withcra_name= authenc(hmac(sha1),cbc(aes)).
These names are not matching, so__crypto_alg_lookup()will not choose for the pcrypt version regardless of the higher priority.
When pcrypt instantiates an algorithm, it should set cra_name to %s and cra_driver_name to pcrypt(%s). So as long as the pcrypt priority is higher than the underlying algorithm, it should all work.
See for instance how cryptd does it.
Cheers,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtSteffen Klassert
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 8 lines · Herbert Xu
When pcrypt instantiates an algorithm, it should set
cra_nameto %s andcra_driver_nameto pcrypt(%s). So as long as the pcrypt priority is higher than the underlying algorithm, it should all work.See for instance how cryptd does it.
Aha, ok I see. So I will see whether I can instantiate pcrypt with tcrypt as you suggested and drop the wrapper from the next patchset.
Thanks!
Herbert Xu
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 4 lines · Steffen Klassert
Aha, ok I see. So I will see whether I can instantiate pcrypt with tcrypt as you suggested and drop the wrapper from the next patchset.
It should be straightforward as you just need to call crypto_has_alg.
Thanks,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtSteffen Klassert
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
In reply to Herbert XuQuoted 6 lines · Herbert Xu
When pcrypt instantiates an algorithm, it should set
cra_nameto %s andcra_driver_nameto pcrypt(%s). So as long as the pcrypt priority is higher than the underlying algorithm, it should all work.
As it is, I can instantiate pcrypt if the priority of pcrypt is lower than the priority of the underlying algorithm. If I do the priority check in crypto_alg_tested() the other way arround, I get it to work if pcrypt has a higher priority than the underlying algorithm. So I guess we need the patch below, right? If so, I would send a signed-off patch.
crypto/algapi.c +1 -1
@@ -255,7 +255,7 @@ found:continue ;if (strcmp (alg->cra_driver_name, q->cra_driver_name) && - q->cra_priority > alg->cra_priority) + q->cra_priority < alg->cra_priority)continue ;crypto_remove_spawns (&q->cra_users, &list, alg->cra_flags);
Herbert Xu
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 6 lines · Steffen Klassert
As it is, I can instantiate pcrypt if the priority of pcrypt is lower than the priority of the underlying algorithm. If I do the priority check in
crypto_alg_tested()the other way arround, I get it to work if pcrypt has a higher priority than the underlying algorithm. So I guess we need the patch below, right? If so, I would send a signed-off patch.
Can you give me an example with actual numbers and what you expect to happen?
Thanks,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtSteffen Klassert
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 11 lines · Herbert Xu
Quoted 6 lines · Steffen Klassert
As it is, I can instantiate pcrypt if the priority of pcrypt is lower than the priority of the underlying algorithm. If I do the priority check in
crypto_alg_tested()the other way arround, I get it to work if pcrypt has a higher priority than the underlying algorithm. So I guess we need the patch below, right? If so, I would send a signed-off patch.Can you give me an example with actual numbers and what you expect to happen?
In pcrypt_alloc_instance() I doinst->alg.cra_priority = alg->cra_priority + 100;
So, in my case authenc has priority 2000 and pcrypt has priority 2100. In this case pcrypt is not instantiated if I use %s for pcrypt as cra_name. If I doinst->alg.cra_priority = alg->cra_priority - 100
it will be instantiated with priority 1900 but it will not be used because the priority of authenc is higher.
So I did the priority check in crypto_alg_tested() the other way around. Then I can instantiate pcrypt with priority 2100 and I can use it.
Herbert Xu
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 11 lines · Steffen Klassert
In
pcrypt_alloc_instance()I doinst->alg.cra_priority=alg->cra_priority+ 100;So, in my case authenc has priority 2000 and pcrypt has priority 2100. In this case pcrypt is not instantiated if I use %s for pcrypt as
cra_name. If I doinst->alg.cra_priority=alg->cra_priority- 100
it will be instantiated with priority 1900 but it will not be used because the priority of authenc is higher.
Quoted 2 lines
So I did the priority check in
crypto_alg_tested()the other way around. Then I can instantiate pcrypt with priority 2100 and I can use it.
Can you send me a pcrypt patch that I can use to reproduce this?
The check modified is meant to replace instances of the same implementation (i.e., you're replaceing aes-x86-64 with a newer version of aes-x86-64). It should never do anything when you add a different implementation of the same algorithm.
So I'm surprised that you're seeing a difference when changing that check. Because unless you're creating two pcrypt objects with the same driver name, or your pcrypt object has the wrong driver name, then this change should make no difference whatsoever.
Cheers,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtSteffen Klassert
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 12 lines · Herbert Xu
Quoted 11 lines · Steffen Klassert
In
pcrypt_alloc_instance()I doinst->alg.cra_priority=alg->cra_priority+ 100;So, in my case authenc has priority 2000 and pcrypt has priority 2100. In this case pcrypt is not instantiated if I use %s for pcrypt as
cra_name. If I doinst->alg.cra_priority=alg->cra_priority- 100
it will be instantiated with priority 1900 but it will not be used because the priority of authenc is higher.
Quoted 4 lines
Quoted 2 lines
So I did the priority check in
crypto_alg_tested()the other way around. Then I can instantiate pcrypt with priority 2100 and I can use it.Can you send me a pcrypt patch that I can use to reproduce this?
Yes, I will send the full patchset including the tcrypt changes to instantiate pcrypt.
As the patchset is, I'm not able to instantiate pcrypt here. I need to either change the priority check in crypto_alg_tested() or to make pcrypt using a lower priority than authenc.
Quoted 11 lines
The check modified is meant to replace instances of the same implementation (i.e., you're replaceing aes-x86-64 with a newer version of aes-x86-64). It should never do anything when you add a different implementation of the same algorithm.
So I'm surprised that you're seeing a difference when changing that check. Because unless you're creating two pcrypt objects with the same driver name, or your pcrypt object has the wrong driver name, then this change should make no difference whatsoever.
I was just surprised that I was able to instantiate pcrypt if it has a lower priority than the underlying authenc algorithm. So I searched for priority checks like the one in crypto_alg_tested() and in fact changing this check got it to work as I described above.
Herbert Xu
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 3 lines · Steffen Klassert
Yes, I will send the full patchset including the tcrypt changes to instantiate pcrypt.
OK, the patch I just posted to the list should fix the problem.
I was able to test it suing
modprobe tcrypt alg='pcrypt(authenc(hmac(sha1-generic),cbc(aes-generic)))' type=3
Cheers,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtSteffen Klassert
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 7 lines · Herbert Xu
OK, the patch I just posted to the list should fix the problem.
I was able to test it suing
modprobe tcrypt alg='pcrypt(authenc(hmac(sha1-generic),cbc(aes-generic)))' type=3
I applied your patch on top of the last pcrypt patchset, but unfortunately it does not change anything here.
If I do
modprobe tcrypt alg='pcrypt(authenc(hmac(sha1-generic),cbc(aes-generic)))' type=3
it instantiates
authenc(hmac(sha1-generic),cbc(aes-generic))
but not
pcrypt(authenc(hmac(sha1-generic),cbc(aes-generic)))
regardless your patch applied or not.
Herbert Xu
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 9 lines · Steffen Klassert
I applied your patch on top of the last pcrypt patchset, but unfortunately it does not change anything here.
If I do
modprobe tcrypt alg='pcrypt(authenc(hmac(sha1-generic),cbc(aes-generic)))' type=3it instantiates
Quoted 7 lines
authenc(hmac(sha1-generic),cbc(aes-generic))
but not
pcrypt(authenc(hmac(sha1-generic),cbc(aes-generic)))
regardless your patch applied or not.
OK. Can you send me the patches you used against the current cryptodev tree (I only just pushed so give it an hour or so)? I'll see if I can reproduce it here.
Thanks,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtSteffen Klassert
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 5 lines · Herbert Xu
OK. Can you send me the patches you used against the current cryptodev tree (I only just pushed so give it an hour or so)? I'll see if I can reproduce it here.
I'll send the remaining two patches in reply to this mail. The strange thing is that I can instantiate pcrypt if the priority is lower than the priority of authenc, but not if it's equal or higher.
Steffen Klassert
maintainerPATCH 1/2 padata: generic interface for parallel processing
This patch introduces an interface to process data objects in parallel. On request it is possible to serialize again. The parallelized objects return after serialization in the same order as they were before the parallelization.
--- include/linux/interrupt.h | 3 +- include/linux/padata.h | 116 +++++++++++ kernel/Makefile | 2 +- kernel/padata.c | 490 +++++++++++++++++++++++++++++++++++++++++++++ kernel/softirq.c | 2 +- 5 files changed, 610 insertions(+), 3 deletions(-) create mode 100644 include/linux/padata.h create mode 100644 kernel/padata.c
include/linux/interrupt.h +2 -1
@@ -344,7 +344,8 @@ enumTASKLET_SOFTIRQ ,SCHED_SOFTIRQ ,HRTIMER_SOFTIRQ , -RCU_SOFTIRQ ,/* Preferable RCU should always be the last softirq */ +PADATA_SOFTIRQ , +RCU_SOFTIRQ ,/* Preferable RCU should always be the last softirq */ NR_SOFTIRQS };
include/linux/padata.h new file +116 -0
116 lines not on this page · raw message
kernel/Makefile +1 -1
@@ -41,7 +41,7 @@ obj-$(CONFIG_RT_MUTEXES) += rtmutex.o obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o obj-$(CONFIG_RT_MUTEX_TESTER) += rtmutex-tester.o obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o -obj-$(CONFIG_USE_GENERIC_SMP_HELPERS) += smp.o +obj-$(CONFIG_USE_GENERIC_SMP_HELPERS) += smp.o padata.o ifneq ($(CONFIG_SMP),y) obj-y += up.o endif
kernel/padata.c new file +490 -0
490 lines not on this page · raw message
kernel/softirq.c +1 -1
@@ -58,7 +58,7 @@ static DEFINE_PER_CPU(struct task_struct *, ksoftirqd);char *softirq_to_name[NR_SOFTIRQS ] = {"HI" ,"TIMER" ,"NET_TX" ,"NET_RX" ,"BLOCK" , -"TASKLET" ,"SCHED" ,"HRTIMER" ,"RCU" +"TASKLET" ,"SCHED" ,"HRTIMER" ,"PADATA" ,"RCU" };/*
Signature · 1 line
1.5.4.2
Steffen Klassert
maintainerPATCH 2/2 pcrypt: Add pcrypt crypto parallelization wrapper
In reply to Steffen KlassertThis patch adds a parallel crypto template that takes a crypto algorithm and converts it to process the crypto transforms in parallel. For the moment only aead is supported.
--- crypto/Kconfig | 13 ++ crypto/Makefile | 2 + crypto/pcrypt.c | 411 +++++++++++++++++++++++++++++++++++++++++++++ crypto/pcrypt_core.c | 106 ++++++++++++ include/crypto/pcrypt.h | 51 ++++++ include/linux/interrupt.h | 2 + 6 files changed, 585 insertions(+), 0 deletions(-) create mode 100644 crypto/pcrypt.c create mode 100644 crypto/pcrypt_core.c create mode 100644 include/crypto/pcrypt.h
crypto/Kconfig +13 -0
@@ -113,6 +113,19 @@ config CRYPTO_NULL help These are 'Null' algorithms, used by IPsec, which do nothing. +config CRYPTO_PCRYPT_CORE + bool + +config CRYPTO_PCRYPT + tristate "Parallel crypto engine (EXPERIMENTAL)" + depends on USE_GENERIC_SMP_HELPERS && EXPERIMENTAL + select CRYPTO_MANAGER + select CRYPTO_PCRYPT_CORE + select CRYPTO_AEAD + help + This converts an arbitrary crypto algorithm into a parallel + algorithm that is executed in a softirq. + config CRYPTO_WORKQUEUE tristate
crypto/Makefile +2 -0
@@ -56,6 +56,8 @@ obj-$(CONFIG_CRYPTO_XTS) += xts.o obj-$(CONFIG_CRYPTO_CTR) += ctr.o obj-$(CONFIG_CRYPTO_GCM) += gcm.o obj-$(CONFIG_CRYPTO_CCM) += ccm.o +obj-$(CONFIG_CRYPTO_PCRYPT_CORE) += pcrypt_core.o +obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o obj-$(CONFIG_CRYPTO_DES) += des_generic.o obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o
crypto/pcrypt.c new file +411 -0
411 lines not on this page · raw message
crypto/pcrypt_core.c new file +106 -0
106 lines not on this page · raw message
include/crypto/pcrypt.h new file +51 -0
51 lines not on this page · raw message
include/linux/interrupt.h +2 -0
@@ -344,6 +344,8 @@ enumTASKLET_SOFTIRQ ,SCHED_SOFTIRQ ,HRTIMER_SOFTIRQ , +AEAD_ENC_SOFTIRQ , +AEAD_DEC_SOFTIRQ ,PADATA_SOFTIRQ , RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
Signature · 1 line
1.5.4.2
Steffen Klassert
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
In reply to Steffen KlassertQuoted 10 lines · Steffen Klassert
Quoted 5 lines · Herbert Xu
OK. Can you send me the patches you used against the current cryptodev tree (I only just pushed so give it an hour or so)? I'll see if I can reproduce it here.
I'll send the remaining two patches in reply to this mail. The strange thing is that I can instantiate pcrypt if the priority is lower than the priority of authenc, but not if it's equal or higher.
Any ideas why it's not possible to instantiate pcrypt?
In between I updated padata to use the dynamic percpu allocator, so the instantiating of pcrypt is the last issue I know of for the moment.
Herbert Xu
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 2 lines · Steffen Klassert
Any ideas why it's not possible to instantiate pcrypt?
Sorry for the late response.
In fact it was being instantiated, it was just getting killed immediately after completing its self-test :)
Please let me know if this fixes it for you.
commit 2bf2901669a564b402cd0e40eb3f941c391e64c4
Author: Herbert Xu <[email protected]> Date: Mon Aug 31 15:56:54 2009 +1000
crypto: api - Do not displace newly registered algorithms
We have a mechanism where newly registered algorithms of a higher priority can displace existing instances that use a different implementation of the same algorithm with a lower priority.
Unfortunately the same mechanism can cause a newly registered algorithm to displace itself if it depends on an existing version of the same algorithm.
This patch fixes this by keeping all algorithms that the newly reigstered algorithm depends on, thus protecting them from being removed.
crypto/algapi.c +63 -14
@@ -81,16 +81,35 @@ static void crypto_destroy_instance(struct crypto_alg *alg)crypto_tmpl_put (tmpl); } +static struct list_head *crypto_more_spawns (struct crypto_alg *alg, +struct list_head *stack, +struct list_head *top, +struct list_head *secondary_spawns) +{ +struct crypto_spawn *spawn, *n; + +if (list_empty (stack)) +return NULL ; + + spawn = list_first_entry(stack, struct crypto_spawn, list); + n = list_entry(spawn->list.next, struct crypto_spawn, list); + +if (spawn->alg && &n->list != stack && !n->alg) + n->alg = (n->list.next == stack) ? alg : + &list_entry(n->list.next, struct crypto_spawn, + list)->inst->alg; + +list_move (&spawn->list, secondary_spawns); + +return &n->list == stack ? top : &n->inst->alg.cra_users; +} +static void crypto_remove_spawn (struct crypto_spawn *spawn, -struct list_head *list, -struct list_head *secondary_spawns) +struct list_head *list) {struct crypto_instance *inst = spawn->inst;struct crypto_template *tmpl = inst->tmpl; -list_del_init (&spawn->list); - spawn->alg =NULL ; -if (crypto_is_dead (&inst->alg))return ;
@@ -106,25 +125,55 @@ static void crypto_remove_spawn(struct crypto_spawn *spawn,hlist_del (&inst->list); inst->alg.cra_destroy = crypto_destroy_instance; -list_splice (&inst->alg.cra_users, secondary_spawns); +BUG_ON (!list_empty (&inst->alg.cra_users)); } -static void crypto_remove_spawns (struct list_head *spawns, -struct list_head *list,u32 new_type) +static void crypto_remove_spawns (struct crypto_alg *alg, +struct list_head *list, +struct crypto_alg *nalg) { +u32 new_type = (nalg ?: alg)->cra_flags;struct crypto_spawn *spawn, *n;LIST_HEAD (secondary_spawns); +struct list_head *spawns; +LIST_HEAD (stack); +LIST_HEAD (top); + spawns = &alg->cra_users;list_for_each_entry_safe (spawn, n, spawns, list) {if ((spawn->alg->cra_flags ^ new_type) & spawn->mask)continue ; -crypto_remove_spawn (spawn, list, &secondary_spawns); +list_move (&spawn->list, &top); } -while (!list_empty (&secondary_spawns)) { -list_for_each_entry_safe (spawn, n, &secondary_spawns, list) -crypto_remove_spawn (spawn, list, &secondary_spawns); + spawns = ⊤ +do { +while (!list_empty (spawns)) { +struct crypto_instance *inst; + + spawn = list_first_entry(spawns, struct crypto_spawn, + list); + inst = spawn->inst; + +BUG_ON (&inst->alg == alg); + +list_move (&spawn->list, &stack); + +if (&inst->alg == nalg) +break ; + + spawn->alg =NULL ; + spawns = &inst->alg.cra_users; + } + }while ((spawns =crypto_more_spawns (alg, &stack, &top, + &secondary_spawns))); + +list_for_each_entry_safe (spawn, n, &secondary_spawns, list) { +if (spawn->alg) +list_move (&spawn->list, &spawn->alg->cra_users); +else +crypto_remove_spawn (spawn, list); } }
@@ -258,7 +307,7 @@ found: q->cra_priority > alg->cra_priority)continue ; -crypto_remove_spawns (&q->cra_users, &list, alg->cra_flags); +crypto_remove_spawns (q, &list, alg); } complete:
@@ -330,7 +379,7 @@ static int crypto_remove_alg(struct crypto_alg *alg, struct list_head *list)crypto_notify (CRYPTO_MSG_ALG_UNREGISTER , alg);list_del_init (&alg->cra_list); -crypto_remove_spawns (&alg->cra_users, list, alg->cra_flags); +crypto_remove_spawns (alg, list,NULL );return 0 ; }
Thanks,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtSteffen Klassert
maintainerRe: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface
Quoted 6 lines · Herbert Xu
In fact it was being instantiated, it was just getting killed immediately after completing its self-test :)
Please let me know if this fixes it for you.
Yes, it fixes it. Thanks a lot!
So pcrypt would be ready to use from my point of view. I'll send a next version of pcrypt and padata later.
Steffen Klassert
maintainerRFC PATCH 3/5 pcrypt: Add pcrypt crypto parallelization wrapper
In reply to Steffen KlassertThis patch adds a parallel crypto template that takes a crypto algorithm and converts it to process the crypto transforms in parallel. For the moment only aead is supported.
--- crypto/Kconfig | 13 ++ crypto/Makefile | 2 + crypto/pcrypt.c | 353 +++++++++++++++++++++++++++++++++++++++++++++ crypto/pcrypt_core.c | 106 ++++++++++++++ include/crypto/pcrypt.h | 56 +++++++ include/linux/interrupt.h | 2 + kernel/softirq.c | 3 +- 7 files changed, 534 insertions(+), 1 deletions(-) create mode 100644 crypto/pcrypt.c create mode 100644 crypto/pcrypt_core.c create mode 100644 include/crypto/pcrypt.h
crypto/Kconfig +13 -0
@@ -112,6 +112,19 @@ config CRYPTO_NULL help These are 'Null' algorithms, used by IPsec, which do nothing. +config CRYPTO_PCRYPT_CORE + bool + select CRYPTO_AEAD + +config CRYPTO_PCRYPT + tristate "Parallel crypto wrapper (EXPERIMENTAL)" + depends on USE_GENERIC_SMP_HELPERS && EXPERIMENTAL + select CRYPTO_MANAGER + select CRYPTO_PCRYPT_CORE + help + This converts an arbitrary crypto algorithm into a parallel + algorithm that is executed in a softirq. + config CRYPTO_WORKQUEUE tristate
crypto/Makefile +2 -0
@@ -56,6 +56,8 @@ obj-$(CONFIG_CRYPTO_XTS) += xts.o obj-$(CONFIG_CRYPTO_CTR) += ctr.o obj-$(CONFIG_CRYPTO_GCM) += gcm.o obj-$(CONFIG_CRYPTO_CCM) += ccm.o +obj-$(CONFIG_CRYPTO_PCRYPT_CORE) += pcrypt_core.o +obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o obj-$(CONFIG_CRYPTO_DES) += des_generic.o obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o
crypto/pcrypt.c new file +353 -0
353 lines not on this page · raw message
crypto/pcrypt_core.c new file +106 -0
106 lines not on this page · raw message
include/crypto/pcrypt.h new file +56 -0
56 lines not on this page · raw message
include/linux/interrupt.h +2 -0
@@ -338,6 +338,8 @@ enumTASKLET_SOFTIRQ ,SCHED_SOFTIRQ ,HRTIMER_SOFTIRQ , +AEAD_ENC_SOFTIRQ , +AEAD_DEC_SOFTIRQ ,PADATA_SOFTIRQ , RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
kernel/softirq.c +2 -1
@@ -56,7 +56,8 @@ static DEFINE_PER_CPU(struct task_struct *, ksoftirqd);char *softirq_to_name[NR_SOFTIRQS ] = {"HI" ,"TIMER" ,"NET_TX" ,"NET_RX" ,"BLOCK" , -"TASKLET" ,"SCHED" ,"HRTIMER" ,"PADATA" ,"RCU" +"TASKLET" ,"SCHED" ,"HRTIMER" ,"AEAD_ENC" , +"AEAD_DEC" ,"PADATA" ,"RCU" };/*
Signature · 1 line
1.5.4.2
Steffen Klassert
maintainerRFC PATCH 4/5 eseqiv: Add support for aead algorithms
In reply to Steffen KlassertThis adds eseqiv support for aead algorithms, this is usefull for aead wrappers that need eseqiv as it's default IV generator.
--- crypto/eseqiv.c | 248 +++++++++++++++++++++++++++++++++++++++++++++--- include/linux/crypto.h | 1 + 2 files changed, 235 insertions(+), 14 deletions(-)
crypto/eseqiv.c +234 -14
@@ -15,6 +15,7 @@* */ +#include <crypto/internal/aead.h> #include <crypto/internal/skcipher.h> #include <crypto/rng.h> #include <crypto/scatterwalk.h>
@@ -62,6 +63,29 @@ out:skcipher_givcrypt_complete (req, err); } +static void eseqiv_aead_complete2 (struct aead_givcrypt_request *req) +{ +struct crypto_aead *geniv =aead_givcrypt_reqtfm (req); +struct eseqiv_request_ctx *reqctx =aead_givcrypt_reqctx (req); + +memcpy (req->giv,PTR_ALIGN ((u8 *)reqctx->tail, +crypto_aead_alignmask (geniv) +1 ), +crypto_aead_ivsize (geniv)); +} + +static void eseqiv_aead_complete (struct crypto_async_request *base,int err) +{ +struct aead_givcrypt_request *req = base->data; + +if (err) + goto out; + +eseqiv_aead_complete2 (req); + +out: +aead_givcrypt_complete (req, err); +} +static void eseqiv_chain (struct scatterlist *head,struct scatterlist *sg,int chain) {
@@ -153,7 +177,93 @@ static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req)if (err) goto out; -eseqiv_complete2 (req); +if (giv != req->giv) +eseqiv_complete2 (req); + +out: +return err; +} + +static int eseqiv_aead_givencrypt (struct aead_givcrypt_request *req) +{ +struct crypto_aead *geniv =aead_givcrypt_reqtfm (req); +struct eseqiv_ctx *ctx =crypto_aead_ctx (geniv); +struct eseqiv_request_ctx *reqctx =aead_givcrypt_reqctx (req); +struct aead_request *subreq; +crypto_completion_t complete; +void *data; +struct scatterlist *osrc, *odst; +struct scatterlist *dst; +struct page *srcp; +struct page *dstp; +u8 *giv; +u8 *vsrc; +u8 *vdst; +__be64 seq; +unsigned int ivsize; +unsigned int len; +unsigned int flags; +int err; + + subreq = (void *)(reqctx->tail + ctx->reqoff); +aead_request_set_tfm (subreq,aead_geniv_base (geniv)); + + giv = req->giv; + complete = req->areq.base.complete; + data = req->areq.base.data; + + osrc = req->areq.src; + odst = req->areq.dst; + srcp =sg_page (osrc); + dstp =sg_page (odst); + vsrc =PageHighMem (srcp) ?NULL :page_address (srcp) + osrc->offset; + vdst =PageHighMem (dstp) ?NULL :page_address (dstp) + odst->offset; + + ivsize =crypto_aead_ivsize (geniv); + flags = req->areq.base.flags |CRYPTO_TFM_REQ_SG_HAS_IV ; + +if (vsrc != giv + ivsize && vdst != giv + ivsize) { + giv =PTR_ALIGN ((u8 *)reqctx->tail, +crypto_aead_alignmask (geniv) +1 ); + complete = eseqiv_aead_complete; + data = req; + } + +aead_request_set_callback (subreq, flags, complete, data); + +sg_init_table (reqctx->src,2 ); +sg_set_buf (reqctx->src, giv, ivsize); +eseqiv_chain (reqctx->src, osrc, vsrc == giv + ivsize); + + dst = reqctx->src; +if (osrc != odst) { +sg_init_table (reqctx->dst,2 ); +sg_set_buf (reqctx->dst, giv, ivsize); +eseqiv_chain (reqctx->dst, odst, vdst == giv + ivsize); + + dst = reqctx->dst; + } + +aead_request_set_crypt (subreq, reqctx->src, dst, + req->areq.cryptlen + ivsize, req->areq.iv); +aead_request_set_assoc (subreq, req->areq.assoc, req->areq.assoclen); + +memcpy (req->areq.iv, ctx->salt, ivsize); + + len = ivsize; +if (ivsize >sizeof (u64)) { +memset (req->giv,0 , ivsize -sizeof (u64)); + len =sizeof (u64); + } + seq =cpu_to_be64 (req->seq); +memcpy (req->giv + ivsize - len, &seq, len); + + err =crypto_aead_encrypt (subreq); +if (err) + goto out; + +if (giv != req->giv) +eseqiv_aead_complete2 (req); out:return err;
@@ -182,6 +292,29 @@ unlock:return eseqiv_givencrypt (req); } +static int eseqiv_aead_givencrypt_first (struct aead_givcrypt_request *req) +{ +struct crypto_aead *geniv =aead_givcrypt_reqtfm (req); +struct eseqiv_ctx *ctx =crypto_aead_ctx (geniv); +int err =0 ; + +spin_lock_bh (&ctx->lock); +if (crypto_aead_crt (geniv)->givencrypt != eseqiv_aead_givencrypt_first) + goto unlock; + +crypto_aead_crt (geniv)->givencrypt = eseqiv_aead_givencrypt; + err =crypto_rng_get_bytes (crypto_default_rng, ctx->salt, +crypto_aead_ivsize (geniv)); + +unlock: +spin_unlock_bh (&ctx->lock); + +if (err) +return err; + +return eseqiv_aead_givencrypt (req); +} +static int eseqiv_init (struct crypto_tfm *tfm) {struct crypto_ablkcipher *geniv =__crypto_ablkcipher_cast (tfm);
@@ -214,20 +347,47 @@ static int eseqiv_init(struct crypto_tfm *tfm)return skcipher_geniv_init (tfm); } +static int eseqiv_aead_init (struct crypto_tfm *tfm) +{ +struct crypto_aead *geniv =__crypto_aead_cast (tfm); +struct eseqiv_ctx *ctx =crypto_aead_ctx (geniv); +unsigned long alignmask; +unsigned int reqsize; + +spin_lock_init (&ctx->lock); + + alignmask =crypto_tfm_ctx_alignment () -1 ; + reqsize =sizeof (struct eseqiv_request_ctx ); + +if (alignmask & reqsize) { + alignmask &= reqsize; + alignmask--; + } + + alignmask = ~alignmask; + alignmask &=crypto_aead_alignmask (geniv); + + reqsize += alignmask; + reqsize +=crypto_aead_ivsize (geniv); + reqsize =ALIGN (reqsize,crypto_tfm_ctx_alignment ()); + + ctx->reqoff = reqsize -sizeof (struct eseqiv_request_ctx ); + + tfm->crt_aead.reqsize = reqsize +sizeof (struct aead_request ); + +return aead_geniv_init (tfm); +} +static struct crypto_template eseqiv_tmpl; -static struct crypto_instance *eseqiv_alloc (struct rtattr **tb) +static struct crypto_instance *eseqiv_ablkcipher_alloc (struct rtattr **tb) { -struct crypto_instance *inst;int err; - - err =crypto_get_default_rng (); -if (err) -return ERR_PTR (err); +struct crypto_instance *inst; inst =skcipher_geniv_alloc (&eseqiv_tmpl, tb,0 ,0 );if (IS_ERR (inst)) - goto put_rng; + goto out; err = -EINVAL ;if (inst->alg.cra_ablkcipher.ivsize != inst->alg.cra_blocksize)
@@ -235,18 +395,75 @@ static struct crypto_instance *eseqiv_alloc(struct rtattr **tb) inst->alg.cra_ablkcipher.givencrypt = eseqiv_givencrypt_first; - inst->alg.cra_init = eseqiv_init; - inst->alg.cra_exit = skcipher_geniv_exit; + inst->alg.cra_init = eseqiv_init; + inst->alg.cra_exit = skcipher_geniv_exit; - inst->alg.cra_ctxsize =sizeof (struct eseqiv_ctx ); - inst->alg.cra_ctxsize += inst->alg.cra_ablkcipher.ivsize; + inst->alg.cra_ctxsize = inst->alg.cra_ablkcipher.ivsize; out:return inst; free_inst:skcipher_geniv_free (inst); - inst =ERR_PTR (err); +return ERR_PTR (err); +} + +static struct crypto_instance *eseqiv_aead_alloc (struct rtattr **tb) +{ +int err; +struct crypto_instance *inst; + + inst =aead_geniv_alloc (&eseqiv_tmpl, tb,0 ,0 ); +if (IS_ERR (inst)) + goto out; + + err = -EINVAL ; +if (inst->alg.cra_aead.ivsize != inst->alg.cra_blocksize) + goto free_inst; + + inst->alg.cra_aead.givencrypt = eseqiv_aead_givencrypt_first; + + inst->alg.cra_init = eseqiv_aead_init; + inst->alg.cra_exit = aead_geniv_exit; + + inst->alg.cra_ctxsize = inst->alg.cra_aead.ivsize; + +out: +return inst; + +free_inst: +aead_geniv_free (inst); +return ERR_PTR (err); +} + +static struct crypto_instance *eseqiv_alloc (struct rtattr **tb) +{ +struct crypto_attr_type *algt; +struct crypto_instance *inst; +int err; + + algt =crypto_get_attr_type (tb); + err =PTR_ERR (algt); +if (IS_ERR (algt)) +return ERR_PTR (err); + + err =crypto_get_default_rng (); +if (err) +return ERR_PTR (err); + +if ((algt->type ^CRYPTO_ALG_TYPE_AEAD ) &CRYPTO_ALG_TYPE_MASK ) + inst =eseqiv_ablkcipher_alloc (tb); +else + inst =eseqiv_aead_alloc (tb); + +if (IS_ERR (inst)) + goto put_rng; + + inst->alg.cra_ctxsize +=sizeof (struct eseqiv_ctx ); + +out: +return inst; + put_rng:crypto_put_default_rng (); goto out;
@@ -254,7 +471,10 @@ put_rng:static void eseqiv_free (struct crypto_instance *inst) { -skcipher_geniv_free (inst); +if ((inst->alg.cra_flags ^CRYPTO_ALG_TYPE_AEAD ) &CRYPTO_ALG_TYPE_MASK ) +skcipher_geniv_free (inst); +else +aead_geniv_free (inst);crypto_put_default_rng (); }
include/linux/crypto.h +1 -0
@@ -82,6 +82,7 @@#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100#define CRYPTO_TFM_REQ_MAY_SLEEP 0x00000200#define CRYPTO_TFM_REQ_MAY_BACKLOG 0x00000400 +#define CRYPTO_TFM_REQ_SG_HAS_IV 0x00000800#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000
Signature · 1 line
1.5.4.2
Steffen Klassert
maintainerRFC PATCH 5/5 authenc: Add support for the pcrypt aead wrapper
In reply to Steffen KlassertThis adds support for aead wrapper templates. An aead wrapper can be coosen via a module parameter. For the moment only pcrypt is supported.
--- crypto/authenc.c | 33 +++++++++++++++++++++++++++++++-- 1 files changed, 31 insertions(+), 2 deletions(-)
crypto/authenc.c +31 -2
@@ -13,6 +13,7 @@#include <crypto/aead.h> #include <crypto/internal/hash.h> #include <crypto/internal/skcipher.h> +#include <crypto/internal/aead.h> #include <crypto/authenc.h> #include <crypto/scatterwalk.h> #include <linux/err.h>
@@ -23,6 +24,10 @@#include <linux/slab.h> #include <linux/spinlock.h> +static char *wrapper =NULL ; +module_param (wrapper, charp,0 ); +MODULE_PARM_DESC (wrapper,"Wrapper template for AEAD algorithms" ); +struct authenc_instance_ctx {struct crypto_spawn auth;struct crypto_skcipher_spawn enc;
@@ -157,15 +162,16 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv, dstp =sg_page (dst); vdst =PageHighMem (dstp) ?NULL :page_address (dstp) + dst->offset; + cryptlen = req->cryptlen; -if (ivsize) { +if (ivsize && !(aead_request_flags (req) &CRYPTO_TFM_REQ_SG_HAS_IV )) {sg_init_table (cipher,2 );sg_set_buf (cipher, iv, ivsize);authenc_chain (cipher, dst, vdst == iv + ivsize); dst = cipher; + cryptlen += ivsize; } - cryptlen = req->cryptlen + ivsize; hash =crypto_authenc_hash (req, flags, dst, cryptlen);if (IS_ERR (hash))return PTR_ERR (hash);
@@ -369,6 +375,26 @@ static void crypto_authenc_exit_tfm(struct crypto_tfm *tfm)crypto_free_ablkcipher (ctx->enc); } +static int crypto_authenc_set_wrapper (struct crypto_instance *inst) +{ +int err =0 ; + +if (!wrapper) + goto out; + +if (!strcmp (wrapper,"pcrypt" )) { + inst->alg.cra_type = &crypto_nivaead_type; + inst->alg.cra_aead.geniv ="eseqiv" ; + inst->alg.cra_aead.wrapper ="pcrypt" ; + + goto out; + } + + err = -EINVAL ; +out: +return err; +} +static struct crypto_instance *crypto_authenc_alloc (struct rtattr **tb) {struct crypto_attr_type *algt;
@@ -452,6 +478,9 @@ static struct crypto_instance *crypto_authenc_alloc(struct rtattr **tb) inst->alg.cra_aead.decrypt = crypto_authenc_decrypt; inst->alg.cra_aead.givencrypt = crypto_authenc_givencrypt; +if (crypto_authenc_set_wrapper (inst)) + goto err_drop_enc; + out:crypto_mod_put (auth);return inst;
Signature · 1 line
1.5.4.2