[PATCH 2/4] padata: Allocate cpumask dependend recources in any case

2010-07-20 Thread Steffen Klassert
The cpumask separation work assumes the cpumask dependend recources
present regardless of valid or invalid cpumasks. With this patch
we allocate the cpumask dependend recources in any case. This fixes
two NULL pointer dereference crashes in padata_replace and in
padata_get_cpumask.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 kernel/padata.c |   24 +++-
 1 files changed, 7 insertions(+), 17 deletions(-)

diff --git a/kernel/padata.c b/kernel/padata.c
index 4287868..6a51945 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -417,7 +417,7 @@ static void padata_init_pqueues(struct parallel_data *pd)
}
 
num_cpus = cpumask_weight(pd-cpumask.pcpu);
-   pd-max_seq_nr = (MAX_SEQ_NR / num_cpus) * num_cpus - 1;
+   pd-max_seq_nr = num_cpus ? (MAX_SEQ_NR / num_cpus) * num_cpus - 1 : 0;
 }
 
 /* Allocate and initialize the internal cpumask dependend resources. */
@@ -527,21 +527,19 @@ static void padata_replace(struct padata_instance *pinst,
rcu_assign_pointer(pinst-pd, pd_new);
 
synchronize_rcu();
-   if (!pd_old)
-   goto out;
 
-   padata_flush_queues(pd_old);
if (!cpumask_equal(pd_old-cpumask.pcpu, pd_new-cpumask.pcpu))
notification_mask |= PADATA_CPU_PARALLEL;
if (!cpumask_equal(pd_old-cpumask.cbcpu, pd_new-cpumask.cbcpu))
notification_mask |= PADATA_CPU_SERIAL;
 
+   padata_flush_queues(pd_old);
padata_free_pd(pd_old);
+
if (notification_mask)
blocking_notifier_call_chain(pinst-cpumask_change_notifier,
 notification_mask, pinst);
 
-out:
pinst-flags = ~PADATA_RESET;
 }
 
@@ -673,6 +671,7 @@ int __padata_set_cpumasks(struct padata_instance *pinst,
struct parallel_data *pd = NULL;
 
mutex_lock(pinst-lock);
+   get_online_cpus();
 
valid = padata_validate_cpumask(pinst, pcpumask);
if (!valid) {
@@ -681,20 +680,16 @@ int __padata_set_cpumasks(struct padata_instance *pinst,
}
 
valid = padata_validate_cpumask(pinst, cbcpumask);
-   if (!valid) {
+   if (!valid)
__padata_stop(pinst);
-   goto out_replace;
-   }
-
-   get_online_cpus();
 
+out_replace:
pd = padata_alloc_pd(pinst, pcpumask, cbcpumask);
if (!pd) {
err = -ENOMEM;
goto out;
}
 
-out_replace:
cpumask_copy(pinst-cpumask.pcpu, pcpumask);
cpumask_copy(pinst-cpumask.cbcpu, cbcpumask);
 
@@ -705,7 +700,6 @@ out_replace:
 
 out:
put_online_cpus();
-
mutex_unlock(pinst-lock);
 
return err;
@@ -776,11 +770,8 @@ static int __padata_remove_cpu(struct padata_instance 
*pinst, int cpu)
if (cpumask_test_cpu(cpu, cpu_online_mask)) {
 
if (!padata_validate_cpumask(pinst, pinst-cpumask.pcpu) ||
-   !padata_validate_cpumask(pinst, pinst-cpumask.cbcpu)) {
+   !padata_validate_cpumask(pinst, pinst-cpumask.cbcpu))
__padata_stop(pinst);
-   padata_replace(pinst, pd);
-   goto out;
-   }
 
pd = padata_alloc_pd(pinst, pinst-cpumask.pcpu,
 pinst-cpumask.cbcpu);
@@ -790,7 +781,6 @@ static int __padata_remove_cpu(struct padata_instance 
*pinst, int cpu)
padata_replace(pinst, pd);
}
 
-out:
return 0;
 }
 
-- 
1.5.6.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/4] padata: Check for valid cpumasks

2010-07-20 Thread Steffen Klassert
Now that we allow to change the cpumasks from userspace, we have
to check for valid cpumasks in padata_do_parallel. This patch adds
the necessary check. This fixes a division by zero crash if the
parallel cpumask contains no active cpu.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 kernel/padata.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/kernel/padata.c b/kernel/padata.c
index 6a51945..7f895e2 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -114,7 +114,7 @@ int padata_do_parallel(struct padata_instance *pinst,
pd = rcu_dereference(pinst-pd);
 
err = -EINVAL;
-   if (!(pinst-flags  PADATA_INIT))
+   if (!(pinst-flags  PADATA_INIT) || pinst-flags  PADATA_INVALID)
goto out;
 
if (!cpumask_test_cpu(cb_cpu, pd-cpumask.cbcpu))
-- 
1.5.6.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/4] crypto: pcrypt - Dont calulate a callback cpu on empty callback cpumask

2010-07-20 Thread Steffen Klassert
If the callback cpumask is empty, we crash with a division by zero
when we try to calculate a callback cpu. So we don't update the callback
cpu in pcrypt_do_parallel if the callback cpumask is empty.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/pcrypt.c |3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
index 7153a50..794c172 100644
--- a/crypto/pcrypt.c
+++ b/crypto/pcrypt.c
@@ -82,6 +82,9 @@ static int pcrypt_do_parallel(struct padata_priv *padata, 
unsigned int *cb_cpu,
if (cpumask_test_cpu(cpu, cpumask-mask))
goto out;
 
+   if (!cpumask_weight(cpumask-mask))
+   goto out;
+
cpu_index = cpu % cpumask_weight(cpumask-mask);
 
cpu = cpumask_first(cpumask-mask);
-- 
1.5.6.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 0/3] padata: cpumasks

2010-07-19 Thread Steffen Klassert
On Mon, Jul 19, 2010 at 02:04:26PM +0800, Herbert Xu wrote:
 
 All applied.  Thanks!

Hm, I was just about to write some comments on these patches,
they still have some issues. For example, handling empty cpumasks
is broken again (NULL pointer dereference in padata_replace).
The cpu_index is zero for all cpus now, so can we leak objects
on cpu hotplug etc. Also I'm not that happy with some of the
API changes. I'll try to fix this up with some patches.

Steffen
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/6] padata: updates

2010-07-07 Thread Steffen Klassert
This patchset contains the following changes:

1. Add a flag to mark the padata instance as invalid.
We will use this to mark the padata instace as invalid
if the padata cpumask contains no active cpu.

2. Make padata_stop to block until the padata instance is
unused. So it's save to change the cpumask after a call to
padata_stop.

3. Add a possibility to handle empty padata cpumasks.
The first three patches address a bug, found by Dan Kruchinin.
When the padata cpumask does not intersect with the active
cpumask we get a division by zero in padata_alloc_pd and we
end up with a useless padata instance. It's not possible to
trigger this bug by now, but Dan has patches that let the
cpumask change from userspace. So this bug has to be fixed
before these patches can go in.

4. Make padata_do_parallel to return zero on success.
To return -EINPROGRESS on success was considered to be odd,
so we change the API to return zero instead. Users are updated
accordingly.

5. Simplify the serialization mechanism.
As it is, we go through all the percpu reorder queues to calculate
the sequence number of the next object that needs serialization. 
This patch avoids this and minimalizes the accesses of foreign
memory. This gives some performance inprovements, in particular
on machines with many cpus.

6. Update the padata documentation.

Steffen

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/6] padata: Check for valid padata instance on start

2010-07-07 Thread Steffen Klassert
This patch introduces the PADATA_INVALID flag which is
checked on padata start. This will be used to mark a padata
instance as invalid, if the padata cpumask does not intersect
with the active cpumask. we change padata_start to return an
error if the PADATA_INVALID is set. Also we adapt the only
padata user, pcrypt to this change.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/pcrypt.c|   19 ++-
 include/linux/padata.h |3 ++-
 kernel/padata.c|   18 --
 3 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
index 247178c..71ae2b2 100644
--- a/crypto/pcrypt.c
+++ b/crypto/pcrypt.c
@@ -385,6 +385,7 @@ static struct crypto_template pcrypt_tmpl = {
 
 static int __init pcrypt_init(void)
 {
+   int err = -ENOMEM;
encwq = create_workqueue(pencrypt);
if (!encwq)
goto err;
@@ -400,14 +401,22 @@ static int __init pcrypt_init(void)
 
pcrypt_dec_padata = padata_alloc(cpu_possible_mask, decwq);
if (!pcrypt_dec_padata)
-   goto err_free_padata;
+   goto err_free_enc_padata;
 
-   padata_start(pcrypt_enc_padata);
-   padata_start(pcrypt_dec_padata);
+   err = padata_start(pcrypt_enc_padata);
+   if (err)
+   goto err_free_dec_padata;
+
+   err = padata_start(pcrypt_dec_padata);
+   if (err)
+   goto err_free_dec_padata;
 
return crypto_register_template(pcrypt_tmpl);
 
-err_free_padata:
+err_free_dec_padata:
+   padata_free(pcrypt_dec_padata);
+
+err_free_enc_padata:
padata_free(pcrypt_enc_padata);
 
 err_destroy_decwq:
@@ -417,7 +426,7 @@ err_destroy_encwq:
destroy_workqueue(encwq);
 
 err:
-   return -ENOMEM;
+   return err;
 }
 
 static void __exit pcrypt_exit(void)
diff --git a/include/linux/padata.h b/include/linux/padata.h
index 8d84062..e4c17f9 100644
--- a/include/linux/padata.h
+++ b/include/linux/padata.h
@@ -126,6 +126,7 @@ struct padata_instance {
u8  flags;
 #definePADATA_INIT 1
 #definePADATA_RESET2
+#definePADATA_INVALID  4
 };
 
 extern struct padata_instance *padata_alloc(const struct cpumask *cpumask,
@@ -138,6 +139,6 @@ extern int padata_set_cpumask(struct padata_instance *pinst,
  cpumask_var_t cpumask);
 extern int padata_add_cpu(struct padata_instance *pinst, int cpu);
 extern int padata_remove_cpu(struct padata_instance *pinst, int cpu);
-extern void padata_start(struct padata_instance *pinst);
+extern int padata_start(struct padata_instance *pinst);
 extern void padata_stop(struct padata_instance *pinst);
 #endif
diff --git a/kernel/padata.c b/kernel/padata.c
index ff8de1b..e7d723a 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -485,6 +485,11 @@ static void padata_flush_queues(struct parallel_data *pd)
BUG_ON(atomic_read(pd-refcnt) != 0);
 }
 
+static void __padata_start(struct padata_instance *pinst)
+{
+   pinst-flags |= PADATA_INIT;
+}
+
 /* Replace the internal control stucture with a new one. */
 static void padata_replace(struct padata_instance *pinst,
   struct parallel_data *pd_new)
@@ -619,11 +624,20 @@ EXPORT_SYMBOL(padata_remove_cpu);
  *
  * @pinst: padata instance to start
  */
-void padata_start(struct padata_instance *pinst)
+int padata_start(struct padata_instance *pinst)
 {
+   int err = 0;
+
mutex_lock(pinst-lock);
-   pinst-flags |= PADATA_INIT;
+
+   if (pinst-flags  PADATA_INVALID)
+   err =-EINVAL;
+
+__padata_start(pinst);
+
mutex_unlock(pinst-lock);
+
+   return err;
 }
 EXPORT_SYMBOL(padata_start);
 
-- 
1.5.6.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/6] padata: Block until the instance is unused on stop

2010-07-07 Thread Steffen Klassert
This patch makes padata_stop to block until the padata
instance is unused. Also we split padata_stop to a locked
and a unlocked version. This is in preparation to be able
to change the cpumask after a call to patata stop.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 kernel/padata.c |   24 
 1 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/kernel/padata.c b/kernel/padata.c
index e7d723a..9e18dfa 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -490,6 +490,20 @@ static void __padata_start(struct padata_instance *pinst)
pinst-flags |= PADATA_INIT;
 }
 
+static void __padata_stop(struct padata_instance *pinst)
+{
+   if (!(pinst-flags  PADATA_INIT))
+   return;
+
+   pinst-flags = ~PADATA_INIT;
+
+   synchronize_rcu();
+
+   get_online_cpus();
+   padata_flush_queues(pinst-pd);
+   put_online_cpus();
+}
+
 /* Replace the internal control stucture with a new one. */
 static void padata_replace(struct padata_instance *pinst,
   struct parallel_data *pd_new)
@@ -649,7 +663,7 @@ EXPORT_SYMBOL(padata_start);
 void padata_stop(struct padata_instance *pinst)
 {
mutex_lock(pinst-lock);
-   pinst-flags = ~PADATA_INIT;
+   __padata_stop(pinst);
mutex_unlock(pinst-lock);
 }
 EXPORT_SYMBOL(padata_stop);
@@ -770,17 +784,11 @@ EXPORT_SYMBOL(padata_alloc);
  */
 void padata_free(struct padata_instance *pinst)
 {
-   padata_stop(pinst);
-
-   synchronize_rcu();
-
 #ifdef CONFIG_HOTPLUG_CPU
unregister_hotcpu_notifier(pinst-cpu_notifier);
 #endif
-   get_online_cpus();
-   padata_flush_queues(pinst-pd);
-   put_online_cpus();
 
+   padata_stop(pinst);
padata_free_pd(pinst-pd);
free_cpumask_var(pinst-cpumask);
kfree(pinst);
-- 
1.5.6.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/6] padata: make padata_do_parallel to return zero on success

2010-07-07 Thread Steffen Klassert
To return -EINPROGRESS on success in padata_do_parallel was
considered to be odd. This patch changes this to return zero
on success. Also the only user of padata, pcrypt is adapted to
convert a return of zero to -EINPROGRESS within the crypto layer.
This also removes the pcrypt fallback if padata_do_parallel
was called on a not running padata instance as we can't handle it
anymore. This fallback was unused, so it's save to remove it.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/pcrypt.c |   18 ++
 kernel/padata.c |   11 +--
 2 files changed, 11 insertions(+), 18 deletions(-)

diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
index 71ae2b2..6036b6d 100644
--- a/crypto/pcrypt.c
+++ b/crypto/pcrypt.c
@@ -143,10 +143,8 @@ static int pcrypt_aead_encrypt(struct aead_request *req)
aead_request_set_assoc(creq, req-assoc, req-assoclen);
 
err = pcrypt_do_parallel(padata, ctx-cb_cpu, pcrypt_enc_padata);
-   if (err)
-   return err;
-   else
-   err = crypto_aead_encrypt(creq);
+   if (!err)
+   return -EINPROGRESS;
 
return err;
 }
@@ -187,10 +185,8 @@ static int pcrypt_aead_decrypt(struct aead_request *req)
aead_request_set_assoc(creq, req-assoc, req-assoclen);
 
err = pcrypt_do_parallel(padata, ctx-cb_cpu, pcrypt_dec_padata);
-   if (err)
-   return err;
-   else
-   err = crypto_aead_decrypt(creq);
+   if (!err)
+   return -EINPROGRESS;
 
return err;
 }
@@ -233,10 +229,8 @@ static int pcrypt_aead_givencrypt(struct 
aead_givcrypt_request *req)
aead_givcrypt_set_giv(creq, req-giv, req-seq);
 
err = pcrypt_do_parallel(padata, ctx-cb_cpu, pcrypt_enc_padata);
-   if (err)
-   return err;
-   else
-   err = crypto_aead_givencrypt(creq);
+   if (!err)
+   return -EINPROGRESS;
 
return err;
 }
diff --git a/kernel/padata.c b/kernel/padata.c
index 57ec4eb..ae8defc 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -111,10 +111,13 @@ int padata_do_parallel(struct padata_instance *pinst,
 
pd = rcu_dereference(pinst-pd);
 
-   err = 0;
+   err = -EINVAL;
if (!(pinst-flags  PADATA_INIT))
goto out;
 
+   if (!cpumask_test_cpu(cb_cpu, pd-cpumask))
+   goto out;
+
err =  -EBUSY;
if ((pinst-flags  PADATA_RESET))
goto out;
@@ -122,11 +125,7 @@ int padata_do_parallel(struct padata_instance *pinst,
if (atomic_read(pd-refcnt) = MAX_OBJ_NUM)
goto out;
 
-   err = -EINVAL;
-   if (!cpumask_test_cpu(cb_cpu, pd-cpumask))
-   goto out;
-
-   err = -EINPROGRESS;
+   err = 0;
atomic_inc(pd-refcnt);
padata-pd = pd;
padata-cb_cpu = cb_cpu;
-- 
1.5.6.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/6] padata: simplify serialization mechanism

2010-07-07 Thread Steffen Klassert
We count the number of processed objects on a percpu basis,
so we need to go through all the percpu reorder queues to calculate
the sequence number of the next object that needs serialization.
This patch changes this to count the number of processed objects
global. So we can calculate the sequence number and the percpu
reorder queue of the next object that needs serialization without
searching through the percpu reorder queues. This avoids some
accesses to memory of foreign cpus.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 include/linux/padata.h |6 ++--
 kernel/padata.c|   71 +---
 2 files changed, 22 insertions(+), 55 deletions(-)

diff --git a/include/linux/padata.h b/include/linux/padata.h
index e4c17f9..8844b85 100644
--- a/include/linux/padata.h
+++ b/include/linux/padata.h
@@ -67,7 +67,6 @@ struct padata_list {
  * @pwork: work struct for parallelization.
  * @swork: work struct for serialization.
  * @pd: Backpointer to the internal control structure.
- * @num_obj: Number of objects that are processed by this cpu.
  * @cpu_index: Index of the cpu.
  */
 struct padata_queue {
@@ -77,7 +76,6 @@ struct padata_queue {
struct work_struct  pwork;
struct work_struct  swork;
struct parallel_data*pd;
-   atomic_tnum_obj;
int cpu_index;
 };
 
@@ -93,6 +91,7 @@ struct padata_queue {
  * @max_seq_nr:  Maximal used sequence number.
  * @cpumask: cpumask in use.
  * @lock: Reorder lock.
+ * @processed: Number of already processed objects.
  * @timer: Reorder timer.
  */
 struct parallel_data {
@@ -103,7 +102,8 @@ struct parallel_data {
atomic_trefcnt;
unsigned intmax_seq_nr;
cpumask_var_t   cpumask;
-   spinlock_t  lock;
+   spinlock_t  lock cacheline_aligned;
+   unsigned intprocessed;
struct timer_list   timer;
 };
 
diff --git a/kernel/padata.c b/kernel/padata.c
index ae8defc..450d67d 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -170,79 +170,47 @@ EXPORT_SYMBOL(padata_do_parallel);
  */
 static struct padata_priv *padata_get_next(struct parallel_data *pd)
 {
-   int cpu, num_cpus, empty, calc_seq_nr;
-   int seq_nr, next_nr, overrun, next_overrun;
+   int cpu, num_cpus;
+   int next_nr, next_index;
struct padata_queue *queue, *next_queue;
struct padata_priv *padata;
struct padata_list *reorder;
 
-   empty = 0;
-   next_nr = -1;
-   next_overrun = 0;
-   next_queue = NULL;
-
num_cpus = cpumask_weight(pd-cpumask);
 
-   for_each_cpu(cpu, pd-cpumask) {
-   queue = per_cpu_ptr(pd-queue, cpu);
-   reorder = queue-reorder;
-
-   /*
-* Calculate the seq_nr of the object that should be
-* next in this reorder queue.
-*/
-   overrun = 0;
-   calc_seq_nr = (atomic_read(queue-num_obj) * num_cpus)
-  + queue-cpu_index;
-
-   if (unlikely(calc_seq_nr  pd-max_seq_nr)) {
-   calc_seq_nr = calc_seq_nr - pd-max_seq_nr - 1;
-   overrun = 1;
-   }
-
-   if (!list_empty(reorder-list)) {
-   padata = list_entry(reorder-list.next,
-   struct padata_priv, list);
-
-   seq_nr  = padata-seq_nr;
-   BUG_ON(calc_seq_nr != seq_nr);
-   } else {
-   seq_nr = calc_seq_nr;
-   empty++;
-   }
-
-   if (next_nr  0 || seq_nr  next_nr
-   || (next_overrun  !overrun)) {
-   next_nr = seq_nr;
-   next_overrun = overrun;
-   next_queue = queue;
-   }
+   /*
+* Calculate the percpu reorder queue and the sequence
+* number of the next object.
+*/
+   next_nr = pd-processed;
+   next_index = next_nr % num_cpus;
+   cpu = padata_index_to_cpu(pd, next_index);
+   next_queue = per_cpu_ptr(pd-queue, cpu);
+
+   if (unlikely(next_nr  pd-max_seq_nr)) {
+   next_nr = next_nr - pd-max_seq_nr - 1;
+   next_index = next_nr % num_cpus;
+   cpu = padata_index_to_cpu(pd, next_index);
+   next_queue = per_cpu_ptr(pd-queue, cpu);
+   pd-processed = 0;
}
 
padata = NULL;
 
-   if (empty == num_cpus)
-   goto out;
-
reorder = next_queue-reorder;
 
if (!list_empty(reorder-list)) {
padata = list_entry(reorder-list.next,
struct padata_priv, list);
 
-   if (unlikely(next_overrun)) {
-   for_each_cpu(cpu, pd

[PATCH 6/6] padata: update documentation

2010-07-07 Thread Steffen Klassert
This patch updates the padata documentation to the changed
API of padata_start/padata_stop and padata_do parallel.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 Documentation/padata.txt |   21 +++--
 1 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/Documentation/padata.txt b/Documentation/padata.txt
index 269d7d0..3d77d09 100644
--- a/Documentation/padata.txt
+++ b/Documentation/padata.txt
@@ -22,12 +22,15 @@ actually be done; it should be a multithreaded queue, 
naturally.
 
 There are functions for enabling and disabling the instance:
 
-void padata_start(struct padata_instance *pinst);
+int padata_start(struct padata_instance *pinst);
 void padata_stop(struct padata_instance *pinst);
 
-These functions literally do nothing beyond setting or clearing the
-padata_start() was called flag; if that flag is not set, other functions
-will refuse to work.
+These functions are setting or clearing the PADATA_INIT flag;
+if that flag is not set, other functions will refuse to work.
+padata_start returns zero on success (flag set) or -EINVAL if the
+padata cpumask contains no active cpu (flag not set).
+padata_stop clears the flag and blocks until the padata instance
+is unused. 
 
 The list of CPUs to be used can be adjusted with these functions:
 
@@ -63,12 +66,10 @@ The submission of work is done with:
 The pinst and padata structures must be set up as described above; cb_cpu
 specifies which CPU will be used for the final callback when the work is
 done; it must be in the current instance's CPU mask.  The return value from
-padata_do_parallel() is a little strange; zero is an error return
-indicating that the caller forgot the padata_start() formalities.  -EBUSY
-means that somebody, somewhere else is messing with the instance's CPU
-mask, while -EINVAL is a complaint about cb_cpu not being in that CPU mask.
-If all goes well, this function will return -EINPROGRESS, indicating that
-the work is in progress.
+padata_do_parallel() is zero on success, indicating that the work is in
+progress. -EBUSY means that somebody, somewhere else is messing with the
+instance's CPU mask, while -EINVAL is a complaint about cb_cpu not being
+in that CPU mask or about a not running instance.
 
 Each task submitted to padata_do_parallel() will, in turn, be passed to
 exactly one call to the above-mentioned parallel() function, on one CPU, so
-- 
1.5.6.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/4] padata: Add some code comments

2010-05-17 Thread Steffen Klassert
Hi Randy,

On Fri, May 14, 2010 at 09:18:57AM -0700, Randy Dunlap wrote:
 
 Hi Steffen,
 
 These comments are roughly 90% of the way to being kernel-doc notation,
 so how about going the rest of the way, please?
 

yes of course we can. I read Documentation/kernel-doc-nano-HOWTO.txt,
so I need to use /** for all comments that I want to add to kernel-doc.
Anything else to do?

 
 Use:
 /**
 in multiple places.
 

I wondered several times why some comments start with /** while
others start with /*. Anyway, I did not pay too much attention
to this, because it was just the beginning line of a comment.
Now I know the difference :)


 /**
 
  + * padata_get_next - Get the next object that needs serialization.
 

This one is a static function, I would not mind to add it to kernel-doc
too, but that's probaply not needed.

I'll resend this one with the suggested changes,
thanks for pointing this out.

Steffen
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/4 v2] padata: Add some code comments

2010-05-17 Thread Steffen Klassert

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 include/linux/padata.h |   53 +
 kernel/padata.c|   68 
 2 files changed, 110 insertions(+), 11 deletions(-)

diff --git a/include/linux/padata.h b/include/linux/padata.h
index 64836a6..8d84062 100644
--- a/include/linux/padata.h
+++ b/include/linux/padata.h
@@ -26,6 +26,17 @@
 #include linux/list.h
 #include linux/timer.h
 
+/**
+ * struct padata_priv -  Embedded to the users data structure.
+ *
+ * @list: List entry, to attach to the padata lists.
+ * @pd: Pointer to the internal control structure.
+ * @cb_cpu: Callback cpu for serializatioon.
+ * @seq_nr: Sequence number of the parallelized data object.
+ * @info: Used to pass information from the parallel to the serial function.
+ * @parallel: Parallel execution function.
+ * @serial: Serial complete function.
+ */
 struct padata_priv {
struct list_headlist;
struct parallel_data*pd;
@@ -36,11 +47,29 @@ struct padata_priv {
void(*serial)(struct padata_priv *padata);
 };
 
+/**
+ * struct padata_list
+ *
+ * @list: List head.
+ * @lock: List lock.
+ */
 struct padata_list {
struct list_headlist;
spinlock_t  lock;
 };
 
+/**
+ * struct padata_queue - The percpu padata queues.
+ *
+ * @parallel: List to wait for parallelization.
+ * @reorder: List to wait for reordering after parallel processing.
+ * @serial: List to wait for serialization after reordering.
+ * @pwork: work struct for parallelization.
+ * @swork: work struct for serialization.
+ * @pd: Backpointer to the internal control structure.
+ * @num_obj: Number of objects that are processed by this cpu.
+ * @cpu_index: Index of the cpu.
+ */
 struct padata_queue {
struct padata_list  parallel;
struct padata_list  reorder;
@@ -52,6 +81,20 @@ struct padata_queue {
int cpu_index;
 };
 
+/**
+ * struct parallel_data - Internal control structure, covers everything
+ * that depends on the cpumask in use.
+ *
+ * @pinst: padata instance.
+ * @queue: percpu padata queues.
+ * @seq_nr: The sequence number that will be attached to the next object.
+ * @reorder_objects: Number of objects waiting in the reorder queues.
+ * @refcnt: Number of objects holding a reference on this parallel_data.
+ * @max_seq_nr:  Maximal used sequence number.
+ * @cpumask: cpumask in use.
+ * @lock: Reorder lock.
+ * @timer: Reorder timer.
+ */
 struct parallel_data {
struct padata_instance  *pinst;
struct padata_queue *queue;
@@ -64,6 +107,16 @@ struct parallel_data {
struct timer_list   timer;
 };
 
+/**
+ * struct padata_instance - The overall control structure.
+ *
+ * @cpu_notifier: cpu hotplug notifier.
+ * @wq: The workqueue in use.
+ * @pd: The internal control structure.
+ * @cpumask: User supplied cpumask.
+ * @lock: padata instance lock.
+ * @flags: padata flags.
+ */
 struct padata_instance {
struct notifier_block   cpu_notifier;
struct workqueue_struct *wq;
diff --git a/kernel/padata.c b/kernel/padata.c
index ec6b8b7..ca89dfb 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -88,7 +88,7 @@ static void padata_parallel_worker(struct work_struct *work)
local_bh_enable();
 }
 
-/*
+/**
  * padata_do_parallel - padata parallelization function
  *
  * @pinst: padata instance
@@ -152,6 +152,23 @@ out:
 }
 EXPORT_SYMBOL(padata_do_parallel);
 
+/*
+ * padata_get_next - Get the next object that needs serialization.
+ *
+ * Return values are:
+ *
+ * A pointer to the control struct of the next object that needs
+ * serialization, if present in one of the percpu reorder queues.
+ *
+ * NULL, if all percpu reorder queues are empty.
+ *
+ * -EINPROGRESS, if the next object that needs serialization will
+ *  be parallel processed by another cpu and is not yet present in
+ *  the cpu's reorder queue.
+ *
+ * -ENODATA, if this cpu has to do the parallel processing for
+ *  the next object.
+ */
 static struct padata_priv *padata_get_next(struct parallel_data *pd)
 {
int cpu, num_cpus, empty, calc_seq_nr;
@@ -173,7 +190,7 @@ static struct padata_priv *padata_get_next(struct 
parallel_data *pd)
 
/*
 * Calculate the seq_nr of the object that should be
-* next in this queue.
+* next in this reorder queue.
 */
overrun = 0;
calc_seq_nr = (atomic_read(queue-num_obj) * num_cpus)
@@ -248,15 +265,36 @@ static void padata_reorder(struct parallel_data *pd)
struct padata_queue *queue;
struct padata_instance *pinst = pd-pinst;
 
+   /*
+* We need to ensure that only one cpu can work on dequeueing of
+* the reorder queue the time. Calculating in which percpu reorder
+* queue the next object will arrive takes some time. A spinlock

[PATCH 1/4] padata: Use a timer to handle remaining objects in the reorder queues

2010-05-14 Thread Steffen Klassert
padata_get_next needs to check whether the next object that
need serialization must be parallel processed by the local cpu.
This check was wrong implemented and returned always true,
so the try_again loop in padata_reorder was never taken. This
can lead to object leaks in some rare cases due to a race that
appears with the trylock in padata_reorder. The try_again loop
was not a good idea after all, because a cpu could take that
loop frequently, so we handle this with a timer instead.

This patch adds a timer to handle the race that appears with
the trylock. If cpu1 queues an object to the reorder queue while
cpu2 holds the pd-lock but left the while loop in padata_reorder
already, cpu2 can't care for this object and cpu1 exits because
it can't get the lock. Usually the next cpu that takes the lock
cares for this object too. We need the timer just if this object
was the last one that arrives to the reorder queues. The timer
function sends it out in this case.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 include/linux/padata.h |2 ++
 kernel/padata.c|   25 ++---
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/include/linux/padata.h b/include/linux/padata.h
index 51611da..64836a6 100644
--- a/include/linux/padata.h
+++ b/include/linux/padata.h
@@ -24,6 +24,7 @@
 #include linux/workqueue.h
 #include linux/spinlock.h
 #include linux/list.h
+#include linux/timer.h
 
 struct padata_priv {
struct list_headlist;
@@ -60,6 +61,7 @@ struct parallel_data {
unsigned intmax_seq_nr;
cpumask_var_t   cpumask;
spinlock_t  lock;
+   struct timer_list   timer;
 };
 
 struct padata_instance {
diff --git a/kernel/padata.c b/kernel/padata.c
index 82958e0..6d7ea48 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -231,7 +231,8 @@ static struct padata_priv *padata_get_next(struct 
parallel_data *pd)
goto out;
}
 
-   if (next_nr % num_cpus == next_queue-cpu_index) {
+   queue = per_cpu_ptr(pd-queue, smp_processor_id());
+   if (queue-cpu_index == next_queue-cpu_index) {
padata = ERR_PTR(-ENODATA);
goto out;
}
@@ -247,9 +248,8 @@ static void padata_reorder(struct parallel_data *pd)
struct padata_queue *queue;
struct padata_instance *pinst = pd-pinst;
 
-try_again:
if (!spin_trylock_bh(pd-lock))
-   goto out;
+   return;
 
while (1) {
padata = padata_get_next(pd);
@@ -258,8 +258,9 @@ try_again:
break;
 
if (PTR_ERR(padata) == -ENODATA) {
+   del_timer(pd-timer);
spin_unlock_bh(pd-lock);
-   goto out;
+   return;
}
 
queue = per_cpu_ptr(pd-queue, padata-cb_cpu);
@@ -273,13 +274,22 @@ try_again:
 
spin_unlock_bh(pd-lock);
 
-   if (atomic_read(pd-reorder_objects))
-   goto try_again;
+   if (atomic_read(pd-reorder_objects)
+!(pinst-flags  PADATA_RESET))
+   mod_timer(pd-timer, jiffies + HZ);
+   else
+   del_timer(pd-timer);
 
-out:
return;
 }
 
+static void padata_reorder_timer(unsigned long arg)
+{
+   struct parallel_data *pd = (struct parallel_data *)arg;
+
+   padata_reorder(pd);
+}
+
 static void padata_serial_worker(struct work_struct *work)
 {
struct padata_queue *queue;
@@ -383,6 +393,7 @@ static struct parallel_data *padata_alloc_pd(struct 
padata_instance *pinst,
num_cpus = cpumask_weight(pd-cpumask);
pd-max_seq_nr = (MAX_SEQ_NR / num_cpus) * num_cpus - 1;
 
+   setup_timer(pd-timer, padata_reorder_timer, (unsigned long)pd);
atomic_set(pd-seq_nr, -1);
atomic_set(pd-reorder_objects, 0);
atomic_set(pd-refcnt, 0);
-- 
1.5.6.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/4] padata: Flush the padata queues actively

2010-05-14 Thread Steffen Klassert
yield was used to wait until all references of the internal control
structure in use are dropped before it is freed. This patch implements
padata_flush_queues which actively flushes the padata percpu queues
in this case.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 kernel/padata.c |   33 +
 1 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/kernel/padata.c b/kernel/padata.c
index 6d7ea48..ec6b8b7 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -417,6 +417,29 @@ static void padata_free_pd(struct parallel_data *pd)
kfree(pd);
 }
 
+static void padata_flush_queues(struct parallel_data *pd)
+{
+   int cpu;
+   struct padata_queue *queue;
+
+   for_each_cpu(cpu, pd-cpumask) {
+   queue = per_cpu_ptr(pd-queue, cpu);
+   flush_work(queue-pwork);
+   }
+
+   del_timer_sync(pd-timer);
+
+   if (atomic_read(pd-reorder_objects))
+   padata_reorder(pd);
+
+   for_each_cpu(cpu, pd-cpumask) {
+   queue = per_cpu_ptr(pd-queue, cpu);
+   flush_work(queue-swork);
+   }
+
+   BUG_ON(atomic_read(pd-refcnt) != 0);
+}
+
 static void padata_replace(struct padata_instance *pinst,
   struct parallel_data *pd_new)
 {
@@ -428,11 +451,7 @@ static void padata_replace(struct padata_instance *pinst,
 
synchronize_rcu();
 
-   while (atomic_read(pd_old-refcnt) != 0)
-   yield();
-
-   flush_workqueue(pinst-wq);
-
+   padata_flush_queues(pd_old);
padata_free_pd(pd_old);
 
pinst-flags = ~PADATA_RESET;
@@ -695,12 +714,10 @@ void padata_free(struct padata_instance *pinst)
 
synchronize_rcu();
 
-   while (atomic_read(pinst-pd-refcnt) != 0)
-   yield();
-
 #ifdef CONFIG_HOTPLUG_CPU
unregister_hotcpu_notifier(pinst-cpu_notifier);
 #endif
+   padata_flush_queues(pinst-pd);
padata_free_pd(pinst-pd);
free_cpumask_var(pinst-cpumask);
kfree(pinst);
-- 
1.5.6.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/4] padata: Add some code comments

2010-05-14 Thread Steffen Klassert

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 include/linux/padata.h |   53 
 kernel/padata.c|   50 +++-
 2 files changed, 101 insertions(+), 2 deletions(-)

diff --git a/include/linux/padata.h b/include/linux/padata.h
index 64836a6..e8aac0f 100644
--- a/include/linux/padata.h
+++ b/include/linux/padata.h
@@ -26,6 +26,17 @@
 #include linux/list.h
 #include linux/timer.h
 
+/*
+ * struct padata_priv -  Embedded to the users data structure.
+ *
+ * @list: List entry, to attach to the padata lists.
+ * @pd: Pointer to the internal control structure.
+ * @cb_cpu: Callback cpu for serializatioon.
+ * @seq_nr: Sequence number of the parallelized data object.
+ * @info: Used to pass information from the parallel to the serial function.
+ * @parallel: Parallel execution function.
+ * @serial: Serial complete function.
+ */
 struct padata_priv {
struct list_headlist;
struct parallel_data*pd;
@@ -36,11 +47,29 @@ struct padata_priv {
void(*serial)(struct padata_priv *padata);
 };
 
+/*
+ * struct padata_list
+ *
+ * @list: List head.
+ * @lock: List lock.
+ */
 struct padata_list {
struct list_headlist;
spinlock_t  lock;
 };
 
+/*
+ * struct padata_queue - The percpu padata queues.
+ *
+ * @parallel: List to wait for parallelization.
+ * @reorder: List to wait for reordering after parallel processing.
+ * @serial: List to wait for serialization after reordering.
+ * @pwork: work struct for parallelization.
+ * @swork: work struct for serialization.
+ * @pd: Backpointer to the internal control structure.
+ * @num_obj: Number of objects that are processed by this cpu.
+ * @cpu_index: Index of the cpu.
+ */
 struct padata_queue {
struct padata_list  parallel;
struct padata_list  reorder;
@@ -52,6 +81,20 @@ struct padata_queue {
int cpu_index;
 };
 
+/*
+ * struct parallel_data - Internal control structure, covers everything
+ * that depends on the cpumask in use.
+ *
+ * @pinst: padata instance.
+ * @queue: percpu padata queues.
+ * @seq_nr: The sequence number that will be attached to the next object.
+ * @reorder_objects: Number of objects waiting in the reorder queues.
+ * @refcnt: Number of objects holding a reference on this parallel_data.
+ * @max_seq_nr:  Maximal used sequence number.
+ * @cpumask: cpumask in use.
+ * @lock: Reorder lock.
+ * @timer: Reorder timer.
+ */
 struct parallel_data {
struct padata_instance  *pinst;
struct padata_queue *queue;
@@ -64,6 +107,16 @@ struct parallel_data {
struct timer_list   timer;
 };
 
+/*
+ * struct padata_instance - The overall control structure.
+ *
+ * @cpu_notifier: cpu hotplug notifier.
+ * @wq: The workqueue in use.
+ * @pd: The internal control structure.
+ * @cpumask: User supplied cpumask.
+ * @lock: padata instance lock.
+ * @flags: padata flags.
+ */
 struct padata_instance {
struct notifier_block   cpu_notifier;
struct workqueue_struct *wq;
diff --git a/kernel/padata.c b/kernel/padata.c
index ec6b8b7..629bef3 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -152,6 +152,23 @@ out:
 }
 EXPORT_SYMBOL(padata_do_parallel);
 
+/*
+ * padata_get_next - Get the next object that needs serialization.
+ *
+ * Return values are:
+ *
+ * A pointer to the control struct of the next object that needs
+ * serialization, if present in one of the percpu reorder queues.
+ *
+ * NULL, if all percpu reorder queues are empty.
+ *
+ * -EINPROGRESS, if the next object that needs serialization will
+ *  be parallel processed by another cpu and is not yet present in
+ *  the cpu's reorder queue.
+ *
+ * -ENODATA, if this cpu has to do the parallel processing for
+ *  the next object.
+ */
 static struct padata_priv *padata_get_next(struct parallel_data *pd)
 {
int cpu, num_cpus, empty, calc_seq_nr;
@@ -173,7 +190,7 @@ static struct padata_priv *padata_get_next(struct 
parallel_data *pd)
 
/*
 * Calculate the seq_nr of the object that should be
-* next in this queue.
+* next in this reorder queue.
 */
overrun = 0;
calc_seq_nr = (atomic_read(queue-num_obj) * num_cpus)
@@ -248,15 +265,36 @@ static void padata_reorder(struct parallel_data *pd)
struct padata_queue *queue;
struct padata_instance *pinst = pd-pinst;
 
+   /*
+* We need to ensure that only one cpu can work on dequeueing of
+* the reorder queue the time. Calculating in which percpu reorder
+* queue the next object will arrive takes some time. A spinlock
+* would be highly contended. Also it is not clear in which order
+* the objects arrive to the reorder queues. So a cpu could wait to
+* get the lock just to notice

Re: Long pause when using pcrypt

2010-04-23 Thread Steffen Klassert
On Thu, Apr 22, 2010 at 10:57:24AM +0200, Nils Rennebarth wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1
 
 Hi,
 
 As parallel encryption of ipsec is now in the official kernel, I tried to use
 it, and to actually make ipsec connections use it, I did
 
   $ modprobe tcrypt alg='pcrypt(authenc(hmac(sha1),cbc(aes)))' type=3
 
 This works, but the computer pauses for about 60s when running the modprobe,
 and appears to be completely idle in the meantime. Why is that necessary?

You can try to specify the drivers e.g.

modprobe tcrypt alg=pcrypt(authenc(hmac(sha1-generic),cbc(aes-asm))) type=3

this should be faster.

 
 Is there another recommended way to instantiate pcrypt, e.g. via netlink?
 I searched for a while, by browsing the sources, but found nothing 
 appropriate.
 

Unfortunately not yet, this should change as soon as we have a generic crypto 
user
configuration interface.

Steffen
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [patch v3] pcrypt: handle crypto_get_attr_type() errors

2010-03-23 Thread Steffen Klassert
On Mon, Mar 22, 2010 at 06:28:45PM +0300, Dan Carpenter wrote:
 I was concerned about the error handling for crypto_get_attr_type() in
 pcrypt_alloc_aead().  Steffen Klassert pointed out that we could simply
 avoid calling crypto_get_attr_type() if we passed the type and mask as a
 parameters.
 
 Signed-off-by: Dan Carpenter erro...@gmail.com

Acked-by: Steffen Klassert steffen.klass...@secunet.com

Thanks a lot!

 ---
 All three versions have basically been the same except for style issues.
 I will confess that this (hopefully final :P) version looks much nicer 
 than the earlier ones.
 

It's not only style issues. We also got some additional benefit from
this version. We got rid of a superfluous call to crypto_get_attr_type
and we are able to change type and mask before we pass it to
pcrypt_alloc_aead if this becomes necessary.

Steffen
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [patch] pcrypt: handle crypto_get_attr_type() errors

2010-03-22 Thread Steffen Klassert
On Sun, Mar 21, 2010 at 12:28:47PM +0300, Dan Carpenter wrote:
 crypto_get_attr_type() can returns ERR_PTRs if there is a problem. 
 
 Signed-off-by: Dan Carpenter erro...@gmail.com
 
 diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
 index 8020124..41bd80f 100644
 --- a/crypto/pcrypt.c
 +++ b/crypto/pcrypt.c
 @@ -322,6 +322,8 @@ static struct crypto_instance *pcrypt_alloc_aead(struct 
 rtattr **tb)
   struct crypto_attr_type *algt;
  
   algt = crypto_get_attr_type(tb);
 + if (IS_ERR(algt))
 + return ERR_CAST(algt);
  
   alg = crypto_get_attr_alg(tb, algt-type,
 (algt-mask  CRYPTO_ALG_TYPE_MASK));

I've just noticed that we are calling crypto_get_attr_type already in
pcrypt_alloc, so perhaps we could just pass the type and mask to
pcrypt_alloc_aead. Then we can remove this second call to
crypto_get_attr_type completely.

Steffen
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [patch v2] pcrypt: handle crypto_get_attr_type() errors

2010-03-22 Thread Steffen Klassert
On Mon, Mar 22, 2010 at 04:53:19PM +0300, Dan Carpenter wrote:
  
 -static struct crypto_instance *pcrypt_alloc_aead(struct rtattr **tb)
 +static struct crypto_instance *pcrypt_alloc_aead(struct rtattr **tb,
 +  struct crypto_attr_type *algt)
  {
   struct crypto_instance *inst;
   struct crypto_alg *alg;
 - struct crypto_attr_type *algt;
 -
 - algt = crypto_get_attr_type(tb);
  
   alg = crypto_get_attr_alg(tb, algt-type,
 (algt-mask  CRYPTO_ALG_TYPE_MASK));
 @@ -365,7 +363,7 @@ static struct crypto_instance *pcrypt_alloc(struct rtattr 
 **tb)
  
   switch (algt-type  algt-mask  CRYPTO_ALG_TYPE_MASK) {
   case CRYPTO_ALG_TYPE_AEAD:
 - return pcrypt_alloc_aead(tb);
 + return pcrypt_alloc_aead(tb, algt);
   }
  

I thought about passing the type and mask values separately to
pcrypt_alloc_aead, like type and mask values are passed to
crypto_get_attr_alg. This is the usual way to do this in the
crypto layer.

Thanks,

Steffen
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Suspect bug in the authenc module

2010-03-01 Thread Steffen Klassert
On Sat, Feb 27, 2010 at 12:14:15PM +0100, Roberto Sassu wrote:
 Hello
 
 i'm trying to use the authenc module and i wrote a small kernel module that 
 simply encrypts/decrypts a fixed data using the hmac(sha1) as authentication 
 algorithm and cbc(aes) as encryption algorithm. 
 The used platform is a KVM quest with Fedora 12 i686 and the latest kernel 
 2.6.33.
 I have taken the code from the testmgr and from net/ipv4/esp4.c.
 But, when testing the code, attached in this mail, the crypto_aead_decrypt() 
 function always replies -EBADMSG. 

I've posted two fixes for authenc to the linux-crypto list last week.
Could you please try whether these patches fix your problems?

Thanks,

Steffen

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: tip: origin tree boot crash

2010-03-01 Thread Steffen Klassert
Hi.

On Mon, Mar 01, 2010 at 08:50:24AM +0100, Ingo Molnar wrote:
 
 Hi,
 
 * Herbert Xu herb...@gondor.apana.org.au wrote:
 
crypto: pcrypt - Add pcrypt crypto parallelization wrapper
 
 -tip testing started triggering the following frequent boot crash yesterday, 
 on 64-bit x86:
 
  |  calling  pcrypt_init+0x0/0xee @ 1
  |  BUG: unable to handle kernel NULL pointer dereference at (null)
  |  IP: [8126550b] memcpy+0xb/0xb0
  |  Call Trace:
  |   [810c2f38] ? padata_alloc+0x98/0x150
  |   [82158c51] ? pcrypt_init+0x0/0xee
  |   [82158ccc] pcrypt_init+0x7b/0xee
 

Ugh, it seems that I forgot to allocate one of the cpumasks. Looking at the
configs of my test systems I noticed, that CONFIG_CPUMASK_OFFSTACK was
not set on all the configs, so I did not notice it.

The patch below fixes the boot crash if CONFIG_CPUMASK_OFFSTACK is
enabled on my test systems. Does the patch fix it for you too?

Thanks,

Steffen

Subject: [PATCH] padata: allocate the cpumask for the padata instance

The cpumask of the padata instance was used without allocated.
This caused boot crashes if CONFIG_CPUMASK_OFFSTACK is enabled.
This patch fixes this by doing proper allocation for this cpumask.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 kernel/padata.c |8 +++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/kernel/padata.c b/kernel/padata.c
index 6f9bcb8..93caf65 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -642,6 +642,9 @@ struct padata_instance *padata_alloc(const struct cpumask 
*cpumask,
if (!pd)
goto err_free_inst;
 
+   if (!alloc_cpumask_var(pinst-cpumask, GFP_KERNEL))
+   goto err_free_pd;
+
rcu_assign_pointer(pinst-pd, pd);
 
pinst-wq = wq;
@@ -654,12 +657,14 @@ struct padata_instance *padata_alloc(const struct cpumask 
*cpumask,
pinst-cpu_notifier.priority = 0;
err = register_hotcpu_notifier(pinst-cpu_notifier);
if (err)
-   goto err_free_pd;
+   goto err_free_cpumask;
 
mutex_init(pinst-lock);
 
return pinst;
 
+err_free_cpumask:
+   free_cpumask_var(pinst-cpumask);
 err_free_pd:
padata_free_pd(pd);
 err_free_inst:
@@ -685,6 +690,7 @@ void padata_free(struct padata_instance *pinst)
 
unregister_hotcpu_notifier(pinst-cpu_notifier);
padata_free_pd(pinst-pd);
+   free_cpumask_var(pinst-cpumask);
kfree(pinst);
 }
 EXPORT_SYMBOL(padata_free);
-- 
1.5.6.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] crypto: authenc - Use correct ahash complete functions

2010-02-22 Thread Steffen Klassert
We accidentally assigned the ahash update complete function to
the wrong function pointer in crypto_authenc_verify.
This patch fixes this.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/authenc.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/crypto/authenc.c b/crypto/authenc.c
index 1887090..6287cfd 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -454,7 +454,7 @@ static int crypto_authenc_verify(struct aead_request *req,
unsigned int authsize;
 
areq_ctx-complete = authenc_verify_ahash_done;
-   areq_ctx-complete = authenc_verify_ahash_update_done;
+   areq_ctx-update_complete = authenc_verify_ahash_update_done;
 
ohash = authenc_ahash_fn(req, CRYPTO_TFM_REQ_MAY_SLEEP);
if (IS_ERR(ohash))
-- 
1.5.6.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] crypto: authenc - move saved IV in front of the ablkcipher request

2010-02-22 Thread Steffen Klassert
In crypto_authenc_encrypt() we save the IV behind the ablkcipher
request. To save space on the request, we overwrite the ablkcipher
request with a ahash request after encryption. So the IV may be
overwritten by the ahash request. This patch fixes this by placing
the IV in front of the ablkcipher/ahash request.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/authenc.c |   25 ++---
 1 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/crypto/authenc.c b/crypto/authenc.c
index 6287cfd..2bb7348 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -386,11 +386,13 @@ static int crypto_authenc_encrypt(struct aead_request 
*req)
 {
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
-   struct ablkcipher_request *abreq = aead_request_ctx(req);
+   struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
struct crypto_ablkcipher *enc = ctx-enc;
struct scatterlist *dst = req-dst;
unsigned int cryptlen = req-cryptlen;
-   u8 *iv = (u8 *)(abreq + 1) + crypto_ablkcipher_reqsize(enc);
+   struct ablkcipher_request *abreq = (void *)(areq_ctx-tail
+   + ctx-reqoff);
+   u8 *iv = (u8 *)abreq - crypto_ablkcipher_ivsize(enc);
int err;
 
ablkcipher_request_set_tfm(abreq, enc);
@@ -546,10 +548,6 @@ static int crypto_authenc_init_tfm(struct crypto_tfm *tfm)
if (IS_ERR(auth))
return PTR_ERR(auth);
 
-   ctx-reqoff = ALIGN(2 * crypto_ahash_digestsize(auth) +
-   crypto_ahash_alignmask(auth),
-   crypto_ahash_alignmask(auth) + 1);
-
enc = crypto_spawn_skcipher(ictx-enc);
err = PTR_ERR(enc);
if (IS_ERR(enc))
@@ -558,13 +556,18 @@ static int crypto_authenc_init_tfm(struct crypto_tfm *tfm)
ctx-auth = auth;
ctx-enc = enc;
 
-   tfm-crt_aead.reqsize = max_t(unsigned int,
-   crypto_ahash_reqsize(auth) + ctx-reqoff +
-   sizeof(struct authenc_request_ctx) +
+   ctx-reqoff = ALIGN(2 * crypto_ahash_digestsize(auth) +
+   crypto_ahash_alignmask(auth),
+   crypto_ahash_alignmask(auth) + 1) +
+ crypto_ablkcipher_ivsize(enc);
+
+   tfm-crt_aead.reqsize = sizeof(struct authenc_request_ctx) +
+   ctx-reqoff +
+   max_t(unsigned int,
+   crypto_ahash_reqsize(auth) +
sizeof(struct ahash_request),
sizeof(struct skcipher_givcrypt_request) +
-   crypto_ablkcipher_reqsize(enc) +
-   crypto_ablkcipher_ivsize(enc));
+   crypto_ablkcipher_reqsize(enc));
 
return 0;
 
-- 
1.5.6.5

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] crypto: pcrypt - call the complete function on error

2010-02-01 Thread Steffen Klassert
This fixes three forgotten calls to the complete function
in the error case.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/pcrypt.c |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
index b9527d0..8020124 100644
--- a/crypto/pcrypt.c
+++ b/crypto/pcrypt.c
@@ -114,7 +114,7 @@ static void pcrypt_aead_enc(struct padata_priv *padata)
 
padata-info = crypto_aead_encrypt(req);
 
-   if (padata-info)
+   if (padata-info == -EINPROGRESS)
return;
 
padata_do_serial(padata);
@@ -158,7 +158,7 @@ static void pcrypt_aead_dec(struct padata_priv *padata)
 
padata-info = crypto_aead_decrypt(req);
 
-   if (padata-info)
+   if (padata-info == -EINPROGRESS)
return;
 
padata_do_serial(padata);
@@ -202,7 +202,7 @@ static void pcrypt_aead_givenc(struct padata_priv *padata)
 
padata-info = crypto_aead_givencrypt(req);
 
-   if (padata-info)
+   if (padata-info == -EINPROGRESS)
return;
 
padata_do_serial(padata);
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] crypto: pcrypt - Add pcrypt crypto parallelization wrapper

2009-12-18 Thread Steffen Klassert
This 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 algorithms are supported.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/Kconfig  |   10 +
 crypto/Makefile |1 +
 crypto/pcrypt.c |  445 +++
 include/crypto/pcrypt.h |   51 ++
 4 files changed, 507 insertions(+), 0 deletions(-)
 create mode 100644 crypto/pcrypt.c
 create mode 100644 include/crypto/pcrypt.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 81c185a..6a2e295 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -114,6 +114,16 @@ config CRYPTO_NULL
help
  These are 'Null' algorithms, used by IPsec, which do nothing.
 
+config CRYPTO_PCRYPT
+   tristate Parallel crypto engine (EXPERIMENTAL)
+   depends on SMP  EXPERIMENTAL
+   select PADATA
+   select CRYPTO_MANAGER
+   select CRYPTO_AEAD
+   help
+ This converts an arbitrary crypto algorithm into a parallel
+ algorithm that executes in kernel threads.
+
 config CRYPTO_WORKQUEUE
tristate
 
diff --git a/crypto/Makefile b/crypto/Makefile
index 9e8f619..d7e6441 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -56,6 +56,7 @@ 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) += pcrypt.o
 obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o
 obj-$(CONFIG_CRYPTO_DES) += des_generic.o
 obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
new file mode 100644
index 000..b9527d0
--- /dev/null
+++ b/crypto/pcrypt.c
@@ -0,0 +1,445 @@
+/*
+ * pcrypt - Parallel crypto wrapper.
+ *
+ * Copyright (C) 2009 secunet Security Networks AG
+ * Copyright (C) 2009 Steffen Klassert steffen.klass...@secunet.com
+ *
+ * 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 crypto/algapi.h
+#include crypto/internal/aead.h
+#include linux/err.h
+#include linux/init.h
+#include linux/module.h
+#include linux/slab.h
+#include crypto/pcrypt.h
+
+static struct padata_instance *pcrypt_enc_padata;
+static struct padata_instance *pcrypt_dec_padata;
+static struct workqueue_struct *encwq;
+static struct workqueue_struct *decwq;
+
+struct pcrypt_instance_ctx {
+   struct crypto_spawn spawn;
+   unsigned int tfm_count;
+};
+
+struct pcrypt_aead_ctx {
+   struct crypto_aead *child;
+   unsigned int cb_cpu;
+};
+
+static int pcrypt_do_parallel(struct padata_priv *padata, unsigned int *cb_cpu,
+ struct padata_instance *pinst)
+{
+   unsigned int cpu_index, cpu, i;
+
+   cpu = *cb_cpu;
+
+   if (cpumask_test_cpu(cpu, cpu_active_mask))
+   goto out;
+
+   cpu_index = cpu % cpumask_weight(cpu_active_mask);
+
+   cpu = cpumask_first(cpu_active_mask);
+   for (i = 0; i  cpu_index; i++)
+   cpu = cpumask_next(cpu, cpu_active_mask);
+
+   *cb_cpu = cpu;
+
+out:
+   return padata_do_parallel(pinst, padata, cpu);
+}
+
+static int pcrypt_aead_setkey(struct crypto_aead *parent,
+ const u8 *key, unsigned int keylen)
+{
+   struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent);
+
+   return crypto_aead_setkey(ctx-child, key, keylen);
+}
+
+static int pcrypt_aead_setauthsize(struct crypto_aead *parent,
+  unsigned int authsize)
+{
+   struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent);
+
+   return crypto_aead_setauthsize(ctx-child, authsize);
+}
+
+static void pcrypt_aead_serial(struct padata_priv *padata)
+{
+   struct pcrypt_request *preq = pcrypt_padata_request(padata);
+   struct aead_request *req = pcrypt_request_ctx(preq);
+
+   aead_request_complete(req-base.data, padata-info);
+}
+
+static void pcrypt_aead_giv_serial(struct padata_priv *padata)
+{
+   struct pcrypt_request *preq = pcrypt_padata_request(padata);
+   struct aead_givcrypt_request *req = pcrypt_request_ctx(preq);
+
+   aead_request_complete(req-areq.base.data, padata-info);
+}
+
+static void pcrypt_aead_done(struct crypto_async_request *areq, int err)
+{
+   struct aead_request *req = areq-data;
+   struct pcrypt_request *preq

[PATCH 1/2] padata: generic parallelization/serialization interface

2009-12-18 Thread Steffen Klassert
This patch introduces an interface to process data objects
in parallel. The parallelized objects return after serialization
in the same order as they were before the parallelization.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 include/linux/padata.h |   88 ++
 init/Kconfig   |4 +
 kernel/Makefile|1 +
 kernel/padata.c|  690 
 4 files changed, 783 insertions(+), 0 deletions(-)
 create mode 100644 include/linux/padata.h
 create mode 100644 kernel/padata.c

diff --git a/include/linux/padata.h b/include/linux/padata.h
new file mode 100644
index 000..51611da
--- /dev/null
+++ b/include/linux/padata.h
@@ -0,0 +1,88 @@
+/*
+ * padata.h - header for the padata parallelization interface
+ *
+ * Copyright (C) 2008, 2009 secunet Security Networks AG
+ * Copyright (C) 2008, 2009 Steffen Klassert steffen.klass...@secunet.com
+ *
+ * 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.
+ */
+
+#ifndef PADATA_H
+#define PADATA_H
+
+#include linux/workqueue.h
+#include linux/spinlock.h
+#include linux/list.h
+
+struct padata_priv {
+   struct list_headlist;
+   struct parallel_data*pd;
+   int cb_cpu;
+   int seq_nr;
+   int info;
+   void(*parallel)(struct padata_priv *padata);
+   void(*serial)(struct padata_priv *padata);
+};
+
+struct padata_list {
+   struct list_headlist;
+   spinlock_t  lock;
+};
+
+struct padata_queue {
+   struct padata_list  parallel;
+   struct padata_list  reorder;
+   struct padata_list  serial;
+   struct work_struct  pwork;
+   struct work_struct  swork;
+   struct parallel_data*pd;
+   atomic_tnum_obj;
+   int cpu_index;
+};
+
+struct parallel_data {
+   struct padata_instance  *pinst;
+   struct padata_queue *queue;
+   atomic_tseq_nr;
+   atomic_treorder_objects;
+   atomic_trefcnt;
+   unsigned intmax_seq_nr;
+   cpumask_var_t   cpumask;
+   spinlock_t  lock;
+};
+
+struct padata_instance {
+   struct notifier_block   cpu_notifier;
+   struct workqueue_struct *wq;
+   struct parallel_data*pd;
+   cpumask_var_t   cpumask;
+   struct mutexlock;
+   u8  flags;
+#definePADATA_INIT 1
+#definePADATA_RESET2
+};
+
+extern struct padata_instance *padata_alloc(const struct cpumask *cpumask,
+   struct workqueue_struct *wq);
+extern void padata_free(struct padata_instance *pinst);
+extern int padata_do_parallel(struct padata_instance *pinst,
+ struct padata_priv *padata, int cb_cpu);
+extern void padata_do_serial(struct padata_priv *padata);
+extern int padata_set_cpumask(struct padata_instance *pinst,
+ cpumask_var_t cpumask);
+extern int padata_add_cpu(struct padata_instance *pinst, int cpu);
+extern int padata_remove_cpu(struct padata_instance *pinst, int cpu);
+extern void padata_start(struct padata_instance *pinst);
+extern void padata_stop(struct padata_instance *pinst);
+#endif
diff --git a/init/Kconfig b/init/Kconfig
index a23da9f..9fd23bc 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1252,4 +1252,8 @@ source block/Kconfig
 config PREEMPT_NOTIFIERS
bool
 
+config PADATA
+   depends on SMP
+   bool
+
 source kernel/Kconfig.locks
diff --git a/kernel/Makefile b/kernel/Makefile
index 864ff75..6aebdeb 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -100,6 +100,7 @@ obj-$(CONFIG_SLOW_WORK_DEBUG) += slow-work-debugfs.o
 obj-$(CONFIG_PERF_EVENTS) += perf_event.o
 obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
 obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
+obj-$(CONFIG_PADATA) += padata.o
 
 ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
 # According to Alan Modra a...@linuxcare.com.au, the -fno-omit-frame-pointer 
is
diff --git a/kernel/padata.c b/kernel/padata.c
new file mode 100644
index 000..6f9bcb8
--- /dev/null
+++ b/kernel/padata.c
@@ -0,0 +1,690

Re: [PATCH 2/2] crypto: pcrypt - Add pcrypt crypto parallelization wrapper

2009-10-30 Thread Steffen Klassert
On Thu, Oct 08, 2009 at 11:18:33PM -0700, David Miller wrote:
 
 Steffen are we going to end up adding a softirq for every crypto
 transform type?
 
 That won't work, softirqs are to be scarcely allocated and operate
 at a very high level.
 

I changed padata to use workqueues instead of softirqs to do the
parallelization/serialization. The performance for IPsec is similar
to the softirq version, so probaply we don't need to use softirqs at
all.

While thinking about using workqueues for padata/pcrypt, I noticed
two problems if we return asynchronous in thread context from the
crypto-layer to xfrm. Returning in thread context is not new with
pcrypt, we also can return in thread context if we use the cryptd. 

If we use tunnel mode, xfrm_input() calls netif_rx() which is certainly
wrong if we are in thread context, we need to call netif_rx_ni() instead. 
Also xfrm_input() uses bare spinlocks to protect the xfrm_state, this is
not appropriate in this case. We probaply need to switch off the bottom
halves, if we allow to return from the cypto-layer in softirq and thread
context.

Any thoughts on how to handle this?
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] crypto: pcrypt - Add pcrypt crypto parallelization wrapper

2009-10-30 Thread Steffen Klassert
On Fri, Oct 30, 2009 at 08:58:18AM -0400, Herbert Xu wrote:
 
 Since this is all happening through a crypto completion call,
 it needs to be done with BH off since that's a requirement for
 crypto completion functions.  So netif_rx will work correctly
 as when BH is reenabled it'll pick up the packets.

Ok, if it's required that BHs are off then everything is fine.
In fact I solved this problem for pcrypt by switching off the BHs.
I just was not sure whether this is the right way to do.

Thanks for clarification!

I'm going to send a workqueue based version of padata/pcrypt
within the next week.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] crypto: pcrypt - Add pcrypt crypto parallelization wrapper

2009-10-09 Thread Steffen Klassert
On Thu, Oct 08, 2009 at 11:18:33PM -0700, David Miller wrote:
 
 Steffen are we going to end up adding a softirq for every crypto
 transform type?
 
 That won't work, softirqs are to be scarcely allocated and operate
 at a very high level.
 
 I can think of two alternatives:
 
 1) One softirq that does per-cpu padata work via some generic
callout mechanism.

I tried already to reduce the softirqs by using the same softirq for
encryption and decryption. But in case of IPsec this had a negative
performance impact. So if we stay with softirqs we would probaply need
at least two for the whole crypto layer.

Best would be if we would not need softirqs at all. In fact I started
with a thread based version but the thread based version had never that
performance like the softirq version has.

Anyway, in between the workqueue interface changed so perhaps it is
worth to try again with workqueues.

 
 2) Use tasklets
 

Tasklets are not sufficient because I can't control on which cpu the
tasklet will run on. Also we can run just one tasklet of the same type
the time, so tasklets don't parallelize.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] padata: generic interface for parallel processing

2009-10-08 Thread Steffen Klassert
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.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 include/linux/interrupt.h  |3 +-
 include/linux/padata.h |  121 ++
 include/trace/events/irq.h |1 +
 kernel/Makefile|2 +-
 kernel/padata.c|  519 
 kernel/softirq.c   |2 +-
 6 files changed, 645 insertions(+), 3 deletions(-)
 create mode 100644 include/linux/padata.h
 create mode 100644 kernel/padata.c

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index b78cf81..1af1e4b 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -350,7 +350,8 @@ enum
TASKLET_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
 };
diff --git a/include/linux/padata.h b/include/linux/padata.h
new file mode 100644
index 000..a81161d
--- /dev/null
+++ b/include/linux/padata.h
@@ -0,0 +1,121 @@
+/*
+ * padata.h - header for the padata parallelization interface
+ *
+ * Copyright (C) 2008, 2009 secunet Security Networks AG
+ * Copyright (C) 2008, 2009 Steffen Klassert steffen.klass...@secunet.com
+ *
+ * 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.
+ */
+
+#ifndef PADATA_H
+#define PADATA_H
+
+#include linux/interrupt.h
+#include linux/smp.h
+#include linux/list.h
+
+enum
+{
+   NO_PADATA=0,
+   AEAD_ENC_PADATA,
+   AEAD_DEC_PADATA,
+   NR_PADATA
+};
+
+struct padata_priv {
+   struct list_headlist;
+   struct call_single_data csd;
+   int cb_cpu;
+   int seq_nr;
+   unsigned intnr;
+   int info;
+   void(*parallel)(struct padata_priv *padata);
+   void(*serial)(struct padata_priv *padata);
+};
+
+struct padata_queue {
+   struct list_headlist;
+   atomic_tnum_obj;
+   int cpu_index;
+   spinlock_t  lock;
+};
+
+struct parallel_data {
+   struct work_struct  work;
+   struct padata_queue *queue;
+   atomic_tseq_nr;
+   atomic_tqueued_objects;
+   cpumask_var_t   cpumask;
+   cpumask_var_t   new_cpumask;
+   u8  flags;
+#definePADATA_INIT 1
+#definePADATA_FLUSH_HARD   2
+#definePADATA_RESET_IN_PROGRESS4
+   spinlock_t  lock;
+};
+
+#ifdef CONFIG_USE_GENERIC_SMP_HELPERS
+extern void __init padata_init(unsigned int nr, const struct cpumask *cpumask);
+extern void padata_dont_wait(unsigned int nr, struct padata_priv *padata);
+extern int padata_do_parallel(unsigned int softirq_nr, unsigned int nr,
+ struct padata_priv *padata, int cb_cpu);
+extern int padata_do_serial(unsigned int nr, struct padata_priv *padata);
+extern int padata_cpumask_weight(unsigned int nr);
+extern int padata_index_to_cpu(unsigned int nr, int cpu_index);
+extern void padata_set_cpumask(unsigned int nr, cpumask_var_t cpumask);
+extern void padata_add_cpu(unsigned int nr, int cpu);
+extern void padata_remove_cpu(unsigned int nr, int cpu);
+extern void padata_start(unsigned int nr);
+extern void padata_stop(unsigned int nr);
+#else
+static inline void padata_init(unsigned int nr, const struct cpumask *cpumask)
+{
+}
+static inline void padata_dont_wait(unsigned int nr, struct padata_priv 
*padata)
+{
+}
+static inline int padata_do_parallel(unsigned int softirq_nr, unsigned int nr,
+struct padata_priv *padata, int cb_cpu)
+{
+   return 0;
+}
+static inline int padata_do_serial(unsigned int nr, struct padata_priv *padata)
+{
+   return 0;
+}
+static inline int padata_cpumask_weight(unsigned int nr)
+{
+   return 0;
+}
+static inline int padata_index_to_cpu(unsigned int nr, int cpu_index)
+{
+   return -ENOSYS

Re: Does ESP support 64 bit sequence numbering for authentication hash ?

2009-09-01 Thread Steffen Klassert
On Thu, Jan 15, 2009 at 04:56:44PM +1100, Herbert Xu wrote:
 Dean Jenkins djenk...@mvista.com wrote:
  
  Does ESP support 64 bit sequence numbering for use with the
  authentication HMAC ?
 
 We don't support 64-bit sequence numbers yet.  If you look at
 struct xfrm_replay_state which is where we store the sequence
 number internally you'll find that it uses u32s.
 
 Patches for 64-bit support are welcome of course.
 

Is there actually anybody working on 64-bit sequence number support?
If not, I'd start to look at it.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Does ESP support 64 bit sequence numbering for authentication hash ?

2009-09-01 Thread Steffen Klassert
On Tue, Sep 01, 2009 at 03:23:21PM +0300, Alex Badea wrote:
 
 A while ago I implemented a rough version of ESN support. It's against
 an ancient 2.6.7 kernel though, and is only superficially tested.
 
 I suppose there's no reason not to publish them here, if only for
 historical reasons. My apologies to anyone not interested :)
 

I'll have a look whether I can use some parts of it, thanks.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2] crypto: pcrypt - Add pcrypt crypto parallelization wrapper

2009-08-31 Thread Steffen Klassert
This 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.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/Kconfig|   13 ++
 crypto/Makefile   |2 +
 crypto/pcrypt.c   |  409 +
 crypto/pcrypt_core.c  |  106 
 include/crypto/pcrypt.h   |   51 ++
 include/linux/interrupt.h |2 +
 6 files changed, 583 insertions(+), 0 deletions(-)
 create mode 100644 crypto/pcrypt.c
 create mode 100644 crypto/pcrypt_core.c
 create mode 100644 include/crypto/pcrypt.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 7623442..dbb1ec0 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -114,6 +114,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
 
diff --git a/crypto/Makefile b/crypto/Makefile
index c2ca721..48345da 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -55,6 +55,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
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
new file mode 100644
index 000..26b6ec1
--- /dev/null
+++ b/crypto/pcrypt.c
@@ -0,0 +1,409 @@
+/*
+ * pcrypt - Parallel crypto wrapper.
+ *
+ * Copyright (C) 2009 secunet Security Networks AG
+ * Copyright (C) 2009 Steffen Klassert steffen.klass...@secunet.com
+ *
+ * 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 crypto/algapi.h
+#include crypto/internal/aead.h
+#include linux/err.h
+#include linux/init.h
+#include linux/module.h
+#include linux/slab.h
+#include crypto/pcrypt.h
+
+struct pcrypt_instance_ctx {
+   struct crypto_spawn spawn;
+   unsigned int tfm_count;
+};
+
+struct pcrypt_aead_ctx {
+   struct crypto_aead *child;
+   unsigned int tfm_nr;
+};
+
+static int pcrypt_do_parallel(struct padata_priv *padata, unsigned int tfm_nr,
+ unsigned int softirq, unsigned int padata_nr)
+{
+   unsigned int cpu_index, num_cpus, cb_cpu;
+
+   num_cpus = padata_cpumask_weight(padata_nr);
+   if (!num_cpus)
+   return 0;
+   
+   cpu_index = tfm_nr % num_cpus;
+
+   cb_cpu = padata_index_to_cpu(padata_nr, cpu_index);
+
+   return padata_do_parallel(softirq, padata_nr, padata, cb_cpu);
+}
+
+static int pcrypt_aead_setkey(struct crypto_aead *parent,
+ const u8 *key, unsigned int keylen)
+{
+   struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent);
+
+   return crypto_aead_setkey(ctx-child, key, keylen);
+}
+
+static int pcrypt_aead_setauthsize(struct crypto_aead *parent,
+  unsigned int authsize)
+{
+   struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent);
+
+   return crypto_aead_setauthsize(ctx-child, authsize);
+}
+
+static void pcrypt_aead_serial(struct padata_priv *padata)
+{
+   struct pcrypt_request *preq = pcrypt_padata_request(padata);
+   struct aead_request *req = pcrypt_request_ctx(preq);
+
+   aead_request_complete(req-base.data, padata-info);
+}
+
+static void pcrypt_aead_giv_serial(struct padata_priv *padata)
+{
+   struct pcrypt_request *preq = pcrypt_padata_request(padata);
+   struct aead_givcrypt_request *req = pcrypt_request_ctx(preq);
+
+   aead_request_complete(req-areq.base.data, padata-info);
+}
+
+static void pcrypt_aead_done(struct crypto_async_request *areq, int err)
+{
+   struct aead_request *req = areq-data;
+   struct pcrypt_request *preq = aead_request_ctx(req

[PATCH 0/2] Parallel crypto/IPsec v5

2009-08-31 Thread Steffen Klassert
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 v4:

- Use the dynamic percpu allocator

- Drop of the obsolete eseqiv changes (eseqiv is the default IV generator
  for blockcipher algorithms on smp machines now).

Changes from v3:

- The generic aead wrapper is dropped.

- tcrypt is extended to test algorithms by name. So it is possible to
  instantiate pcrypt by doing e.g.:
  modprobe tcrypt alg=pcrypt(authenc(hmac(sha1),cbc(aes))) type=3

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.

Steffen
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] crypto: xcbc - Fix alignment calculation of xcbc_tfm_ctx

2009-08-19 Thread Steffen Klassert
The alignment calculation of xcbc_tfm_ctx uses alg-cra_alignmask
and not alg-cra_alignmask + 1 as it should. This led to frequent
crashes during the selftest of xcbc(aes-asm) on x86_64
machines. This patch fixes this. Also we use the alignmask
of xcbc and not the alignmask of the underlying algorithm
for the alignmnent calculation in xcbc_create now.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/xcbc.c |8 +---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index 1e30b31..bb7b67f 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -199,6 +199,7 @@ static int xcbc_create(struct crypto_template *tmpl, struct 
rtattr **tb)
 {
struct shash_instance *inst;
struct crypto_alg *alg;
+   unsigned long alignmask;
int err;
 
err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SHASH);
@@ -228,19 +229,20 @@ static int xcbc_create(struct crypto_template *tmpl, 
struct rtattr **tb)
if (err)
goto out_free_inst;
 
+   alignmask = alg-cra_alignmask | 3;
+   inst-alg.base.cra_alignmask = alignmask;
inst-alg.base.cra_priority = alg-cra_priority;
inst-alg.base.cra_blocksize = alg-cra_blocksize;
-   inst-alg.base.cra_alignmask = alg-cra_alignmask | 3;
 
inst-alg.digestsize = alg-cra_blocksize;
inst-alg.descsize = ALIGN(sizeof(struct xcbc_desc_ctx),
   crypto_tfm_ctx_alignment()) +
-(alg-cra_alignmask 
+(alignmask 
  ~(crypto_tfm_ctx_alignment() - 1)) +
 alg-cra_blocksize * 2;
 
inst-alg.base.cra_ctxsize = ALIGN(sizeof(struct xcbc_tfm_ctx),
-  alg-cra_alignmask) +
+  alignmask + 1) +
 alg-cra_blocksize * 2;
inst-alg.base.cra_init = xcbc_init_tfm;
inst-alg.base.cra_exit = xcbc_exit_tfm;
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface

2009-08-19 Thread Steffen Klassert
On Mon, Jun 29, 2009 at 03:52:57PM +0200, Steffen Klassert wrote:
 On Mon, Jun 29, 2009 at 07:59:50PM +0800, Herbert Xu wrote:
  
  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.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] crypto: authenc - convert to ahash

2009-07-24 Thread Steffen Klassert
On Fri, Jul 24, 2009 at 03:23:11PM +0800, Herbert Xu wrote:
 
 Ah, that makes sense.  I've done the prehash patch, let me know
 if this works.
 

Yes, it works.

Thanks!
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] crypto: authenc - convert to ahash

2009-07-23 Thread Steffen Klassert
On Tue, Jul 21, 2009 at 09:07:25PM +0800, Herbert Xu wrote:
 On Tue, Jul 21, 2009 at 02:25:09PM +0200, Steffen Klassert wrote:
  I just noticed that your shash version of hmac keeps the paded keys
  on the transform. I assumed the hashing to be reentrant, so I
  removed the locks arround the hash functions here.
 
 The padded keys are in the transform because they never change
 unless you call setkey.  The assumption has always been that
 you should use one tfm per key.
 

I found the problem. It's the digest state that is saved on the
transform right behind the opad in hmac_finup() and hmac_final().
The digest state is of course not constant and must be saved on the
request. That's why I needed the locks in authenc to get pcrypt to
work. I have a patch which moves the digest state to the request,
based on the cryptodev-2.6 tree.
However, as soon as your recent import/export patches are in the
cryptodev-2.6 tree we could probaply change hmac to do prehashing of the
keys what would fix the problem too.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] crypto: authenc - convert to ahash

2009-07-22 Thread Steffen Klassert
On Wed, Jul 22, 2009 at 03:02:59PM +0800, Herbert Xu wrote:
 On Tue, Jul 21, 2009 at 11:02:17AM +0200, Steffen Klassert wrote:
 
  +   err = crypto_ahash_finup(ahreq);
  +   if (err == -EINPROGRESS)
  +   return;
 
 This is redundant.  All completion functions must expect to be
 called with EINPROGRESS followed by the actual completion later.

I copied this from crypto_authenc_encrypt_done(), so this is probaply
redundant too. If so, I'd send a patch to remove the already existing
checks too and put the updated ahash convertion patch on top of it.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] crypto: ahash - Use GFP_KERNEL on allocation if the request can sleep

2009-07-22 Thread Steffen Klassert
ahash_op_unaligned() and ahash_def_finup() allocate memory atomically,
regardless whether the request can sleep or not. This patch changes
this to use GFP_KERNEL if the request can sleep.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/ahash.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/crypto/ahash.c b/crypto/ahash.c
index 28a33d0..33a4ff4 100644
--- a/crypto/ahash.c
+++ b/crypto/ahash.c
@@ -223,7 +223,7 @@ static int ahash_op_unaligned(struct ahash_request *req,
 
priv = kmalloc(sizeof(*priv) + ahash_align_buffer_size(ds, alignmask),
   (req-base.flags  CRYPTO_TFM_REQ_MAY_SLEEP) ?
-  GFP_ATOMIC : GFP_ATOMIC);
+  GFP_KERNEL : GFP_ATOMIC);
if (!priv)
return -ENOMEM;
 
@@ -333,7 +333,7 @@ static int ahash_def_finup(struct ahash_request *req)
 
priv = kmalloc(sizeof(*priv) + ahash_align_buffer_size(ds, alignmask),
   (req-base.flags  CRYPTO_TFM_REQ_MAY_SLEEP) ?
-  GFP_ATOMIC : GFP_ATOMIC);
+  GFP_KERNEL : GFP_ATOMIC);
if (!priv)
return -ENOMEM;
 
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] crypto: shash - Test for the algorithms import function before exporting it

2009-07-22 Thread Steffen Klassert
crypto_init_shash_ops_async() tests for setkey and not for import
before exporting the algorithms import function to ahash.
This patch fixes this.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/shash.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/crypto/shash.c b/crypto/shash.c
index 7713b52..d923c88 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -348,7 +348,7 @@ int crypto_init_shash_ops_async(struct crypto_tfm *tfm)
crt-setkey = shash_async_setkey;
if (alg-export)
crt-export = shash_async_export;
-   if (alg-setkey)
+   if (alg-import)
crt-import = shash_async_import;
 
crt-reqsize = sizeof(struct shash_desc) + crypto_shash_descsize(shash);
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] crypto: authenc - convert to ahash

2009-07-21 Thread Steffen Klassert
This patch converts authenc to the new ahash interface.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/authenc.c |  371 --
 1 files changed, 302 insertions(+), 69 deletions(-)

diff --git a/crypto/authenc.c b/crypto/authenc.c
index 2e16ce0..b9da719 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -23,24 +23,36 @@
 #include linux/slab.h
 #include linux/spinlock.h
 
+typedef u8 *(*authenc_ahash_t)(struct aead_request *req, unsigned int flags);
+
 struct authenc_instance_ctx {
-   struct crypto_spawn auth;
+   struct crypto_ahash_spawn auth;
struct crypto_skcipher_spawn enc;
 };
 
 struct crypto_authenc_ctx {
-   spinlock_t auth_lock;
-   struct crypto_hash *auth;
+   unsigned int reqoff;
+   struct crypto_ahash *auth;
struct crypto_ablkcipher *enc;
 };
 
+struct authenc_request_ctx {
+   unsigned int cryptlen;
+   struct scatterlist *sg;
+   struct scatterlist asg[2];
+   struct scatterlist cipher[2];
+   crypto_completion_t complete;
+   crypto_completion_t update_complete;
+   char tail[];
+};
+
 static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
 unsigned int keylen)
 {
unsigned int authkeylen;
unsigned int enckeylen;
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
-   struct crypto_hash *auth = ctx-auth;
+   struct crypto_ahash *auth = ctx-auth;
struct crypto_ablkcipher *enc = ctx-enc;
struct rtattr *rta = (void *)key;
struct crypto_authenc_key_param *param;
@@ -64,11 +76,11 @@ static int crypto_authenc_setkey(struct crypto_aead 
*authenc, const u8 *key,
 
authkeylen = keylen - enckeylen;
 
-   crypto_hash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
-   crypto_hash_set_flags(auth, crypto_aead_get_flags(authenc) 
+   crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
+   crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc) 
CRYPTO_TFM_REQ_MASK);
-   err = crypto_hash_setkey(auth, key, authkeylen);
-   crypto_aead_set_flags(authenc, crypto_hash_get_flags(auth) 
+   err = crypto_ahash_setkey(auth, key, authkeylen);
+   crypto_aead_set_flags(authenc, crypto_ahash_get_flags(auth) 
   CRYPTO_TFM_RES_MASK);
 
if (err)
@@ -103,40 +115,209 @@ static void authenc_chain(struct scatterlist *head, 
struct scatterlist *sg,
sg_mark_end(head);
 }
 
-static u8 *crypto_authenc_hash(struct aead_request *req, unsigned int flags,
-  struct scatterlist *cipher,
-  unsigned int cryptlen)
+
+static void authenc_geniv_ahash_update_done(struct crypto_async_request *areq,
+   int err)
+{
+   struct aead_request *req = areq-data;
+   struct crypto_aead *authenc = crypto_aead_reqtfm(req);
+   struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
+   struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
+   struct ahash_request *ahreq = (void *)(areq_ctx-tail + ctx-reqoff);
+
+   if (err)
+   goto out;
+
+   ahash_request_set_crypt(ahreq, areq_ctx-sg, ahreq-result,
+   areq_ctx-cryptlen);
+   ahash_request_set_callback(ahreq, aead_request_flags(req) 
+ CRYPTO_TFM_REQ_MAY_SLEEP,
+  areq_ctx-complete, req);
+
+   err = crypto_ahash_finup(ahreq);
+   if (err == -EINPROGRESS)
+   return;
+   else if (err)
+   goto out;
+
+   scatterwalk_map_and_copy(ahreq-result, areq_ctx-sg,
+areq_ctx-cryptlen,
+crypto_aead_authsize(authenc), 1);
+
+out:
+   aead_request_complete(req, err);
+}
+
+static void authenc_geniv_ahash_done(struct crypto_async_request *areq, int 
err)
+{
+   struct aead_request *req = areq-data;
+   struct crypto_aead *authenc = crypto_aead_reqtfm(req);
+   struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
+   struct authenc_request_ctx *areq_ctx = aead_request_ctx(req);
+   struct ahash_request *ahreq = (void *)(areq_ctx-tail + ctx-reqoff);
+
+   if (err)
+   goto out;
+
+   scatterwalk_map_and_copy(ahreq-result, areq_ctx-sg,
+areq_ctx-cryptlen,
+crypto_aead_authsize(authenc), 1);
+
+out:
+   aead_request_complete(req, err);
+}
+
+
+static void authenc_verify_ahash_update_done(struct crypto_async_request *areq,
+int err)
+{
+   u8 *ihash;
+   unsigned int authsize;
+   struct ablkcipher_request *abreq;
+   struct aead_request *req = areq-data;
+   struct crypto_aead *authenc

Re: [PATCH v2] crypto: authenc - convert to ahash

2009-07-21 Thread Steffen Klassert
On Tue, Jul 21, 2009 at 09:07:25PM +0800, Herbert Xu wrote:
 On Tue, Jul 21, 2009 at 02:25:09PM +0200, Steffen Klassert wrote:
  I just noticed that your shash version of hmac keeps the paded keys
  on the transform. I assumed the hashing to be reentrant, so I
  removed the locks arround the hash functions here.
 
 The padded keys are in the transform because they never change
 unless you call setkey.  The assumption has always been that
 you should use one tfm per key.

Ah, yes of course.

 
  Is there a plan to move the paded keys to the request soon, 
  or should we keep the locks for now and remove them later?
 
 You don't need to lock it since the same assumption applies to
 AEAD.
 

I came on it because I applied the pcrypt patches on top of this one
and I had to put the locks arround the hash functions to get it to work.
The problem is probaply somewhere else, I'll look at it again.

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] crypto: authenc - convert to ahash

2009-07-20 Thread Steffen Klassert
On Mon, Jul 20, 2009 at 02:52:44PM +0800, Herbert Xu wrote:
 
 This is not quite right.  What I had in mind was to use the digest
 interface if the assoc SG list has a single entry in it.  Otherwise
 it should just fall back to doing update followed by finup.
 

Ok. I was not even aware that the assoc sg list can have more than one
entry, because esp sets up assoc as a single entry list and this is
actually the only user of authenc as far as I know.

Aside the optimization, another reason to use the digest interface was to
avoid callback functions for init, update and finup. I guess we can not
avoid this if assoc can be a sg list with more than one entry, so I'll
update the patch in this manner.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH 2/7] crypto: authenc - convert to ahash

2009-07-20 Thread Steffen Klassert
On Mon, Jul 20, 2009 at 02:55:14PM +0800, Herbert Xu wrote:
 
 For the case at hand, as we've agreed to only do the chaining
 if there is only a single entry in the list, we don't need this
 at all.  All you need to do is copy the page pointer, offset and
 length without copying the raw scatterlist entry.
 

Agreed for this case. What about the existing code, should we create an
interface for it?
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] crypto: authenc - convert to ahash

2009-07-20 Thread Steffen Klassert
On Mon, Jul 20, 2009 at 04:22:24PM +0800, Herbert Xu wrote:
 
 Actually, you can assume that init is always sync since I'll
 ensure that everything supports export/import before hmac is
 converted to ahash (from shash).
 

Ok, I'll update and resend the patch.

Thanks.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH 0/7] IPsec: convert to ahash

2009-07-17 Thread Steffen Klassert
On Thu, Jul 16, 2009 at 11:46:14PM +0800, Herbert Xu wrote:
 
 My suggestion would be to optimise for the common case, where
 assoc is a single-entry list.  So just put some space aside in
 the request context for a two-entry sg list and copy the assoc
 sg entry into it and chain it with the rest.
 

Sounds good. This would also have the advantage that all necessary
changes are local to authenc. I'll give it a try.

Any further comments on the rest of the patchset?
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] crypto: authenc - convert to ahash

2009-07-17 Thread Steffen Klassert
This patch converts authenc to the new ahash interface.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/authenc.c |  217 ++
 1 files changed, 152 insertions(+), 65 deletions(-)

diff --git a/crypto/authenc.c b/crypto/authenc.c
index 2e16ce0..dec62ce 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -24,23 +24,30 @@
 #include linux/spinlock.h
 
 struct authenc_instance_ctx {
-   struct crypto_spawn auth;
+   struct crypto_ahash_spawn auth;
struct crypto_skcipher_spawn enc;
 };
 
 struct crypto_authenc_ctx {
-   spinlock_t auth_lock;
-   struct crypto_hash *auth;
+   unsigned int reqoff;
+   struct crypto_ahash *auth;
struct crypto_ablkcipher *enc;
 };
 
+struct authenc_ahash_request_ctx {
+   struct scatterlist asg[2];
+   struct scatterlist sg[2];
+   crypto_completion_t complete;
+   char tail[];
+};
+
 static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
 unsigned int keylen)
 {
unsigned int authkeylen;
unsigned int enckeylen;
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
-   struct crypto_hash *auth = ctx-auth;
+   struct crypto_ahash *auth = ctx-auth;
struct crypto_ablkcipher *enc = ctx-enc;
struct rtattr *rta = (void *)key;
struct crypto_authenc_key_param *param;
@@ -64,11 +71,11 @@ static int crypto_authenc_setkey(struct crypto_aead 
*authenc, const u8 *key,
 
authkeylen = keylen - enckeylen;
 
-   crypto_hash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
-   crypto_hash_set_flags(auth, crypto_aead_get_flags(authenc) 
+   crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
+   crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc) 
CRYPTO_TFM_REQ_MASK);
-   err = crypto_hash_setkey(auth, key, authkeylen);
-   crypto_aead_set_flags(authenc, crypto_hash_get_flags(auth) 
+   err = crypto_ahash_setkey(auth, key, authkeylen);
+   crypto_aead_set_flags(authenc, crypto_ahash_get_flags(auth) 
   CRYPTO_TFM_RES_MASK);
 
if (err)
@@ -103,40 +110,85 @@ static void authenc_chain(struct scatterlist *head, 
struct scatterlist *sg,
sg_mark_end(head);
 }
 
-static u8 *crypto_authenc_hash(struct aead_request *req, unsigned int flags,
-  struct scatterlist *cipher,
-  unsigned int cryptlen)
+static void crypto_authenc_ahash_geniv_done(
+   struct crypto_async_request *areq, int err)
 {
+   struct aead_request *req = areq-data;
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
-   struct crypto_hash *auth = ctx-auth;
-   struct hash_desc desc = {
-   .tfm = auth,
-   .flags = aead_request_flags(req)  flags,
-   };
-   u8 *hash = aead_request_ctx(req);
-   int err;
-
-   hash = (u8 *)ALIGN((unsigned long)hash + crypto_hash_alignmask(auth), 
-  crypto_hash_alignmask(auth) + 1);
+   struct authenc_ahash_request_ctx *ahreq_ctx = aead_request_ctx(req);
+   struct ahash_request *ahreq = (void *)(ahreq_ctx-tail + ctx-reqoff);
 
-   spin_lock_bh(ctx-auth_lock);
-   err = crypto_hash_init(desc);
if (err)
-   goto auth_unlock;
+   goto out;
+
+   scatterwalk_map_and_copy(ahreq-result, ahreq-src, ahreq-nbytes,
+crypto_aead_authsize(authenc), 1);
+
+out:
+   aead_request_complete(req, err);
+}
+
+static void crypto_authenc_ahash_verify_done(
+   struct crypto_async_request *areq, int err)
+{
+   u8 *ihash;
+   unsigned int authsize;
+   struct ablkcipher_request *abreq;
+   struct aead_request *req = areq-data;
+   struct crypto_aead *authenc = crypto_aead_reqtfm(req);
+   struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
+   struct authenc_ahash_request_ctx *ahreq_ctx = aead_request_ctx(req);
+   struct ahash_request *ahreq = (void *)(ahreq_ctx-tail + ctx-reqoff);
 
-   err = crypto_hash_update(desc, req-assoc, req-assoclen);
if (err)
-   goto auth_unlock;
+   goto out;
+
+   authsize = crypto_aead_authsize(authenc);
+   ihash = ahreq-result + authsize;
+   scatterwalk_map_and_copy(ihash, ahreq-src, ahreq-nbytes, authsize, 0);
+   err = memcmp(ihash, ahreq-result, authsize) ? -EBADMSG: 0;
 
-   err = crypto_hash_update(desc, cipher, cryptlen);
if (err)
-   goto auth_unlock;
+   goto out;
+
+   abreq = aead_request_ctx(req);
+   ablkcipher_request_set_tfm(abreq, ctx-enc);
+   ablkcipher_request_set_callback(abreq, aead_request_flags(req

[RFC] [PATCH 0/7] IPsec: convert to ahash

2009-07-16 Thread Steffen Klassert
This patchset converts IPsec over to the new ahash interface.
The pachset applies to cryptodev-2.6. I was able to test the synchronous
codepaths, the asynchronous ones are untested.

I'm still somewhat unhappy with the ahash version of authenc, but I decided
to post anyway as a base for discussion.

Since the calls to the hash algorithms can now return asynchronous, I'd like
to avoid multiple calls to the hash update functions. I'd rather like to do
all the hashing with one call to crypto_ahash_digest(). As it is, this
requires chaining of all the involved scatterlists. Since we still can't use
sg_chain() to chain up the lists, I added an additional scatterlist entry to
the scatterlist of the assoc data (esp) to be able to chain later in the
crypto layer. To keep compatibility I set the termination bit at the first
entry and remove it later in authenc. In fact to rely on this additional
entry and just to remove the termintation bit later makes me a bit nervous
and I'm not sure whether this is acceptable, so better ideas are very welcome.

Steffen

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [PATCH 1/7] esp: Add an additional scatterlist entry for the assoc data

2009-07-16 Thread Steffen Klassert
To be able to chain all the scatterlists we add an additional
scatterlist entry to the scatterlist of the associated data.
To keep compatibility we set the termination bit at the first
entry. This can be reverted as soon as we can use sg_chain().

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 net/ipv4/esp4.c |   23 +--
 net/ipv6/esp6.c |   25 +++--
 2 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 18bb383..dbb1a33 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -139,14 +139,14 @@ static int esp_output(struct xfrm_state *x, struct 
sk_buff *skb)
goto error;
nfrags = err;
 
-   tmp = esp_alloc_tmp(aead, nfrags + 1);
+   tmp = esp_alloc_tmp(aead, nfrags + 2);
if (!tmp)
goto error;
 
iv = esp_tmp_iv(aead, tmp);
req = esp_tmp_givreq(aead, iv);
asg = esp_givreq_sg(aead, req);
-   sg = asg + 1;
+   sg = asg + 2;
 
/* Fill padding... */
tail = skb_tail_pointer(trailer);
@@ -205,7 +205,16 @@ static int esp_output(struct xfrm_state *x, struct sk_buff 
*skb)
skb_to_sgvec(skb, sg,
 esph-enc_data + crypto_aead_ivsize(aead) - skb-data,
 clen + alen);
-   sg_init_one(asg, esph, sizeof(*esph));
+
+   /*
+* We add an additional scatterlist entry to be able to chain up
+* the scatterlists in the crypto layer. To keep compatibility we
+* set the termination bit at the first entry. This can be removed
+* as soon as as architectures support scatterlist chaining.
+*/
+   sg_init_table(asg, 2);
+   sg_mark_end(asg);
+   sg_set_buf(asg, esph, sizeof(*esph));
 
aead_givcrypt_set_callback(req, 0, esp_output_done, skb);
aead_givcrypt_set_crypt(req, sg, sg, clen, iv);
@@ -347,7 +356,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff 
*skb)
nfrags = err;
 
err = -ENOMEM;
-   tmp = esp_alloc_tmp(aead, nfrags + 1);
+   tmp = esp_alloc_tmp(aead, nfrags + 2);
if (!tmp)
goto out;
 
@@ -355,7 +364,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff 
*skb)
iv = esp_tmp_iv(aead, tmp);
req = esp_tmp_req(aead, iv);
asg = esp_req_sg(aead, req);
-   sg = asg + 1;
+   sg = asg + 2;
 
skb-ip_summed = CHECKSUM_NONE;
 
@@ -366,7 +375,9 @@ static int esp_input(struct xfrm_state *x, struct sk_buff 
*skb)
 
sg_init_table(sg, nfrags);
skb_to_sgvec(skb, sg, sizeof(*esph) + crypto_aead_ivsize(aead), elen);
-   sg_init_one(asg, esph, sizeof(*esph));
+   sg_init_table(asg, 2);
+   sg_mark_end(asg);
+   sg_set_buf(asg, esph, sizeof(*esph));
 
aead_request_set_callback(req, 0, esp_input_done, skb);
aead_request_set_crypt(req, sg, sg, elen, iv);
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 678bb95..6ba707a 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -163,14 +163,14 @@ static int esp6_output(struct xfrm_state *x, struct 
sk_buff *skb)
goto error;
nfrags = err;
 
-   tmp = esp_alloc_tmp(aead, nfrags + 1);
+   tmp = esp_alloc_tmp(aead, nfrags + 2);
if (!tmp)
goto error;
 
iv = esp_tmp_iv(aead, tmp);
req = esp_tmp_givreq(aead, iv);
asg = esp_givreq_sg(aead, req);
-   sg = asg + 1;
+   sg = asg + 2;
 
/* Fill padding... */
tail = skb_tail_pointer(trailer);
@@ -194,7 +194,17 @@ static int esp6_output(struct xfrm_state *x, struct 
sk_buff *skb)
skb_to_sgvec(skb, sg,
 esph-enc_data + crypto_aead_ivsize(aead) - skb-data,
 clen + alen);
-   sg_init_one(asg, esph, sizeof(*esph));
+
+
+   /*
+* We add an additional scatterlist entry to be able to chain up
+* the scatterlists in the crypto layer. To keep compatibility we
+* set the termination bit at the first entry. This can be removed
+* as soon as as architectures support scatterlist chaining.
+*/
+   sg_init_table(asg, 2);
+   sg_mark_end(asg);
+   sg_set_buf(asg, esph, sizeof(*esph));
 
aead_givcrypt_set_callback(req, 0, esp_output_done, skb);
aead_givcrypt_set_crypt(req, sg, sg, clen, iv);
@@ -298,7 +308,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff 
*skb)
}
 
ret = -ENOMEM;
-   tmp = esp_alloc_tmp(aead, nfrags + 1);
+   tmp = esp_alloc_tmp(aead, nfrags + 2);
if (!tmp)
goto out;
 
@@ -306,7 +316,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff 
*skb)
iv = esp_tmp_iv(aead, tmp);
req = esp_tmp_req(aead, iv);
asg = esp_req_sg(aead, req);
-   sg = asg + 1;
+   sg = asg + 2;
 
skb-ip_summed = CHECKSUM_NONE;
 
@@ -317,7 +327,10 @@ static int esp6_input(struct

[RFC] [PATCH 2/7] crypto: authenc - convert to ahash

2009-07-16 Thread Steffen Klassert
This patch converts authenc to the new ahash interface.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/authenc.c |  215 +
 1 files changed, 150 insertions(+), 65 deletions(-)

diff --git a/crypto/authenc.c b/crypto/authenc.c
index 2e16ce0..bd456e3 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -24,23 +24,29 @@
 #include linux/spinlock.h
 
 struct authenc_instance_ctx {
-   struct crypto_spawn auth;
+   struct crypto_ahash_spawn auth;
struct crypto_skcipher_spawn enc;
 };
 
 struct crypto_authenc_ctx {
-   spinlock_t auth_lock;
-   struct crypto_hash *auth;
+   unsigned int reqoff;
+   struct crypto_ahash *auth;
struct crypto_ablkcipher *enc;
 };
 
+struct authenc_ahash_request_ctx {
+   struct scatterlist sg[2];
+   crypto_completion_t complete;
+   char tail[];
+};
+
 static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
 unsigned int keylen)
 {
unsigned int authkeylen;
unsigned int enckeylen;
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
-   struct crypto_hash *auth = ctx-auth;
+   struct crypto_ahash *auth = ctx-auth;
struct crypto_ablkcipher *enc = ctx-enc;
struct rtattr *rta = (void *)key;
struct crypto_authenc_key_param *param;
@@ -64,11 +70,11 @@ static int crypto_authenc_setkey(struct crypto_aead 
*authenc, const u8 *key,
 
authkeylen = keylen - enckeylen;
 
-   crypto_hash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
-   crypto_hash_set_flags(auth, crypto_aead_get_flags(authenc) 
+   crypto_ahash_clear_flags(auth, CRYPTO_TFM_REQ_MASK);
+   crypto_ahash_set_flags(auth, crypto_aead_get_flags(authenc) 
CRYPTO_TFM_REQ_MASK);
-   err = crypto_hash_setkey(auth, key, authkeylen);
-   crypto_aead_set_flags(authenc, crypto_hash_get_flags(auth) 
+   err = crypto_ahash_setkey(auth, key, authkeylen);
+   crypto_aead_set_flags(authenc, crypto_ahash_get_flags(auth) 
   CRYPTO_TFM_RES_MASK);
 
if (err)
@@ -92,6 +98,13 @@ badkey:
 static void authenc_chain(struct scatterlist *head, struct scatterlist *sg,
  int chain)
 {
+   /* 
+* head must be a scatterlist with two entries.
+* We remove a potentially set termination bit
+* on the first enty.
+*/
+   head-page_link = ~0x02;
+
if (chain) {
head-length += sg-length;
sg = scatterwalk_sg_next(sg);
@@ -103,40 +116,85 @@ static void authenc_chain(struct scatterlist *head, 
struct scatterlist *sg,
sg_mark_end(head);
 }
 
-static u8 *crypto_authenc_hash(struct aead_request *req, unsigned int flags,
-  struct scatterlist *cipher,
-  unsigned int cryptlen)
+static void crypto_authenc_ahash_geniv_done(
+   struct crypto_async_request *areq, int err)
 {
+   struct aead_request *req = areq-data;
struct crypto_aead *authenc = crypto_aead_reqtfm(req);
struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
-   struct crypto_hash *auth = ctx-auth;
-   struct hash_desc desc = {
-   .tfm = auth,
-   .flags = aead_request_flags(req)  flags,
-   };
-   u8 *hash = aead_request_ctx(req);
-   int err;
-
-   hash = (u8 *)ALIGN((unsigned long)hash + crypto_hash_alignmask(auth), 
-  crypto_hash_alignmask(auth) + 1);
+   struct authenc_ahash_request_ctx *ahreq_ctx = aead_request_ctx(req);
+   struct ahash_request *ahreq = (void *)(ahreq_ctx-tail + ctx-reqoff);
 
-   spin_lock_bh(ctx-auth_lock);
-   err = crypto_hash_init(desc);
if (err)
-   goto auth_unlock;
+   goto out;
+
+   scatterwalk_map_and_copy(ahreq-result, ahreq-src, ahreq-nbytes,
+crypto_aead_authsize(authenc), 1);
+
+out:
+   aead_request_complete(req, err);
+}
+
+static void crypto_authenc_ahash_verify_done(
+   struct crypto_async_request *areq, int err)
+{
+   u8 *ihash;
+   unsigned int authsize;
+   struct ablkcipher_request *abreq;
+   struct aead_request *req = areq-data;
+   struct crypto_aead *authenc = crypto_aead_reqtfm(req);
+   struct crypto_authenc_ctx *ctx = crypto_aead_ctx(authenc);
+   struct authenc_ahash_request_ctx *ahreq_ctx = aead_request_ctx(req);
+   struct ahash_request *ahreq = (void *)(ahreq_ctx-tail + ctx-reqoff);
 
-   err = crypto_hash_update(desc, req-assoc, req-assoclen);
if (err)
-   goto auth_unlock;
+   goto out;
+
+   authsize = crypto_aead_authsize(authenc);
+   ihash = ahreq-result + authsize;
+   scatterwalk_map_and_copy(ihash, ahreq-src, ahreq

[RFC] [PATCH 5/7] ah6: convert to ahash

2009-07-16 Thread Steffen Klassert
This patch converts ah6 to the new ahash interface.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 net/ipv6/ah6.c |  352 +++-
 1 files changed, 272 insertions(+), 80 deletions(-)

diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 86f42a2..9fb063c 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -24,18 +24,92 @@
  * This file is derived from net/ipv4/ah.c.
  */
 
+#include crypto/hash.h
 #include linux/module.h
 #include net/ip.h
 #include net/ah.h
 #include linux/crypto.h
 #include linux/pfkeyv2.h
-#include linux/spinlock.h
 #include linux/string.h
+#include linux/scatterlist.h
 #include net/icmp.h
 #include net/ipv6.h
 #include net/protocol.h
 #include net/xfrm.h
 
+#define IPV6HDR_BASELEN 8
+
+struct tmp_ext {
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+   struct in6_addr saddr;
+#endif
+   struct in6_addr daddr;
+   char hdrs[0];
+};
+
+struct ah_skb_cb {
+   struct xfrm_skb_cb xfrm;
+   void *tmp;
+};
+
+#define AH_SKB_CB(__skb) ((struct ah_skb_cb *)((__skb)-cb[0]))
+
+static void *ah_alloc_tmp(struct crypto_ahash *ahash, int nfrags,
+ unsigned int size)
+{
+   unsigned int len;
+
+   len = size + crypto_ahash_digestsize(ahash) +
+ (crypto_ahash_alignmask(ahash) 
+  ~(crypto_tfm_ctx_alignment() - 1));
+
+   len = ALIGN(len, crypto_tfm_ctx_alignment());
+
+   len += sizeof(struct ahash_request) + crypto_ahash_reqsize(ahash);
+   len = ALIGN(len, __alignof__(struct scatterlist));
+
+   len += sizeof(struct scatterlist) * nfrags;
+
+   return kmalloc(len, GFP_ATOMIC);
+}
+
+static inline struct tmp_ext *ah_tmp_ext(void *base)
+{
+   return base + IPV6HDR_BASELEN;
+}
+
+static inline u8 *ah_tmp_auth(u8 *tmp, unsigned int offset)
+{
+   return tmp + offset;
+}
+
+static inline u8 *ah_tmp_icv(struct crypto_ahash *ahash, void *tmp,
+unsigned int offset)
+{
+   return PTR_ALIGN((u8 *)tmp + offset, crypto_ahash_alignmask(ahash) + 1);
+}
+
+static inline struct ahash_request *ah_tmp_req(struct crypto_ahash *ahash,
+  u8 *icv)
+{
+   struct ahash_request *req;
+
+   req = (void *)PTR_ALIGN(icv + crypto_ahash_digestsize(ahash),
+   crypto_tfm_ctx_alignment());
+
+   ahash_request_set_tfm(req, ahash);
+
+   return req;
+}
+
+static inline struct scatterlist *ah_req_sg(struct crypto_ahash *ahash,
+struct ahash_request *req)
+{
+   return (void *)ALIGN((unsigned long)(req + 1) +
+crypto_ahash_reqsize(ahash),
+__alignof__(struct scatterlist));
+}
+
 static int zero_out_mutable_opts(struct ipv6_opt_hdr *opthdr)
 {
u8 *opt = (u8 *)opthdr;
@@ -218,24 +292,85 @@ static int ipv6_clear_mutable_options(struct ipv6hdr 
*iph, int len, int dir)
return 0;
 }
 
+static void ah6_output_done(struct crypto_async_request *base, int err)
+{
+   int extlen;
+   u8 *iph_base;
+   u8 *icv;
+   struct sk_buff *skb = base-data;
+   struct xfrm_state *x = skb_dst(skb)-xfrm;
+   struct ah_data *ahp = x-data;
+   struct ipv6hdr *top_iph = ipv6_hdr(skb);
+   struct ip_auth_hdr *ah = ip_auth_hdr(skb);
+   struct tmp_ext *iph_ext;
+
+   extlen = skb_network_header_len(skb) - sizeof(struct ipv6hdr);
+   if (extlen)
+   extlen += sizeof(*iph_ext);
+
+   iph_base = AH_SKB_CB(skb)-tmp;
+   iph_ext = ah_tmp_ext(iph_base);
+   icv = ah_tmp_icv(ahp-ahash, iph_ext, extlen);
+
+   memcpy(ah-auth_data, icv, ahp-icv_trunc_len);
+   memcpy(top_iph, iph_base, IPV6HDR_BASELEN);
+
+   if (extlen) {
+#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
+   memcpy(top_iph-saddr, iph_ext, extlen);
+#else
+   memcpy(top_iph-daddr, iph_ext, extlen);
+#endif
+   }
+
+   err = ah-nexthdr;
+
+   kfree(AH_SKB_CB(skb)-tmp);
+   xfrm_output_resume(skb, err);
+}
+
 static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
 {
int err;
+   int nfrags;
int extlen;
+   u8 *iph_base;
+   u8 *icv;
+   u8 nexthdr;
+   struct sk_buff *trailer;
+   struct crypto_ahash *ahash;
+   struct ahash_request *req;
+   struct scatterlist *sg;
struct ipv6hdr *top_iph;
struct ip_auth_hdr *ah;
struct ah_data *ahp;
-   u8 nexthdr;
-   char tmp_base[8];
-   struct {
-#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
-   struct in6_addr saddr;
-#endif
-   struct in6_addr daddr;
-   char hdrs[0];
-   } *tmp_ext;
+   struct tmp_ext *iph_ext;
+
+   ahp = x-data;
+   ahash = ahp-ahash;
+
+   if ((err = skb_cow_data(skb, 0, trailer))  0

[RFC] [PATCH 6/7] ah: Remove obsolete code

2009-07-16 Thread Steffen Klassert
ah4 and ah6 are converted to ahash now, so we can remove the
code for the obsolete hash algorithm.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 include/net/ah.h |   29 +++--
 1 files changed, 3 insertions(+), 26 deletions(-)

diff --git a/include/net/ah.h b/include/net/ah.h
index 7ac5221..7573a71 100644
--- a/include/net/ah.h
+++ b/include/net/ah.h
@@ -1,44 +1,21 @@
 #ifndef _NET_AH_H
 #define _NET_AH_H
 
-#include linux/crypto.h
-#include net/xfrm.h
+#include linux/skbuff.h
 
 /* This is the maximum truncated ICV length that we know of. */
 #define MAX_AH_AUTH_LEN12
 
+struct crypto_ahash;
+
 struct ah_data
 {
-   u8  *work_icv;
int icv_full_len;
int icv_trunc_len;
 
-   struct crypto_hash  *tfm;
struct crypto_ahash *ahash;
 };
 
-static inline int ah_mac_digest(struct ah_data *ahp, struct sk_buff *skb,
-   u8 *auth_data)
-{
-   struct hash_desc desc;
-   int err;
-
-   desc.tfm = ahp-tfm;
-   desc.flags = 0;
-
-   memset(auth_data, 0, ahp-icv_trunc_len);
-   err = crypto_hash_init(desc);
-   if (unlikely(err))
-   goto out;
-   err = skb_icv_walk(skb, desc, 0, skb-len, crypto_hash_update);
-   if (unlikely(err))
-   goto out;
-   err = crypto_hash_final(desc, ahp-work_icv);
-
-out:
-   return err;
-}
-
 struct ip_auth_hdr;
 
 static inline struct ip_auth_hdr *ip_auth_hdr(const struct sk_buff *skb)
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [PATCH 7/7] xfrm: remove skb_icv_walk

2009-07-16 Thread Steffen Klassert
The last users of skb_icv_walk are converted to ahash now,
so skb_icv_walk is unused and can be removed.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 include/net/xfrm.h   |3 --
 net/xfrm/xfrm_algo.c |   78 --
 2 files changed, 0 insertions(+), 81 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 9e3a3f4..8181541 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1500,9 +1500,6 @@ struct scatterlist;
 typedef int (icv_update_fn_t)(struct hash_desc *, struct scatterlist *,
  unsigned int);
 
-extern int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *tfm,
-   int offset, int len, icv_update_fn_t icv_update);
-
 static inline int xfrm_addr_cmp(xfrm_address_t *a, xfrm_address_t *b,
int family)
 {
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index faf54c6..b393410 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -689,84 +689,6 @@ int xfrm_count_enc_supported(void)
 }
 EXPORT_SYMBOL_GPL(xfrm_count_enc_supported);
 
-/* Move to common area: it is shared with AH. */
-
-int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
-int offset, int len, icv_update_fn_t icv_update)
-{
-   int start = skb_headlen(skb);
-   int i, copy = start - offset;
-   struct sk_buff *frag_iter;
-   struct scatterlist sg;
-   int err;
-
-   /* Checksum header. */
-   if (copy  0) {
-   if (copy  len)
-   copy = len;
-
-   sg_init_one(sg, skb-data + offset, copy);
-
-   err = icv_update(desc, sg, copy);
-   if (unlikely(err))
-   return err;
-
-   if ((len -= copy) == 0)
-   return 0;
-   offset += copy;
-   }
-
-   for (i = 0; i  skb_shinfo(skb)-nr_frags; i++) {
-   int end;
-
-   WARN_ON(start  offset + len);
-
-   end = start + skb_shinfo(skb)-frags[i].size;
-   if ((copy = end - offset)  0) {
-   skb_frag_t *frag = skb_shinfo(skb)-frags[i];
-
-   if (copy  len)
-   copy = len;
-
-   sg_init_table(sg, 1);
-   sg_set_page(sg, frag-page, copy,
-   frag-page_offset + offset-start);
-
-   err = icv_update(desc, sg, copy);
-   if (unlikely(err))
-   return err;
-
-   if (!(len -= copy))
-   return 0;
-   offset += copy;
-   }
-   start = end;
-   }
-
-   skb_walk_frags(skb, frag_iter) {
-   int end;
-
-   WARN_ON(start  offset + len);
-
-   end = start + frag_iter-len;
-   if ((copy = end - offset)  0) {
-   if (copy  len)
-   copy = len;
-   err = skb_icv_walk(frag_iter, desc, offset-start,
-  copy, icv_update);
-   if (unlikely(err))
-   return err;
-   if ((len -= copy) == 0)
-   return 0;
-   offset += copy;
-   }
-   start = end;
-   }
-   BUG_ON(len);
-   return 0;
-}
-EXPORT_SYMBOL_GPL(skb_icv_walk);
-
 #if defined(CONFIG_INET_ESP) || defined(CONFIG_INET_ESP_MODULE) || 
defined(CONFIG_INET6_ESP) || defined(CONFIG_INET6_ESP_MODULE)
 
 void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len)
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 27/35] crypto: cryptd - Switch to template create API

2009-07-15 Thread Steffen Klassert
On Wed, Jul 15, 2009 at 03:16:21PM +0800, Herbert Xu wrote:
 crypto: cryptd - Switch to template create API
 
 This patch changes cryptd to use the template-create function
 instead of alloc in anticipation for the switch to new style
 ahash algorithms.
 
 Signed-off-by: Herbert Xu herb...@gondor.apana.org.au
 ---
 
  crypto/cryptd.c |   53 
 ++--
  crypto/internal.h   |3 --
  include/crypto/algapi.h |3 ++
  3 files changed, 32 insertions(+), 27 deletions(-)
 
 diff --git a/crypto/cryptd.c b/crypto/cryptd.c
 index 6e6722e..ad58f51 100644
 --- a/crypto/cryptd.c
 +++ b/crypto/cryptd.c
 @@ -287,8 +287,9 @@ out_free_inst:
   goto out;
  }
  
 -static struct crypto_instance *cryptd_alloc_blkcipher(
 - struct rtattr **tb, struct cryptd_queue *queue)
 +static int cryptd_create_blkcipher(struct crypto_template *tmpl,
 +struct rtattr **tb,
 +struct cryptd_queue *queue)
  {
   struct cryptd_instance_ctx *ctx;
   struct crypto_instance *inst;
 @@ -298,7 +299,7 @@ static struct crypto_instance *cryptd_alloc_blkcipher(
   alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_BLKCIPHER,
 CRYPTO_ALG_TYPE_MASK);
   if (IS_ERR(alg))
 - return ERR_CAST(alg);
 + return PTR_ERR(alg);
  
   inst = cryptd_alloc_instance(alg, sizeof(*ctx));
   if (IS_ERR(inst))
 @@ -330,14 +331,16 @@ static struct crypto_instance *cryptd_alloc_blkcipher(
   inst-alg.cra_ablkcipher.encrypt = cryptd_blkcipher_encrypt_enqueue;
   inst-alg.cra_ablkcipher.decrypt = cryptd_blkcipher_decrypt_enqueue;
  
 + err = crypto_register_instance(tmpl, inst);
 + if (err) {
 + crypto_drop_spawn(ctx-spawn);
 +out_free_inst:
 + kfree(inst);
 + }
 +
  out_put_alg:
   crypto_mod_put(alg);
 - return inst;
 -
 -out_free_inst:
 - kfree(inst);
 - inst = ERR_PTR(err);
 - goto out_put_alg;
 + return err;

This introduces an uninitialized return value warning. err is not initialized
if cryptd_alloc_instance() fails.

  }
  
  static int cryptd_hash_init_tfm(struct crypto_tfm *tfm)
 @@ -502,8 +505,8 @@ static int cryptd_hash_digest_enqueue(struct 
 ahash_request *req)
   return cryptd_hash_enqueue(req, cryptd_hash_digest);
  }
  
 -static struct crypto_instance *cryptd_alloc_hash(
 - struct rtattr **tb, struct cryptd_queue *queue)
 +static int cryptd_create_hash(struct crypto_template *tmpl, struct rtattr 
 **tb,
 +   struct cryptd_queue *queue)
  {
   struct hashd_instance_ctx *ctx;
   struct crypto_instance *inst;
 @@ -513,7 +516,7 @@ static struct crypto_instance *cryptd_alloc_hash(
  
   salg = shash_attr_alg(tb[1], 0, 0);
   if (IS_ERR(salg))
 - return ERR_CAST(salg);
 + return PTR_ERR(salg);
  
   alg = salg-base;
   inst = cryptd_alloc_instance(alg, sizeof(*ctx));
 @@ -542,34 +545,36 @@ static struct crypto_instance *cryptd_alloc_hash(
   inst-alg.cra_ahash.setkey = cryptd_hash_setkey;
   inst-alg.cra_ahash.digest = cryptd_hash_digest_enqueue;
  
 + err = crypto_register_instance(tmpl, inst);
 + if (err) {
 + crypto_drop_shash(ctx-spawn);
 +out_free_inst:
 + kfree(inst);
 + }
 +
  out_put_alg:
   crypto_mod_put(alg);
 - return inst;
 -
 -out_free_inst:
 - kfree(inst);
 - inst = ERR_PTR(err);
 - goto out_put_alg;
 + return err;

Same here.
I'll send a patch to fix it.

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] cryptd: Fix uninitialized return value

2009-07-15 Thread Steffen Klassert
If cryptd_alloc_instance() fails, the return value is uninitialized.
This patch fixes this by setting the return value.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/cryptd.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index 5dabb7d..fbd26f9 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -303,6 +303,7 @@ static int cryptd_create_blkcipher(struct crypto_template 
*tmpl,
return PTR_ERR(alg);
 
inst = cryptd_alloc_instance(alg, 0, sizeof(*ctx));
+   err = PTR_ERR(inst);
if (IS_ERR(inst))
goto out_put_alg;
 
@@ -522,6 +523,7 @@ static int cryptd_create_hash(struct crypto_template *tmpl, 
struct rtattr **tb,
alg = salg-base;
inst = cryptd_alloc_instance(alg, ahash_instance_headroom(),
 sizeof(*ctx));
+   err = PTR_ERR(inst);
if (IS_ERR(inst))
goto out_put_alg;
 
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 12/35] crypto: padlock - Switch sha to shash

2009-07-15 Thread Steffen Klassert
On Wed, Jul 15, 2009 at 03:16:05PM +0800, Herbert Xu wrote:
 crypto: padlock - Switch sha to shash
 
 This patch converts the padlock-sha implementation to shash.
 In doing so the existing mechanism of storing the data until
 final is no longer viable as we do not have a way of allocating
 data in crypto_shash_init and then reliably freeing it.
 
 This is just as well because a better way of handling the problem
 is to hash everything but the last chunk using normal sha code
 and then provide the intermediate result to the padlock device.
 
 This is good enough because the primary application of padlock-sha
 is IPsec and there the data is laid out in the form of an hmac
 header followed by the rest of the packet.  In essence we can
 provide all the data to the padlock as the hmac header only needs
 to be hashed once.
 
 Signed-off-by: Herbert Xu herb...@gondor.apana.org.au
 ---
 
  drivers/crypto/Kconfig   |2 
  drivers/crypto/padlock-sha.c |  333 
 ---
  2 files changed, 156 insertions(+), 179 deletions(-)
 

Just FYI, I'm getting the following compiler error:

 CC [M]  drivers/crypto/padlock-sha.o
  LD  kernel/built-in.o
/home/klassert/git/linux-sinafe-2.6/drivers/crypto/padlock-sha.c: In function 
'padlock_sha256_finup':
/home/klassert/git/linux-sinafe-2.6/drivers/crypto/padlock-sha.c:166: error: 
impossible register constraint in 'asm'
/home/klassert/git/linux-sinafe-2.6/drivers/crypto/padlock-sha.c:166: error: 
impossible register constraint in 'asm'
/home/klassert/git/linux-sinafe-2.6/drivers/crypto/padlock-sha.c:176: confused 
by earlier errors, bailing out
make[3]: *** [drivers/crypto/padlock-sha.o] Error 1

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 12/35] crypto: padlock - Switch sha to shash

2009-07-15 Thread Steffen Klassert
On Wed, Jul 15, 2009 at 06:30:25PM +0800, Herbert Xu wrote:
 On Wed, Jul 15, 2009 at 12:28:18PM +0200, Steffen Klassert wrote:
 
  Just FYI, I'm getting the following compiler error:
 
 Is this 32-bit or 64-bit?
 

It's 32-bit.
One of my test systems had padlock enabled by chance.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Bogus sha1 implementation in crypto4xx

2009-07-14 Thread Steffen Klassert
On Tue, Jul 14, 2009 at 09:06:00PM +0800, Herbert Xu wrote:
 
 This hasn't caused a problem before because we haven't started
 using ahash yet, apart from tcrypt which is single-threaded.
 I'm currently in the process of converting authenc (hence IPsec)
 across, which means that we will soon rely on the fact that
 you can have multiple hash operations ongoing at once.
 

As I pointed out already, I'm working on converting IPsec to ahash too.
So perhaps we can share the work to do not all the work twice.
I have ahash versions of authenc and ah4/ah6. The authenc ahash version
needs a hack in esp to be able to chain all scatterlist in authenc and I
wanted to look over it again before I post. 

Today I finished with ah4/ah6. This needs still some tests but I could post
these two in the next days if you have not converted them it yet.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Bogus sha1 implementation in crypto4xx

2009-07-14 Thread Steffen Klassert
On Tue, Jul 14, 2009 at 10:43:44PM +0800, Herbert Xu wrote:
 
 Sure, go ahead.  I'm still redoing the ahash infrastructure to
 properly support finup and export/import.
 

Ok, for a moment I thought we both working at the same thing :)
I'll finalize my work and send everything in the next days.

Thanks for clarification.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 7/7] crypto: Add PCLMULQDQ accelerated GHASH implementation

2009-07-07 Thread Steffen Klassert
On Tue, Jul 07, 2009 at 02:00:03PM +0800, Herbert Xu wrote:
 
 Sure, maybe I could take some of your code as is.  My plan for
 hmac is to first convert it to shash, then convert the users to
 ahash, and finally convert hmac itself to ahash.
 
 This way we don't have to convert all the users and hmac in one
 go.
 

I see. authenc is already converted, yesterday I started to look into
ah4/ah6 ipsec. I'll post my hmac version to linux-crypto.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [PATCH 0/3] convert hmac to ahash

2009-07-07 Thread Steffen Klassert
This patchset converts hmac to the new ahash frontend. It has just some
basic tests and is not yet for inclusion.

Steffen
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [PATCH 1/3] crypto: ahash - Add some helper functions

2009-07-07 Thread Steffen Klassert

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 include/crypto/hash.h  |   25 +
 include/crypto/internal/hash.h |5 +
 2 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/include/crypto/hash.h b/include/crypto/hash.h
index d56bb71..bd473a0 100644
--- a/include/crypto/hash.h
+++ b/include/crypto/hash.h
@@ -14,6 +14,7 @@
 #define _CRYPTO_HASH_H
 
 #include linux/crypto.h
+#include crypto/algapi.h
 
 struct shash_desc {
struct crypto_shash *tfm;
@@ -54,6 +55,15 @@ static inline struct crypto_ahash 
*__crypto_ahash_cast(struct crypto_tfm *tfm)
return (struct crypto_ahash *)tfm;
 }
 
+static inline struct crypto_ahash *crypto_spawn_ahash(
+   struct crypto_spawn *spawn)
+{
+   u32 type = CRYPTO_ALG_TYPE_AHASH;
+   u32 mask = CRYPTO_ALG_TYPE_AHASH_MASK;
+
+   return __crypto_ahash_cast(crypto_spawn_tfm(spawn, type, mask));
+}
+
 static inline struct crypto_ahash *crypto_alloc_ahash(const char *alg_name,
  u32 type, u32 mask)
 {
@@ -86,6 +96,11 @@ static inline struct ahash_tfm *crypto_ahash_crt(struct 
crypto_ahash *tfm)
return crypto_ahash_tfm(tfm)-crt_ahash;
 }
 
+static inline unsigned int crypto_ahash_blocksize(struct crypto_ahash *tfm)
+{
+   return crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm));
+}
+
 static inline unsigned int crypto_ahash_digestsize(struct crypto_ahash *tfm)
 {
return crypto_ahash_crt(tfm)-digestsize;
@@ -162,6 +177,16 @@ static inline int crypto_ahash_final(struct ahash_request 
*req)
return crt-final(req);
 }
 
+static inline void ahash_request_complete(struct ahash_request *req, int err)
+{
+   req-base.complete(req-base, err);
+}
+
+static inline u32 ahash_request_flags(struct ahash_request *req)
+{
+   return req-base.flags;
+}
+
 static inline void ahash_request_set_tfm(struct ahash_request *req,
 struct crypto_ahash *tfm)
 {
diff --git a/include/crypto/internal/hash.h b/include/crypto/internal/hash.h
index 82b7056..bbcc076 100644
--- a/include/crypto/internal/hash.h
+++ b/include/crypto/internal/hash.h
@@ -51,6 +51,11 @@ static inline void *crypto_ahash_ctx(struct crypto_ahash 
*tfm)
return crypto_tfm_ctx(tfm-base);
 }
 
+static inline void *crypto_ahash_ctx_aligned(struct crypto_ahash *tfm)
+{
+   return crypto_tfm_ctx_aligned(tfm-base);
+}
+
 static inline struct ahash_alg *crypto_ahash_alg(
struct crypto_ahash *tfm)
 {
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [PATCH 2/3] crypto: ahash - add crypto_ahash_finup

2009-07-07 Thread Steffen Klassert
This patch adds the finup method for ahash. This can be used to
do the last hash update and the hash final together.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/ahash.c |1 +
 crypto/shash.c |   15 +++
 include/crypto/hash.h  |6 ++
 include/linux/crypto.h |2 ++
 4 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/crypto/ahash.c b/crypto/ahash.c
index f347637..c2fbc6d 100644
--- a/crypto/ahash.c
+++ b/crypto/ahash.c
@@ -200,6 +200,7 @@ static int crypto_init_ahash_ops(struct crypto_tfm *tfm, 
u32 type, u32 mask)
crt-init = alg-init;
crt-update = alg-update;
crt-final  = alg-final;
+   crt-finup  = alg-finup; 
crt-digest = alg-digest;
crt-setkey = alg-setkey ? ahash_setkey : ahash_nosetkey;
crt-digestsize = alg-digestsize;
diff --git a/crypto/shash.c b/crypto/shash.c
index 2ccc8b0..3f494fe 100644
--- a/crypto/shash.c
+++ b/crypto/shash.c
@@ -224,6 +224,20 @@ static int shash_async_final(struct ahash_request *req)
return crypto_shash_final(ahash_request_ctx(req), req-result);
 }
 
+static int shash_async_finup(struct ahash_request *req)
+{
+   int err;
+
+   err = shash_async_update(req);
+   if (err)
+   goto out;
+
+   err = shash_async_final(req);
+
+out:
+   return err;
+}
+
 static int shash_async_digest(struct ahash_request *req)
 {
struct scatterlist *sg = req-src;
@@ -292,6 +306,7 @@ static int crypto_init_shash_ops_async(struct crypto_tfm 
*tfm)
crt-init = shash_async_init;
crt-update = shash_async_update;
crt-final  = shash_async_final;
+   crt-finup  = shash_async_finup;
crt-digest = shash_async_digest;
crt-setkey = shash_async_setkey;
 
diff --git a/include/crypto/hash.h b/include/crypto/hash.h
index bd473a0..7c36733 100644
--- a/include/crypto/hash.h
+++ b/include/crypto/hash.h
@@ -177,6 +177,12 @@ static inline int crypto_ahash_final(struct ahash_request 
*req)
return crt-final(req);
 }
 
+static inline int crypto_ahash_finup(struct ahash_request *req)
+{
+   struct ahash_tfm *crt = crypto_ahash_crt(crypto_ahash_reqtfm(req));
+   return crt-finup(req);
+}
+
 static inline void ahash_request_complete(struct ahash_request *req, int err)
 {
req-base.complete(req-base, err);
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index ec29fa2..ab3e4b8 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -225,6 +225,7 @@ struct ahash_alg {
int (*reinit)(struct ahash_request *req);
int (*update)(struct ahash_request *req);
int (*final)(struct ahash_request *req);
+   int (*finup)(struct ahash_request *req);
int (*digest)(struct ahash_request *req);
int (*setkey)(struct crypto_ahash *tfm, const u8 *key,
unsigned int keylen);
@@ -437,6 +438,7 @@ struct ahash_tfm {
int (*init)(struct ahash_request *req);
int (*update)(struct ahash_request *req);
int (*final)(struct ahash_request *req);
+   int (*finup)(struct ahash_request *req);
int (*digest)(struct ahash_request *req);
int (*setkey)(struct crypto_ahash *tfm, const u8 *key,
unsigned int keylen);
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [PATCH 3/3] crypto: hmac - convert to ahash

2009-07-07 Thread Steffen Klassert
This converts hmac to the new ahash frontend.
Also the hashing of the ipaded and opaded key is done now with the
setkey function, this saves some bytes of hashing on each request.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/hmac.c |  471 +
 1 files changed, 340 insertions(+), 131 deletions(-)

diff --git a/crypto/hmac.c b/crypto/hmac.c
index 0ad39c3..c3b2c76 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -18,6 +18,7 @@
 
 #include crypto/internal/hash.h
 #include crypto/scatterwalk.h
+#include linux/completion.h
 #include linux/err.h
 #include linux/init.h
 #include linux/kernel.h
@@ -27,192 +28,400 @@
 #include linux/string.h
 
 struct hmac_ctx {
-   struct crypto_hash *child;
+   struct crypto_ahash *child;
+   struct ahash_request *ipad_req;
+   struct ahash_request *opad_req;
+   unsigned int reqoff;
 };
 
-static inline void *align_ptr(void *p, unsigned int align)
+struct hmac_request_ctx {
+   struct scatterlist sg;
+   char tail[];
+};
+
+struct hmac_setkey_result {
+   int err;
+   struct completion completion;
+};
+
+static inline struct hmac_ctx *hmac_ctx(struct crypto_ahash *tfm)
 {
-   return (void *)ALIGN((unsigned long)p, align);
+   return PTR_ALIGN((void *)crypto_ahash_ctx_aligned(tfm) +
+crypto_ahash_blocksize(tfm) * 2 +
+crypto_ahash_digestsize(tfm),
+crypto_ahash_alignmask(tfm) + 1);
 }
 
-static inline struct hmac_ctx *hmac_ctx(struct crypto_hash *tfm)
+static int hmac_hash_pad(struct ahash_request *req,
+struct hmac_setkey_result *result, u8 *out)
 {
-   return align_ptr(crypto_hash_ctx_aligned(tfm) +
-crypto_hash_blocksize(tfm) * 2 +
-crypto_hash_digestsize(tfm), sizeof(void *));
+   int err;
+
+   err = crypto_ahash_init(req);
+   if (err == -EINPROGRESS || err == -EBUSY) {
+   err = wait_for_completion_interruptible(result-completion);
+   if (!err)
+   err = result-err;
+   }
+
+   if (err)
+   goto out;
+
+   err = crypto_ahash_update(req);
+   if (err == -EINPROGRESS || err == -EBUSY) {
+   err = wait_for_completion_interruptible(result-completion);
+   if (!err)
+   err = result-err;
+   }
+
+   if (err)
+   goto out;
+
+   crypto_ahash_export(req, out);
+
+out:
+   return err;
 }
 
-static int hmac_setkey(struct crypto_hash *parent,
+static void hmac_setkey_done(struct crypto_async_request *req, int err)
+{
+   struct hmac_setkey_result *result = req-data;
+
+   if (err == -EINPROGRESS)
+   return;
+
+   result-err = err;
+   complete(result-completion);
+}
+
+static int hmac_setkey(struct crypto_ahash *parent,
   const u8 *inkey, unsigned int keylen)
 {
-   int bs = crypto_hash_blocksize(parent);
-   int ds = crypto_hash_digestsize(parent);
-   char *ipad = crypto_hash_ctx_aligned(parent);
-   char *opad = ipad + bs;
-   char *digest = opad + bs;
-   struct hmac_ctx *ctx = align_ptr(digest + ds, sizeof(void *));
-   struct crypto_hash *tfm = ctx-child;
-   unsigned int i;
+   int err, i;
+   int bs = crypto_ahash_blocksize(parent);
+   int ds = crypto_ahash_digestsize(parent);
+   struct hmac_ctx *ctx = crypto_ahash_ctx(parent);
+   struct {
+   u8 ipad[bs];
+   u8 opad[bs];
+   u8 digest[ds];
+   struct hmac_setkey_result result;
+   struct scatterlist sg;
+   struct ahash_request req;
 
-   if (keylen  bs) {
-   struct hash_desc desc;
-   struct scatterlist tmp;
-   int tmplen;
-   int err;
+   } *data;
 
-   desc.tfm = tfm;
-   desc.flags = crypto_hash_get_flags(parent);
-   desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+   err = -ENOMEM;
+   data = kzalloc(sizeof(*data) + crypto_ahash_reqsize(parent) +
+  bs * 2 + ds, GFP_KERNEL);
 
-   err = crypto_hash_init(desc);
-   if (err)
-   return err;
+   if (!data)
+   goto out;
 
-   tmplen = bs * 2 + ds;
-   sg_init_one(tmp, ipad, tmplen);
+   init_completion(data-result.completion);
 
-   for (; keylen  tmplen; inkey += tmplen, keylen -= tmplen) {
-   memcpy(ipad, inkey, tmplen);
-   err = crypto_hash_update(desc, tmp, tmplen);
-   if (err)
-   return err;
-   }
+   ahash_request_set_tfm(data-req, ctx-child);
+   ahash_request_set_callback(data-req, CRYPTO_TFM_REQ_MAY_BACKLOG

Re: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface

2009-06-29 Thread Steffen Klassert
On Thu, Jun 25, 2009 at 02:51:12PM +0800, Herbert Xu wrote:
 
 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.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH 3/5] eseqiv: Add support for aead algorithms

2009-06-29 Thread Steffen Klassert
On Thu, Jun 25, 2009 at 06:46:02PM +0800, Herbert Xu wrote:
 On Mon, Jun 08, 2009 at 09:10:46AM +0200, Steffen Klassert wrote:
  This adds eseqiv support for aead algorithms, this is usefull
  for aead algorithms that need eseqiv as it's default IV generator.
  
  Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
 
 I'm going to change the default sync geniv to eseqiv for SMP.
 That should render this patch unnecessary, right?
 

Right, this would reduce the patchset to the padata and the pcrypt
patch. I'll strip the patchset to these two patches as soon as I see
your patch applied to cryptodev-2.6.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] padata: generic interface for parallel processing

2009-06-29 Thread Steffen Klassert
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.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 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

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 2721f07..4aad58f 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -344,7 +344,8 @@ enum
TASKLET_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
 };
diff --git a/include/linux/padata.h b/include/linux/padata.h
new file mode 100644
index 000..469359f
--- /dev/null
+++ b/include/linux/padata.h
@@ -0,0 +1,116 @@
+/*
+ * padata.h - header for the padata parallelization interface
+ *
+ * Copyright (C) 2008, 2009 secunet Security Networks AG
+ * Copyright (C) 2008, 2009 Steffen Klassert steffen.klass...@secunet.com
+ *
+ * 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.
+ */
+
+#ifndef PADATA_H
+#define PADATA_H
+
+#include linux/interrupt.h
+#include linux/smp.h
+#include linux/list.h
+
+enum
+{
+   NO_PADATA=0,
+   AEAD_ENC_PADATA,
+   AEAD_DEC_PADATA,
+   NR_PADATA
+};
+
+struct padata_priv {
+   struct list_headlist;
+   struct call_single_data csd;
+   int cb_cpu;
+   int seq_nr;
+   unsigned intnr;
+   int info;
+   void(*parallel)(struct padata_priv *padata);
+   void(*serial)(struct padata_priv *padata);
+};
+
+struct padata_queue {
+   struct list_headlist;
+   atomic_tnum_obj;
+   int cpu_index;
+   spinlock_t  lock;
+};
+
+struct parallel_data {
+   struct work_struct  work;
+   struct padata_queue *queue;
+   atomic_tseq_nr;
+   atomic_tqueued_objects;
+   cpumask_t   cpu_map;
+   cpumask_t   new_cpu_map;
+   u8  flags;
+#definePADATA_INIT 1
+#definePADATA_FLUSH_HARD   2
+#definePADATA_RESET_IN_PROGRESS4
+   spinlock_t  lock;
+};
+
+#ifdef CONFIG_USE_GENERIC_SMP_HELPERS
+extern void __init padata_init(unsigned int nr, cpumask_t cpu_map);
+extern void padata_dont_wait(unsigned int nr, struct padata_priv *padata);
+extern int padata_do_parallel(unsigned int softirq_nr, unsigned int nr,
+ struct padata_priv *padata, int cb_cpu);
+extern int padata_do_serial(unsigned int nr, struct padata_priv *padata);
+extern cpumask_t padata_get_cpumap(unsigned int nr);
+extern void padata_set_cpumap(unsigned int nr, cpumask_t cpu_map);
+extern void padata_add_cpu(unsigned int nr, int cpu);
+extern void padata_remove_cpu(unsigned int nr, int cpu);
+extern void padata_start(unsigned int nr);
+extern void padata_stop(unsigned int nr);
+#else
+static inline void padata_init(unsigned int nr,cpumask_t cpu_map)
+{
+}
+static inline void padata_dont_wait(unsigned int nr, struct padata_priv 
*padata)
+{
+}
+static inline int padata_do_parallel(unsigned int softirq_nr, unsigned int nr,
+struct padata_priv *padata, int cb_cpu)
+{
+   return 0;
+}
+static inline int padata_do_serial(unsigned int nr, struct padata_priv *padata)
+{
+   return 0;
+}
+static inline cpumask_t padata_get_cpumap(unsigned int nr)
+{
+   return cpu_online_map;
+}
+static inline void padata_set_cpumap(unsigned int nr, cpumask_t cpu_map)
+{
+}
+static inline padata_add_cpu(unsigned int nr, int cpu)
+{
+}
+static inline padata_remove_cpu(unsigned int nr, int cpu)
+{
+}
+static

[PATCH 2/2] pcrypt: Add pcrypt crypto parallelization wrapper

2009-06-29 Thread Steffen Klassert
This 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.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 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

diff --git a/crypto/Kconfig b/crypto/Kconfig
index f2002d8..1a3b277 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -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
 
diff --git a/crypto/Makefile b/crypto/Makefile
index 673d9f7..84b9d17 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -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
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
new file mode 100644
index 000..2debf8b
--- /dev/null
+++ b/crypto/pcrypt.c
@@ -0,0 +1,411 @@
+/*
+ * pcrypt - Parallel crypto wrapper.
+ *
+ * Copyright (C) 2009 secunet Security Networks AG
+ * Copyright (C) 2009 Steffen Klassert steffen.klass...@secunet.com
+ *
+ * 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 crypto/algapi.h
+#include crypto/internal/aead.h
+#include linux/err.h
+#include linux/init.h
+#include linux/module.h
+#include linux/slab.h
+#include crypto/pcrypt.h
+
+struct pcrypt_instance_ctx {
+   struct crypto_spawn spawn;
+   unsigned int tfm_count;
+};
+
+struct pcrypt_aead_ctx {
+   struct crypto_aead *child;
+   unsigned int tfm_nr;
+};
+
+static int pcrypt_do_parallel(struct padata_priv *padata, unsigned int tfm_nr,
+ unsigned int softirq, unsigned int padata_nr)
+{
+   unsigned int cpu, cpu_index, num_cpus, cb_cpu;
+   cpumask_t cpu_map;
+
+   cpu_map = padata_get_cpumap(padata_nr);
+   num_cpus = cpus_weight(cpu_map);
+
+   cpu_index = tfm_nr % num_cpus;
+
+   cb_cpu = first_cpu(cpu_map);
+   for (cpu = 0; cpu  cpu_index; cpu++)
+   cb_cpu = next_cpu(cb_cpu, cpu_map);
+
+   return padata_do_parallel(softirq, padata_nr, padata, cb_cpu);
+}
+
+static int pcrypt_aead_setkey(struct crypto_aead *parent,
+ const u8 *key, unsigned int keylen)
+{
+   struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent);
+
+   return crypto_aead_setkey(ctx-child, key, keylen);
+}
+
+static int pcrypt_aead_setauthsize(struct crypto_aead *parent,
+  unsigned int authsize)
+{
+   struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent);
+
+   return crypto_aead_setauthsize(ctx-child, authsize);
+}
+
+static void pcrypt_aead_serial(struct padata_priv *padata)
+{
+   struct pcrypt_request *preq = pcrypt_padata_request(padata);
+   struct aead_request *req = pcrypt_request_ctx(preq);
+
+   aead_request_complete(req-base.data, padata-info);
+}
+
+static void pcrypt_aead_giv_serial(struct padata_priv *padata)
+{
+   struct pcrypt_request *preq = pcrypt_padata_request(padata);
+   struct aead_givcrypt_request *req = pcrypt_request_ctx(preq);
+
+   aead_request_complete(req-areq.base.data, padata-info);
+}
+
+static void pcrypt_aead_done(struct crypto_async_request *areq, int err)
+{
+   struct aead_request *req

Re: [PATCH] tcrypt: Test algorithms by name

2009-06-23 Thread Steffen Klassert
On Fri, Jun 19, 2009 at 08:38:15PM +0800, Herbert Xu wrote:
  
  That was quick :)
  
  Patch applied.  Thanks a lot Steffen!
 
 BTW, I added this on top so that modprobe doesn't complain about
 the return code:
 

Ugh, I was a bit too quick. Thanks for fixing this up!
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH 2/5] pcrypt: Add pcrypt crypto parallelization wrapper

2009-06-23 Thread Steffen Klassert
On Tue, Jun 23, 2009 at 05:18:52PM +0800, Herbert Xu wrote:
 On Tue, Jun 23, 2009 at 11:14:29AM +0200, Steffen Klassert wrote:
 
  I posted some numbers for the actual softirq based version with the
  first patchset, see:
  http://www.mail-archive.com/linux-crypto@vger.kernel.org/msg03035.html
 
 Thanks, but I was thinking of softirq numbers vs. workqueue numbers.
 

I have just some numbers from a network based parallelization
that uses threads. So it's probaply not really comparable to
the pcrypt version. To compare the pcrypt version, we would need a
thread based padata version. If you think that it is needed I could
care about this as soon as I finished the ahash work.

Anyway, here are numbers for the network based versions:

I did forwarding tests with the thread version and two quad core machines
(Intel Core 2 Quad Q6600):

linux-2.6.25.2 + thread based (network) parallelization
Packetsize: 1420 byte
Encryption: aes192-sha1
Unidirectional throughput: 660 Mbit/s (tcp)

After rewriting this to use remote softirqs I've got with the same
environment:

linux-2.6-git (Dec 01, 2008) + softirq based (network) parallelization
Packetsize: 1420 byte
Encryption: aes192-sha1
Unidirectional throughput: 910 Mbit/s (tcp)
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] tcrypt: Test algorithms by name

2009-06-19 Thread Steffen Klassert
This adds the 'alg' module parameter to be able to test an
algorithm by name. If the algorithm type is not ad-hoc
clear for a algorithm (e.g. pcrypt, cryptd) it is possilbe
to set the algorithm type with the 'type' module parameter.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/tcrypt.c |   15 ++-
 1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index d59ba50..dfeec0c 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -45,6 +45,8 @@
  */
 static unsigned int sec;
 
+static char *alg = NULL;
+static u32 type;
 static int mode;
 static char *tvmem[TVMEMSIZE];
 
@@ -885,6 +887,11 @@ static int do_test(int m)
return ret;
 }
 
+static int do_alg_test(const char *alg, u32 type)
+{
+   return crypto_has_alg(alg, type, CRYPTO_ALG_TYPE_MASK);
+}
+
 static int __init tcrypt_mod_init(void)
 {
int err = -ENOMEM;
@@ -896,7 +903,11 @@ static int __init tcrypt_mod_init(void)
goto err_free_tv;
}
 
-   err = do_test(mode);
+   if (alg)
+   err = do_alg_test(alg, type);
+   else
+   err = do_test(mode);
+
if (err) {
printk(KERN_ERR tcrypt: one or more tests failed!\n);
goto err_free_tv;
@@ -928,6 +939,8 @@ static void __exit tcrypt_mod_fini(void) { }
 module_init(tcrypt_mod_init);
 module_exit(tcrypt_mod_fini);
 
+module_param(alg, charp, 0);
+module_param(type, uint, 0);
 module_param(mode, int, 0);
 module_param(sec, uint, 0);
 MODULE_PARM_DESC(sec, Length in seconds of speed tests 
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface

2009-06-08 Thread Steffen Klassert
On Mon, Jun 08, 2009 at 03:28:08PM +1000, Herbert Xu wrote:
 On Fri, Jun 05, 2009 at 11:34:30AM +0200, Steffen Klassert wrote:
 
  In pcrypt_alloc_instance() I do
  inst-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 do 
  inst-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.
 
 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.

 
 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.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [PATCH 1/5] padata: generic interface for parallel processing

2009-06-08 Thread Steffen Klassert
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.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 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

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 91bb76f..a17679c 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -338,7 +338,8 @@ enum
TASKLET_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
 };
diff --git a/include/linux/padata.h b/include/linux/padata.h
new file mode 100644
index 000..469359f
--- /dev/null
+++ b/include/linux/padata.h
@@ -0,0 +1,116 @@
+/*
+ * padata.h - header for the padata parallelization interface
+ *
+ * Copyright (C) 2008, 2009 secunet Security Networks AG
+ * Copyright (C) 2008, 2009 Steffen Klassert steffen.klass...@secunet.com
+ *
+ * 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.
+ */
+
+#ifndef PADATA_H
+#define PADATA_H
+
+#include linux/interrupt.h
+#include linux/smp.h
+#include linux/list.h
+
+enum
+{
+   NO_PADATA=0,
+   AEAD_ENC_PADATA,
+   AEAD_DEC_PADATA,
+   NR_PADATA
+};
+
+struct padata_priv {
+   struct list_headlist;
+   struct call_single_data csd;
+   int cb_cpu;
+   int seq_nr;
+   unsigned intnr;
+   int info;
+   void(*parallel)(struct padata_priv *padata);
+   void(*serial)(struct padata_priv *padata);
+};
+
+struct padata_queue {
+   struct list_headlist;
+   atomic_tnum_obj;
+   int cpu_index;
+   spinlock_t  lock;
+};
+
+struct parallel_data {
+   struct work_struct  work;
+   struct padata_queue *queue;
+   atomic_tseq_nr;
+   atomic_tqueued_objects;
+   cpumask_t   cpu_map;
+   cpumask_t   new_cpu_map;
+   u8  flags;
+#definePADATA_INIT 1
+#definePADATA_FLUSH_HARD   2
+#definePADATA_RESET_IN_PROGRESS4
+   spinlock_t  lock;
+};
+
+#ifdef CONFIG_USE_GENERIC_SMP_HELPERS
+extern void __init padata_init(unsigned int nr, cpumask_t cpu_map);
+extern void padata_dont_wait(unsigned int nr, struct padata_priv *padata);
+extern int padata_do_parallel(unsigned int softirq_nr, unsigned int nr,
+ struct padata_priv *padata, int cb_cpu);
+extern int padata_do_serial(unsigned int nr, struct padata_priv *padata);
+extern cpumask_t padata_get_cpumap(unsigned int nr);
+extern void padata_set_cpumap(unsigned int nr, cpumask_t cpu_map);
+extern void padata_add_cpu(unsigned int nr, int cpu);
+extern void padata_remove_cpu(unsigned int nr, int cpu);
+extern void padata_start(unsigned int nr);
+extern void padata_stop(unsigned int nr);
+#else
+static inline void padata_init(unsigned int nr,cpumask_t cpu_map)
+{
+}
+static inline void padata_dont_wait(unsigned int nr, struct padata_priv 
*padata)
+{
+}
+static inline int padata_do_parallel(unsigned int softirq_nr, unsigned int nr,
+struct padata_priv *padata, int cb_cpu)
+{
+   return 0;
+}
+static inline int padata_do_serial(unsigned int nr, struct padata_priv *padata)
+{
+   return 0;
+}
+static inline cpumask_t padata_get_cpumap(unsigned int nr)
+{
+   return cpu_online_map;
+}
+static inline void padata_set_cpumap(unsigned int nr, cpumask_t cpu_map)
+{
+}
+static inline padata_add_cpu(unsigned int nr, int cpu)
+{
+}
+static inline padata_remove_cpu(unsigned int nr, int cpu)
+{
+}
+static

[RFC] [PATCH 2/5] pcrypt: Add pcrypt crypto parallelization wrapper

2009-06-08 Thread Steffen Klassert
This 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.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/Kconfig|   13 ++
 crypto/Makefile   |2 +
 crypto/pcrypt.c   |  413 +
 crypto/pcrypt_core.c  |  125 ++
 include/crypto/pcrypt.h   |   85 +
 include/linux/interrupt.h |2 +
 6 files changed, 640 insertions(+), 0 deletions(-)
 create mode 100644 crypto/pcrypt.c
 create mode 100644 crypto/pcrypt_core.c
 create mode 100644 include/crypto/pcrypt.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 74d0e62..b05fc95 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -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 engine (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
 
diff --git a/crypto/Makefile b/crypto/Makefile
index 673d9f7..84b9d17 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -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
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
new file mode 100644
index 000..cc960df
--- /dev/null
+++ b/crypto/pcrypt.c
@@ -0,0 +1,413 @@
+/*
+ * pcrypt - Parallel crypto wrapper.
+ *
+ * Copyright (C) 2009 secunet Security Networks AG
+ * Copyright (C) 2009 Steffen Klassert steffen.klass...@secunet.com
+ *
+ * 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 crypto/algapi.h
+#include crypto/internal/aead.h
+#include linux/err.h
+#include linux/init.h
+#include linux/module.h
+#include linux/slab.h
+#include crypto/pcrypt.h
+
+struct pcrypt_instance_ctx {
+   struct crypto_spawn spawn;
+   unsigned int tfm_count;
+};
+
+struct pcrypt_aead_ctx {
+   struct crypto_aead *child;
+   unsigned int tfm_nr;
+};
+
+static int pcrypt_do_parallel(struct padata_priv *padata, unsigned int tfm_nr,
+ unsigned int softirq, unsigned int padata_nr)
+{
+   unsigned int cpu, cpu_index, num_cpus, cb_cpu;
+   cpumask_t cpu_map;
+
+   cpu_map = padata_get_cpumap(padata_nr);
+   num_cpus = cpus_weight(cpu_map);
+
+   cpu_index = tfm_nr % num_cpus;
+
+   cb_cpu = first_cpu(cpu_map);
+   for (cpu = 0; cpu  cpu_index; cpu++)
+   cb_cpu = next_cpu(cb_cpu, cpu_map);
+
+   return padata_do_parallel(softirq, padata_nr, padata, cb_cpu);
+}
+
+static int pcrypt_aead_setkey(struct crypto_aead *parent,
+ const u8 *key, unsigned int keylen)
+{
+   struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent);
+
+   return crypto_aead_setkey(ctx-child, key, keylen);
+}
+
+static int pcrypt_aead_setauthsize(struct crypto_aead *parent,
+  unsigned int authsize)
+{
+   struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent);
+
+   return crypto_aead_setauthsize(ctx-child, authsize);
+}
+
+static void pcrypt_aead_serial(struct padata_priv *padata)
+{
+   struct pcrypt_request *preq = pcrypt_padata_request(padata);
+   struct aead_request *req = pcrypt_request_ctx(preq);
+
+   aead_request_complete(req-base.data, padata-info);
+}
+
+static void pcrypt_aead_giv_serial(struct padata_priv *padata)
+{
+   struct pcrypt_request *preq = pcrypt_padata_request(padata);
+   struct aead_givcrypt_request *req = pcrypt_request_ctx(preq);
+
+   aead_request_complete(req-areq.base.data, padata-info);
+}
+
+static void pcrypt_aead_done(struct crypto_async_request *areq, int err)
+{
+   struct aead_request

[RFC] [PATCH 4/5] authenc: Check if the IV is already added to the scatterlist

2009-06-08 Thread Steffen Klassert
aead eseqiv needs to add the IV to the scatterlist itself.
So check if the IV is already contained in the scatterlist
and add it just if it is not already there.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/authenc.c |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/crypto/authenc.c b/crypto/authenc.c
index 5793b64..e11029a 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -157,15 +157,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);
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [PATCH 5/5] tcrypt: Test algorithms by name

2009-06-08 Thread Steffen Klassert
This adds the 'alg' module parameter to be able to test an
algorithm by name. If the algorithm type is not ad-hoc
clear for a algorithm (e.g. pcrypt, cryptd) it is possilbe
to set the algorithm type with the 'type' module parameter.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/tcrypt.c |   14 +-
 1 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index c3c9124..9d5b33c 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -44,6 +44,8 @@
  */
 static unsigned int sec;
 
+static char *alg = NULL;
+static u32 type;
 static int mode;
 static char *tvmem[TVMEMSIZE];
 
@@ -864,6 +866,11 @@ static void do_test(int m)
}
 }
 
+static void do_alg_test(const char *alg, u32 type)
+{
+   crypto_has_alg(alg, type, CRYPTO_ALG_TYPE_MASK);
+}
+
 static int __init tcrypt_mod_init(void)
 {
int err = -ENOMEM;
@@ -875,7 +882,10 @@ static int __init tcrypt_mod_init(void)
goto err_free_tv;
}
 
-   do_test(mode);
+   if (alg)
+   do_alg_test(alg, type);
+   else
+   do_test(mode);
 
/* We intentionaly return -EAGAIN to prevent keeping
 * the module. It does all its work from init()
@@ -901,6 +911,8 @@ static void __exit tcrypt_mod_fini(void) { }
 module_init(tcrypt_mod_init);
 module_exit(tcrypt_mod_fini);
 
+module_param(alg, charp, 0);
+module_param(type, uint, 0);
 module_param(mode, int, 0);
 module_param(sec, uint, 0);
 MODULE_PARM_DESC(sec, Length in seconds of speed tests 
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface

2009-06-05 Thread Steffen Klassert
On Wed, Jun 03, 2009 at 09:59:31PM +1000, Herbert Xu wrote:
 
 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.
 

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.

 
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 56c62e2..2492e6c 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -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);
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface

2009-06-03 Thread Steffen Klassert
On Tue, Jun 02, 2009 at 07:28:15PM +1000, Herbert Xu wrote:
 On Tue, Jun 02, 2009 at 11:21:51AM +0200, Steffen Klassert wrote:
  
  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.

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?

 
 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.
 
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface

2009-06-03 Thread Steffen Klassert
On Wed, Jun 03, 2009 at 07:40:50PM +1000, Herbert Xu wrote:
 
 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?

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH 2/5] aead: Add generic aead wrapper interface

2009-06-02 Thread Steffen Klassert
On Tue, Jun 02, 2009 at 01:50:41PM +1000, Herbert Xu wrote:
 
 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.
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [PATCH 0/5] Parallel IPsec v3

2009-05-13 Thread Steffen Klassert
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
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [PATCH 3/5] pcrypt: Add pcrypt crypto parallelization wrapper

2009-05-13 Thread Steffen Klassert
This 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.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 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

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 74d0e62..36da74f 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -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
 
diff --git a/crypto/Makefile b/crypto/Makefile
index 673d9f7..84b9d17 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -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
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
new file mode 100644
index 000..32e88fb
--- /dev/null
+++ b/crypto/pcrypt.c
@@ -0,0 +1,353 @@
+/*
+ * pcrypt - Parallel crypto wrapper.
+ *
+ * Copyright (C) 2009 secunet Security Networks AG
+ * Copyright (C) 2009 Steffen Klassert steffen.klass...@secunet.com
+ *
+ * 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 crypto/algapi.h
+#include crypto/internal/aead.h
+#include linux/err.h
+#include linux/init.h
+#include linux/module.h
+#include linux/slab.h
+#include crypto/pcrypt.h
+
+struct pcrypt_instance_ctx {
+   struct crypto_spawn spawn;
+   unsigned int tfm_count;
+};
+
+struct pcrypt_aead_ctx {
+   unsigned int tfm_nr;
+};
+
+static int pcrypt_do_parallel(struct padata_priv *padata, unsigned int tfm_nr,
+ unsigned int softirq, unsigned int padata_nr)
+{
+   unsigned int cpu, cpu_index, num_cpus, cb_cpu;
+   cpumask_t cpu_map;
+
+   cpu_map = padata_get_cpumap(padata_nr);
+   num_cpus = cpus_weight(cpu_map);
+
+   cpu_index = tfm_nr % num_cpus;
+
+   cb_cpu = first_cpu(cpu_map);
+   for (cpu = 0; cpu  cpu_index; cpu++)
+   cb_cpu = next_cpu(cb_cpu, cpu_map);
+
+   return padata_do_parallel(softirq, padata_nr, padata, cb_cpu);
+}
+
+static int pcrypt_aead_setkey(struct crypto_aead *parent,
+ const u8 *key, unsigned int keylen)
+{
+   struct crypto_aead *child = crypto_aead_crt(parent)-base;
+
+   return crypto_aead_setkey(child, key, keylen);
+}
+
+static int pcrypt_aead_setauthsize(struct crypto_aead *parent,
+  unsigned int authsize)
+{
+   struct crypto_aead *child = crypto_aead_crt(parent)-base;
+
+   return crypto_aead_setauthsize(child, authsize);
+}
+
+static void pcrypt_aead_serial(struct padata_priv *padata)
+{
+   struct pcrypt_request *preq = pcrypt_padata_request(padata);
+   struct aead_request *req = pcrypt_request_ctx(preq);
+
+   aead_request_complete(req-base.data, padata-info);
+}
+
+static void pcrypt_aead_giv_serial(struct padata_priv *padata)
+{
+   struct pcrypt_request *preq = pcrypt_padata_request(padata);
+   struct aead_givcrypt_request *req = pcrypt_request_ctx(preq);
+
+   aead_request_complete(req-areq.base.data, padata-info);
+}
+
+static void pcrypt_aead_done(struct crypto_async_request *areq, int err)
+{
+   struct aead_request

[RFC] [PATCH 4/5] eseqiv: Add support for aead algorithms

2009-05-13 Thread Steffen Klassert
This adds eseqiv support for aead algorithms, this is usefull
for aead wrappers that need eseqiv as it's default IV generator.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/eseqiv.c|  248 +---
 include/linux/crypto.h |1 +
 2 files changed, 235 insertions(+), 14 deletions(-)

diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c
index 2a342c8..b6185f4 100644
--- a/crypto/eseqiv.c
+++ b/crypto/eseqiv.c
@@ -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

Re: [RFC] [PATCH v2 2/4] pcrypt: Add pcrypt crypto parallelization engine

2009-04-28 Thread Steffen Klassert
On Mon, Apr 27, 2009 at 04:56:20PM +0800, Herbert Xu wrote:
 On Fri, Apr 24, 2009 at 12:27:20PM +0200, Steffen Klassert wrote:
 
  +   alg = crypto_get_attr_alg(tb, algt-type,
  + (algt-mask  CRYPTO_ALG_TYPE_MASK)
  + | CRYPTO_ALG_PCRYPT);
 
 Do you really need to exclude pcrypt algorithms here? If the user
 wants to added another layer of pcrypt then we should obey.
 

I don't need to exclude it. I just wanted to avoid another layer
of pcrypt here because it does not make too much sense to parallelize
a second time. If the aead algorithm is already parallel it would just
add overhead if we parallelize an underlying algorithm too.
Anyway, I would not mind to allow more than one pcrypt layer.

Steffen
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH v2 2/4] pcrypt: Add pcrypt crypto parallelization engine

2009-04-28 Thread Steffen Klassert
On Tue, Apr 28, 2009 at 02:31:29PM +0800, Herbert Xu wrote:
 
 I thought so.  The system is certainly not going to automatically
 construct a second pcrypt algorithm once one exists.  So I think
 we can just remove this bit.
 

Ok, so I will remove it in the next version.

Steffen
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH v2 3/4] xfrm: Add a netlink attribute for software crypto accelerators

2009-04-28 Thread Steffen Klassert
On Mon, Apr 27, 2009 at 04:53:46PM +0800, Herbert Xu wrote:
 
 While this should work for pcrypt, I'd like this to be solved
 more generally.  The crux of the issue is that we can't specify
 an arbitrary implementation of a given algorithm.  So the obvious
 solution is to specify the driver name along with the algorithm
 name.

So how general should it be? For the moment I would see pcrypt and maybe
cryptd as possible candidates to use this mechanism. I'm just wondering
if it is worth to set up a list of crypto templates that can be choosen
from userspace, similar to the xfrm_algo_list.

 
 This is in fact pretty much what you've done, but I'd just like
 it to be generalised.  In particular, instead of having just a
 single name per SA, we should allow one to be set for each algorithm
 type.

Just to get you right, do you think about adding a netlink attribute for
each algorithm type?

 
 On another note, I don't expect this to be the primary mechanism
 for activating parallel processing.  Doing it manually on each
 SA is just painful.  This should be used for testing or when you
 want to specify it for a subset of SAs only.
 
 When the admin wants to turn the entire system over to pcrypt,
 it should be done at the crypto layer, by simply registering
 the pcrypt version of the algorithm in question, and having it
 as the default implementation of that algorithm.

That's not really clear to me how to let the user register the pcrypt
version of the algorithm, so what's the desired way do this.

 
 In fact, this mechanism should then be able to allow specific
 SAs to not use parallel processing, which means that it should
 definitely not be called accl :)
 

Yes, I think I'll find a better name :)

Steffen
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [PATCH v2 1/4] padata: generic interface for parallel processing

2009-04-24 Thread Steffen Klassert
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.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 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

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 91bb76f..a17679c 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -338,7 +338,8 @@ enum
TASKLET_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
 };
diff --git a/include/linux/padata.h b/include/linux/padata.h
new file mode 100644
index 000..469359f
--- /dev/null
+++ b/include/linux/padata.h
@@ -0,0 +1,116 @@
+/*
+ * padata.h - header for the padata parallelization interface
+ *
+ * Copyright (C) 2008, 2009 secunet Security Networks AG
+ * Copyright (C) 2008, 2009 Steffen Klassert steffen.klass...@secunet.com
+ *
+ * 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.
+ */
+
+#ifndef PADATA_H
+#define PADATA_H
+
+#include linux/interrupt.h
+#include linux/smp.h
+#include linux/list.h
+
+enum
+{
+   NO_PADATA=0,
+   AEAD_ENC_PADATA,
+   AEAD_DEC_PADATA,
+   NR_PADATA
+};
+
+struct padata_priv {
+   struct list_headlist;
+   struct call_single_data csd;
+   int cb_cpu;
+   int seq_nr;
+   unsigned intnr;
+   int info;
+   void(*parallel)(struct padata_priv *padata);
+   void(*serial)(struct padata_priv *padata);
+};
+
+struct padata_queue {
+   struct list_headlist;
+   atomic_tnum_obj;
+   int cpu_index;
+   spinlock_t  lock;
+};
+
+struct parallel_data {
+   struct work_struct  work;
+   struct padata_queue *queue;
+   atomic_tseq_nr;
+   atomic_tqueued_objects;
+   cpumask_t   cpu_map;
+   cpumask_t   new_cpu_map;
+   u8  flags;
+#definePADATA_INIT 1
+#definePADATA_FLUSH_HARD   2
+#definePADATA_RESET_IN_PROGRESS4
+   spinlock_t  lock;
+};
+
+#ifdef CONFIG_USE_GENERIC_SMP_HELPERS
+extern void __init padata_init(unsigned int nr, cpumask_t cpu_map);
+extern void padata_dont_wait(unsigned int nr, struct padata_priv *padata);
+extern int padata_do_parallel(unsigned int softirq_nr, unsigned int nr,
+ struct padata_priv *padata, int cb_cpu);
+extern int padata_do_serial(unsigned int nr, struct padata_priv *padata);
+extern cpumask_t padata_get_cpumap(unsigned int nr);
+extern void padata_set_cpumap(unsigned int nr, cpumask_t cpu_map);
+extern void padata_add_cpu(unsigned int nr, int cpu);
+extern void padata_remove_cpu(unsigned int nr, int cpu);
+extern void padata_start(unsigned int nr);
+extern void padata_stop(unsigned int nr);
+#else
+static inline void padata_init(unsigned int nr,cpumask_t cpu_map)
+{
+}
+static inline void padata_dont_wait(unsigned int nr, struct padata_priv 
*padata)
+{
+}
+static inline int padata_do_parallel(unsigned int softirq_nr, unsigned int nr,
+struct padata_priv *padata, int cb_cpu)
+{
+   return 0;
+}
+static inline int padata_do_serial(unsigned int nr, struct padata_priv *padata)
+{
+   return 0;
+}
+static inline cpumask_t padata_get_cpumap(unsigned int nr)
+{
+   return cpu_online_map;
+}
+static inline void padata_set_cpumap(unsigned int nr, cpumask_t cpu_map)
+{
+}
+static inline padata_add_cpu(unsigned int nr, int cpu)
+{
+}
+static inline padata_remove_cpu(unsigned int nr, int cpu)
+{
+}
+static

[RFC] [PATCH v2 2/4] pcrypt: Add pcrypt crypto parallelization engine

2009-04-24 Thread Steffen Klassert
This 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.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/Kconfig|   13 ++
 crypto/Makefile   |2 +
 crypto/pcrypt.c   |  415 +
 crypto/pcrypt_core.c  |  106 
 include/crypto/pcrypt.h   |   56 ++
 include/linux/crypto.h|2 +
 include/linux/interrupt.h |2 +
 kernel/softirq.c  |3 +-
 8 files changed, 598 insertions(+), 1 deletions(-)
 create mode 100644 crypto/pcrypt.c
 create mode 100644 crypto/pcrypt_core.c
 create mode 100644 include/crypto/pcrypt.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 74d0e62..b05fc95 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -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 engine (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
 
diff --git a/crypto/Makefile b/crypto/Makefile
index 673d9f7..84b9d17 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -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
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
new file mode 100644
index 000..23f7eb7
--- /dev/null
+++ b/crypto/pcrypt.c
@@ -0,0 +1,415 @@
+/*
+ * pcrypt - Parallel crypto wrapper.
+ *
+ * Copyright (C) 2009 secunet Security Networks AG
+ * Copyright (C) 2009 Steffen Klassert steffen.klass...@secunet.com
+ *
+ * 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 crypto/algapi.h
+#include crypto/internal/aead.h
+#include linux/err.h
+#include linux/init.h
+#include linux/module.h
+#include linux/slab.h
+#include crypto/pcrypt.h
+
+struct pcrypt_instance_ctx {
+   struct crypto_spawn spawn;
+   unsigned int tfm_count;
+};
+
+struct pcrypt_aead_ctx {
+   struct crypto_aead *child;
+   unsigned int tfm_nr;
+};
+
+static int pcrypt_do_parallel(struct padata_priv *padata, unsigned int tfm_nr,
+ unsigned int softirq, unsigned int padata_nr)
+{
+   unsigned int cpu, cpu_index, num_cpus, cb_cpu;
+   cpumask_t cpu_map;
+
+   cpu_map = padata_get_cpumap(padata_nr);
+   num_cpus = cpus_weight(cpu_map);
+
+   cpu_index = tfm_nr % num_cpus;
+
+   cb_cpu = first_cpu(cpu_map);
+   for (cpu = 0; cpu  cpu_index; cpu++)
+   cb_cpu = next_cpu(cb_cpu, cpu_map);
+
+   return padata_do_parallel(softirq, padata_nr, padata, cb_cpu);
+}
+
+static int pcrypt_aead_setkey(struct crypto_aead *parent,
+ const u8 *key, unsigned int keylen)
+{
+   struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent);
+
+   return crypto_aead_setkey(ctx-child, key, keylen);
+}
+
+static int pcrypt_aead_setauthsize(struct crypto_aead *parent,
+  unsigned int authsize)
+{
+   struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent);
+
+   return crypto_aead_setauthsize(ctx-child, authsize);
+}
+
+static void pcrypt_aead_serial(struct padata_priv *padata)
+{
+   struct pcrypt_request *preq = pcrypt_padata_request(padata);
+   struct aead_request *req = pcrypt_request_ctx(preq);
+
+   aead_request_complete(req-base.data, padata-info);
+}
+
+static void pcrypt_aead_giv_serial(struct padata_priv *padata)
+{
+   struct pcrypt_request *preq = pcrypt_padata_request(padata);
+   struct aead_givcrypt_request *req = pcrypt_request_ctx(preq);
+
+   aead_request_complete(req-areq.base.data, padata-info);
+}
+
+static void pcrypt_aead_done(struct

[RFC] [PATCH v2 0/4] Parallel IPsec

2009-04-24 Thread Steffen Klassert
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 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
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [PATCH v2 3/4] xfrm: Add a netlink attribute for software crypto accelerators

2009-04-24 Thread Steffen Klassert
This patch adds a netlink attribute for software crypto
accelerators like pcrypt. This makes it possible to choose a
crypto accelerator template by it's name from the userspace.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 include/linux/xfrm.h |   10 ++
 include/net/xfrm.h   |3 +++
 net/xfrm/xfrm_user.c |8 
 3 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index 2d4ec15..e20b74e 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -240,6 +240,15 @@ struct xfrm_encap_tmpl {
xfrm_address_t  encap_oa;
 };
 
+struct xfrm_accl {
+   charname[64];
+   __u8type;
+#define XFRM_ACCL_ENC  1
+#define XFRM_ACCL_AUTH 2   
+#define XFRM_ACCL_COMP 4
+#define XFRM_ACCL_AEAD 8
+};
+
 /* AEVENT flags  */
 enum xfrm_ae_ftype_t {
XFRM_AE_UNSPEC,
@@ -283,6 +292,7 @@ enum xfrm_attr_type_t {
XFRMA_MIGRATE,
XFRMA_ALG_AEAD, /* struct xfrm_algo_aead */
XFRMA_KMADDRESS,/* struct xfrm_user_kmaddress */
+   XFRMA_CRYPTO_ACCL,  /* struct xfrm_accl */
__XFRMA_MAX
 
 #define XFRMA_MAX (__XFRMA_MAX - 1)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 2e9f5c0..b574147 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -171,6 +171,9 @@ struct xfrm_state
/* Data for care-of address */
xfrm_address_t  *coaddr;
 
+   /* Data for crypto accelerator */
+   struct xfrm_accl*accl;
+
/* IPComp needs an IPIP tunnel for handling uncompressed packets */
struct xfrm_state   *tunnel;
 
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index b95a2d6..5272cbc 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -359,6 +359,13 @@ static struct xfrm_state *xfrm_state_construct(struct net 
*net,
goto error;
}
 
+   if (attrs[XFRMA_CRYPTO_ACCL]) {
+   x-accl = kmemdup(nla_data(attrs[XFRMA_CRYPTO_ACCL]),
+   sizeof(*x-accl), GFP_KERNEL);
+   if (x-accl == NULL)
+   goto error;
+   }
+
err = xfrm_init_state(x);
if (err)
goto error;
@@ -1958,6 +1965,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] 
= {
[XFRMA_POLICY_TYPE] = { .len = sizeof(struct xfrm_userpolicy_type)},
[XFRMA_MIGRATE] = { .len = sizeof(struct xfrm_user_migrate) },
[XFRMA_KMADDRESS]   = { .len = sizeof(struct xfrm_user_kmaddress) },
+   [XFRMA_CRYPTO_ACCL] = { .len = sizeof(struct xfrm_accl) },
 };
 
 static struct xfrm_link {
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] crypto: eseqiv - fix IV generation for sync algorithms

2009-04-15 Thread Steffen Klassert
On Wed, Apr 15, 2009 at 07:15:49PM +0800, Herbert Xu wrote:
 
 Well caught! Clearly no one has ever tried this before :)
 

I thought so :)

 
 So how about doing what seqiv does and check
 
   if (giv != req-giv)
 

Yes, that's probaply the better check.
An updated patch is below.


crypto: eseqiv - fix IV generation for sync algorithms

If crypto_ablkcipher_encrypt() returns synchronous,
eseqiv_complete2() is called even if req-giv is already the
pointer to the generated IV. The generated IV is overwritten
with some random data in this case. This patch fixes this by
calling eseqiv_complete2() just if the generated IV has to be
copied to req-giv.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/eseqiv.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c
index 2a342c8..3ca3b66 100644
--- a/crypto/eseqiv.c
+++ b/crypto/eseqiv.c
@@ -153,7 +153,8 @@ 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;
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH 2/4] cpu_chainiv: add percpu IV chain genarator

2009-04-14 Thread Steffen Klassert
On Thu, Apr 09, 2009 at 11:20:45AM +0800, Herbert Xu wrote:
 
 You can allocate eseqiv(alg), e.g., eseqiv(cbc(aes)).
 

Ok, that's possible. I missed this possibility, probaply because nobody
is actually doing it this way. Thanks!

Unfortunately eseqiv does not work out of the box if we do synchronous
encryption. 

If crypto_ablkcipher_encrypt() returns synchronous, eseqiv_complete2()
is called even if req-giv is already the pointer to the generated IV.
The generated IV is overwritten with some random data in this case.

I fixed this by calling eseqiv_complete2() just in the case when an
asynchronous algorithm would call eseqiv_complete() as the complete
function. I'll send the patch with an extra mail.

Now pcrypt runs fine together with eseqiv and the throughput
results are very similar to the ones with cpu_chainiv.

Steffen
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] crypto: eseqiv - fix IV generation for sync algorithms

2009-04-14 Thread Steffen Klassert
If crypto_ablkcipher_encrypt() returns synchronous,
eseqiv_complete2() is called even if req-giv is already the
pointer to the generated IV. The generated IV is overwritten
with some random data in this case. This patch fixes this by
calling eseqiv_complete2() just in the case where an asynchronous
algorithm would call eseqiv_complete() as the complete function.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/eseqiv.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c
index 2a342c8..2fa53b0 100644
--- a/crypto/eseqiv.c
+++ b/crypto/eseqiv.c
@@ -153,7 +153,8 @@ static int eseqiv_givencrypt(struct 
skcipher_givcrypt_request *req)
if (err)
goto out;
 
-   eseqiv_complete2(req);
+   if (complete == eseqiv_complete)
+   eseqiv_complete2(req);
 
 out:
return err;
-- 
1.5.4.2

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH 2/4] cpu_chainiv: add percpu IV chain genarator

2009-03-30 Thread Steffen Klassert
On Fri, Mar 27, 2009 at 04:36:15PM +0800, Herbert Xu wrote:
 On Mon, Mar 16, 2009 at 12:52:51PM +0100, Steffen Klassert wrote:
  If the crypro requests of a crypto transformation are processed in
  parallel, the usual chain IV generator would serialize the crypto
  requests again. The percpu IV chain genarator allocates the IV as
  percpu data and generates percpu IV chains, so a crypro request
  does not need to wait for the completition of the IV generation
  from a previous request that runs on a different cpu.
  
  Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
 
 I actually thought about this one when I first wrote chainiv,
 I chose to avoid this because it has some security consequences.
 In particular, an attacker would now be able to infer whether two
 packets belong to two differnt flows from the fact that they came
 from two different IV streams.
 
 In any case, I don't think this is central to your work, right?
 

Well, to do efficient parallel processing we need a percpu IV chain
genarator. pcrypt sends the crypto requests round robin to the cpus
independent of the flow they are belong to, so the flows and the IV
streams are mixing. As long as we use the percpu IV chain genarator just
for parallel algorithms we don't have this security issues. 

--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH 4/4] esp: add the pcrypt hooks to esp

2009-03-30 Thread Steffen Klassert
On Fri, Mar 27, 2009 at 04:44:57PM +0800, Herbert Xu wrote:
 On Mon, Mar 16, 2009 at 12:55:26PM +0100, Steffen Klassert wrote:
 
  @@ -447,7 +448,7 @@ static int esp_init_aead(struct xfrm_state *x)
  struct crypto_aead *aead;
  int err;
   
  -   aead = crypto_alloc_aead(x-aead-alg_name, 0, 0);
  +   aead = crypto_alloc_aead_tfm(x-aead-alg_name, 0, 0);
 
 I'd like this to be configurable.  After all, there's not much
 point in doing this if your crypto is done through PCI.
 

Indeed, it should be configurable. I was not sure what's the best way to 
make it configurable, so I decided to just make it the default to be
able to use it in this first version.

 The easiest way is to let the user specify pcrypt through the
 algorithm name.  In fact, as long as pcrypt has a higher priority
 than the default software algorithms, the user simply has to
 instantiate it in order for it to be the default for all uses
 of that algorithm.
 

For IPsec I thought about something like 'pcrypt(authenc(...,...))' to
be able to process each crypto request with just one
parallelization/serialization call. Perhaps I'm missing something, but
actually I don't see how to choose for this from userspace through the
name without adding an entry for each possible combination of hmac and
blkcipher algorithm to the xfrm_aead_list. I'd appreciate any hint here.
My idea to make it configurable was to do it similar to the async
algorithms by

aead = crypto_alloc_aead_tfm(x-aead-alg_name, flags, CRYPTO_ALG_PCRYPT);

if CRYPTO_ALG_PCRYPT is set in flags, the crypto manager tries to choose
a parallel algorithm, if it is not set parallel algorithms will be ignored.
~
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [PATCH 2/4] cpu_chainiv: add percpu IV chain genarator

2009-03-30 Thread Steffen Klassert
On Mon, Mar 30, 2009 at 09:19:55PM +0800, Herbert Xu wrote:
 
 How about using eseqiv? It's designed for exactly this situation
 where you want parallel async processing.  Its overhead is just
 one extra encryption block.
 

Yes, that's an option too. I'll give it a try.

Thanks!
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [PATCH 0/4] Parallel IPsec

2009-03-16 Thread Steffen Klassert
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.

I posted a first network based version to the netdev list some time ago. The
discussion can be found here:
http://lwn.net/Articles/309029/

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.

I did forwarding tests with two quad core machines (Intel Core 2 Quad Q6600)
and an EXFO FTB-400 packet blazer.
Unfortunately the thoughput tests are not that meaningful as long as we don't
use the new reentrant ahash/shash interface, because the lock in authenc_hash
serializes the requests. As soon as this work stabilize I'll start to convert
authenc to ahash if nobody else did it in between.

The results of the troughput tests are as follows:

cryptodev-2.6
Packetsize: 1420 byte
Encryption: aes192-sha1
bidirectional throughput: 2 x 132 Mbit/s
unidirectional throughput: 260 Mbit/s

cryptodev-2.6 + pcrypt (authenc) parallelization:
Packetsize: 1420 byte
Encryption: aes192-sha1
bidirectional throughput: 2 x 320 Mbit/s
unidirectional throughput: 493 Mbit/s

To reduce the hold time of the lock in authenc_hash I did the same tests again
with aes192-digest_null:

cryptodev-2.6
Packetsize: 1420 byte
Encryption: aes192-digest_null
bidirectional throughput: 2 x 243 Mbit/s
unidirectional throughput: 480 Mbit/s

cryptodev-2.6 + pcrypt (authenc) parallelization:
Packetsize: 1420 byte
Encryption: aes192-digest_null
bidirectional throughput: 2 x 592 Mbit/s
unidirectional throughput: 936 Mbit/s

Steffen
--
To unsubscribe from this list: send the line unsubscribe linux-crypto in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [PATCH 2/4] cpu_chainiv: add percpu IV chain genarator

2009-03-16 Thread Steffen Klassert
If the crypro requests of a crypto transformation are processed in
parallel, the usual chain IV generator would serialize the crypto
requests again. The percpu IV chain genarator allocates the IV as
percpu data and generates percpu IV chains, so a crypro request
does not need to wait for the completition of the IV generation
from a previous request that runs on a different cpu.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/Makefile  |1 +
 crypto/cpu_chainiv.c |  327 ++
 2 files changed, 328 insertions(+), 0 deletions(-)
 create mode 100644 crypto/cpu_chainiv.c

diff --git a/crypto/Makefile b/crypto/Makefile
index 673d9f7..24f7279 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -19,6 +19,7 @@ crypto_blkcipher-objs := ablkcipher.o
 crypto_blkcipher-objs += blkcipher.o
 obj-$(CONFIG_CRYPTO_BLKCIPHER2) += crypto_blkcipher.o
 obj-$(CONFIG_CRYPTO_BLKCIPHER2) += chainiv.o
+obj-$(CONFIG_CRYPTO_BLKCIPHER2) += cpu_chainiv.o
 obj-$(CONFIG_CRYPTO_BLKCIPHER2) += eseqiv.o
 obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o
 
diff --git a/crypto/cpu_chainiv.c b/crypto/cpu_chainiv.c
new file mode 100644
index 000..8acfc77
--- /dev/null
+++ b/crypto/cpu_chainiv.c
@@ -0,0 +1,327 @@
+/*
+ * cpu_chainiv - Per CPU Chain IV Generator
+ *
+ * Generate IVs by using the last block of the previous encryption on
+ * the local cpu. This is mainly useful for CBC with a parallel algorithm.
+ *
+ * Based on chainiv.c by Herbert Xu herb...@gondor.apana.org.au
+ *
+ * Copyright (C) 2009 secunet Security Networks AG
+ * Copyright (C) 2009 Steffen Klassert steffen.klass...@secunet.com
+ *
+ * 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 crypto/internal/skcipher.h
+#include crypto/internal/aead.h
+#include crypto/rng.h
+#include linux/err.h
+#include linux/init.h
+#include linux/kernel.h
+#include linux/module.h
+#include linux/spinlock.h
+#include linux/string.h
+
+struct cpu_civ_ctx {
+   spinlock_t  lock;
+   char*iv;
+};
+
+static int cpu_civ_aead_givencrypt(struct aead_givcrypt_request *req)
+{
+   struct crypto_aead *geniv = aead_givcrypt_reqtfm(req);
+   struct cpu_civ_ctx *ctx = crypto_aead_ctx(geniv);
+   struct aead_request *subreq = aead_givcrypt_reqctx(req);
+   unsigned int ivsize;
+   char *iv;
+   int err;
+
+   aead_request_set_tfm(subreq, aead_geniv_base(geniv));
+   aead_request_set_callback(subreq, req-areq.base.flags,
+ req-areq.base.complete,
+ req-areq.base.data);
+   aead_request_set_crypt(subreq, req-areq.src, req-areq.dst,
+  req-areq.cryptlen, req-areq.iv);
+   aead_request_set_assoc(subreq, req-areq.assoc, req-areq.assoclen);
+
+   local_bh_disable();
+
+   ivsize = crypto_aead_ivsize(geniv);
+
+   iv = per_cpu_ptr(ctx-iv, smp_processor_id());
+
+   memcpy(req-giv, iv, ivsize);
+   memcpy(subreq-iv, iv, ivsize);
+
+   err = crypto_aead_encrypt(subreq);
+   if (err)
+   goto unlock;
+
+   memcpy(iv, subreq-iv, ivsize);
+
+unlock:
+   local_bh_enable();
+
+   return err;
+}
+
+static int cpu_civ_aead_givencrypt_first(struct aead_givcrypt_request *req)
+{
+   struct crypto_aead *geniv = aead_givcrypt_reqtfm(req);
+   struct cpu_civ_ctx *ctx = crypto_aead_ctx(geniv);
+   char *iv;
+   int err = 0;
+   int cpu;
+
+   spin_lock_bh(ctx-lock);
+   if (crypto_aead_crt(geniv)-givencrypt != cpu_civ_aead_givencrypt_first)
+   goto unlock;
+
+   crypto_aead_crt(geniv)-givencrypt = cpu_civ_aead_givencrypt;
+
+   for_each_possible_cpu(cpu) {
+   iv = per_cpu_ptr(ctx-iv, cpu);
+   err = crypto_rng_get_bytes(crypto_default_rng, iv,
+  crypto_aead_ivsize(geniv));
+
+   if (err)
+   break;
+   }
+
+unlock:
+   spin_unlock_bh(ctx-lock);
+
+   if (err)
+   return err;
+
+   return cpu_civ_aead_givencrypt(req);
+}
+
+static int cpu_civ_ablkcipher_givencrypt(struct skcipher_givcrypt_request *req)
+{
+   struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req);
+   struct cpu_civ_ctx *ctx = crypto_ablkcipher_ctx(geniv);
+   struct

[RFC] [PATCH 3/4] pcrypt: Add pcrypt crypto parallelization engine

2009-03-16 Thread Steffen Klassert
This 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.

Signed-off-by: Steffen Klassert steffen.klass...@secunet.com
---
 crypto/Kconfig|   13 ++
 crypto/Makefile   |2 +
 crypto/pcrypt.c   |  417 +
 crypto/pcrypt_core.c  |  125 ++
 include/crypto/pcrypt.h   |   85 +
 include/linux/crypto.h|2 +
 include/linux/interrupt.h |2 +
 7 files changed, 646 insertions(+), 0 deletions(-)
 create mode 100644 crypto/pcrypt.c
 create mode 100644 crypto/pcrypt_core.c
 create mode 100644 include/crypto/pcrypt.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 74d0e62..b05fc95 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -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 engine (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
 
diff --git a/crypto/Makefile b/crypto/Makefile
index 24f7279..94043fe 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -57,6 +57,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
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
new file mode 100644
index 000..86a8718
--- /dev/null
+++ b/crypto/pcrypt.c
@@ -0,0 +1,417 @@
+/*
+ * pcrypt - Parallel crypto wrapper.
+ *
+ * Copyright (C) 2009 secunet Security Networks AG
+ * Copyright (C) 2009 Steffen Klassert steffen.klass...@secunet.com
+ *
+ * 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 crypto/algapi.h
+#include crypto/internal/aead.h
+#include linux/err.h
+#include linux/init.h
+#include linux/module.h
+#include linux/slab.h
+#include crypto/pcrypt.h
+
+struct pcrypt_instance_ctx {
+   struct crypto_spawn spawn;
+   unsigned int tfm_count;
+};
+
+struct pcrypt_aead_ctx {
+   struct crypto_aead *child;
+   unsigned int tfm_nr;
+};
+
+static int pcrypt_do_parallel(struct padata_priv *padata, unsigned int tfm_nr,
+ unsigned int softirq, unsigned int padata_nr)
+{
+   unsigned int cpu, cpu_index, num_cpus, cb_cpu;
+   cpumask_t cpu_map;
+
+   cpu_map = padata_get_cpumap(padata_nr);
+   num_cpus = cpus_weight(cpu_map);
+
+   cpu_index = tfm_nr % num_cpus;
+
+   cb_cpu = first_cpu(cpu_map);
+   for (cpu = 0; cpu  cpu_index; cpu++)
+   cb_cpu = next_cpu(cb_cpu, cpu_map);
+
+   return padata_do_parallel(softirq, padata_nr, padata, cb_cpu);
+}
+
+static int pcrypt_aead_setkey(struct crypto_aead *parent,
+ const u8 *key, unsigned int keylen)
+{
+   struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent);
+
+   return crypto_aead_setkey(ctx-child, key, keylen);
+}
+
+static int pcrypt_aead_setauthsize(struct crypto_aead *parent,
+  unsigned int authsize)
+{
+   struct pcrypt_aead_ctx *ctx = crypto_aead_ctx(parent);
+
+   return crypto_aead_setauthsize(ctx-child, authsize);
+}
+
+static void pcrypt_aead_serial(struct padata_priv *padata)
+{
+   struct pcrypt_request *preq = pcrypt_padata_request(padata);
+   struct aead_request *req = pcrypt_request_ctx(preq);
+
+   aead_request_complete(req-base.data, padata-info);
+}
+
+static void pcrypt_aead_giv_serial(struct padata_priv *padata)
+{
+   struct pcrypt_request *preq = pcrypt_padata_request(padata);
+   struct aead_givcrypt_request *req = pcrypt_request_ctx(preq);
+
+   aead_request_complete(req-areq.base.data, padata-info);
+}
+
+static void pcrypt_aead_done(struct crypto_async_request *areq, int

<    1   2   3   4   >