Re: [PATCH 1/5] random: fix crng_ready() test

2018-05-17 Thread Christophe LEROY



Le 13/04/2018 à 19:00, Theodore Y. Ts'o a écrit :

On Fri, Apr 13, 2018 at 03:05:01PM +0200, Stephan Mueller wrote:


What I would like to point out that more and more folks change to
getrandom(2). As this call will now unblock much later in the boot cycle,
these systems see a significant departure from the current system behavior.

E.g. an sshd using getrandom(2) would be ready shortly after the boot finishes
as of now. Now it can be a matter minutes before it responds. Thus, is such
change in the kernel behavior something for stable?


It will have some change on the kernel behavior, but not as much as
you might think.  That's because in older kernels, we were *already*
blocking until crng_init > 2 --- if the getrandom(2) call happened
while crng_init was in state 0.

Even before this patch series, we didn't wake up a process blocked on
crng_init_wait until crng_init state 2 is reached:

static void crng_reseed(struct crng_state *crng, struct entropy_store *r)
{
...
if (crng == _crng && crng_init < 2) {
invalidate_batched_entropy();
crng_init = 2;
process_random_ready_list();
wake_up_interruptible(_init_wait);
pr_notice("random: crng init done\n");
}
}

This is the reason why there are reports like this: "Boot delayed for
about 90 seconds until 'random: crng init done'"[1]

[1] https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1685794


So we have the problem already.  There will be more cases of this
after this patch series is applied, true.  But what we have already is
an inconsistent state where if you call getrandom(2) while the kernel
is in crng_init state 0, you will block until crng_init state 2, but
if you are in crng_init state 1, you will assume the CRNG is fully
initialized.

Given the documentation of how getrandom(2) works what its documented
guarantees are, I think it does justify making its behavior both more
consistent with itself, and more consistent what the security
guarantees we have promised people.

I was a little worried that on VM's this could end up causing things
to block for a long time, but an experiment on a GCE VM shows that
isn't a problem:

[0.00] Linux version 4.16.0-rc3-ext4-9-gf6b302ebca85 (tytso@cwcc) 
(gcc version 7.3.0 (Debian 7.3.0-15)) #16 SMP Thu Apr 12 16:57:17 EDT 2018
[1.282220] random: fast init done
[3.987092] random: crng init done
[4.376787] EXT4-fs (sda1): re-mounted. Opts: (null)

There are some desktops where the "crng_init done" report doesn't
happen until 45-90 seconds into the boot.  I don't think I've seen
reports where it takes _minutes_ however.  Can you give me some
examples of such cases?



On a powerpc embedded board which has an mpc8xx processor running at 
133Mhz, I now get the startup done in more than 7 minutes instead of 30 
seconds. This is due to the webserver blocking on read on /dev/random 
until we get 'random: crng init done':


[0.00] Linux version 4.17.0-rc4-00415-gd2f75d40072d 
(root@localhost) (gcc version 5.4.0 (GCC)) #203 PREEMPT Wed May 16 
16:32:02 CEST 2018
[0.295453] random: get_random_u32 called from 
bucket_table_alloc+0x84/0x1bc with crng_init=0

[1.030472] device: 'random': device_add
[1.031279] device: 'urandom': device_add
[1.420069] device: 'hw_random': device_add
[2.156853] random: fast init done
[  462.007776] random: crng init done

This has become really critical, is there anything that can be done ?

Christophe



- Ted

P.S.  Of course, in a VM environment, if the host supports virtio-rng,
the boot delay problem is completely not an issue.  You just have to
enable virtio-rng in the guest kernel, which I believe is already the
case for most distro kernels.

BTW, for KVM, it's fairly simple to set it the host-side support for
virtio-rng.  Just add to the kvm command-line options:

 -object rng-random,filename=/dev/urandom,id=rng0 \
-device virtio-rng-pci,rng=rng0



Re: [PATCH] crypto: talitos - fix IPsec cipher in length

2018-03-22 Thread Christophe LEROY



Le 16/03/2018 à 15:07, Horia Geantă a écrit :

On 3/16/2018 2:42 PM, Christophe LEROY wrote:

Le 16/03/2018 à 09:48, Horia Geantă a écrit :

For SEC 2.x+, cipher in length must contain only the ciphertext length.
In case of using hardware ICV checking, the ICV length is provided via
the "extent" field of the descriptor pointer.

Cc: <sta...@vger.kernel.org> # 4.8+
Fixes: 549bd8bc5987 ("crypto: talitos - Implement AEAD for SEC1 using 
HMAC_SNOOP_NO_AFEU")


It looks like the issue comes more from commit fbb22137c4d9b ("crypto:
talitos - fix use of sg_link_tbl_len"), doesn't it ?


No, the first commit that breaks IPsec for SEC 2.x+ is the one I mentioned.


Today without your patch, IPsec works well on my mpc8321E. It was broken
by 549bd8bc5987 and fixed by fbb22137c4d9b.
But it seems the fix is not complete as it doesn't work yet in your case.



Afterwards, the refactoring of helper functions lead to current situation where
talitos_sg_map() is fed with "len" parameter that is used for two things:
-HW S/G table entries generation
-setting talitos pointer length

But in certain cases (like pointer nr. 4 - cipher in - for SEC 2.x+ IPsec),
talitos pointer length is only part of the total length, the other part being
set in the "extent" pointer field.

Currently talitos_sg_map() does not accommodate for this case.
In order to keep the fix to a minimum I've overwritten talitos pointer length:
-first talitos_sg_map() sets length to sg_link_tbl_len = cryptlen + authsize
-in case of SEC 2.x IPsec, length is corrected to cryptlen (while extent = 
authsize)


I have proposed a v2 version of your patch which takes it into 
talitos_sg_map() hence avoiding direct access to ptr[4] without using 
the helpers.


Regards
Christophe



Regards,
Horia



[PATCH v2] crypto: talitos - fix IPsec cipher in length

2018-03-22 Thread Christophe Leroy
For SEC 2.x+, cipher in length must contain only the ciphertext length.
In case of using hardware ICV checking, the ICV length is provided via
the "extent" field of the descriptor pointer.

Cc: <sta...@vger.kernel.org> # 4.8+
Fixes: 549bd8bc5987 ("crypto: talitos - Implement AEAD for SEC1 using 
HMAC_SNOOP_NO_AFEU")
Reported-by: Horia Geantă <horia.gea...@nxp.com>
Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 36 
 1 file changed, 20 insertions(+), 16 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 6882fa2f8bad..016ff8c4c305 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1130,10 +1130,10 @@ static int sg_to_link_tbl_offset(struct scatterlist 
*sg, int sg_count,
return count;
 }
 
-static int talitos_sg_map(struct device *dev, struct scatterlist *src,
-  unsigned int len, struct talitos_edesc *edesc,
-  struct talitos_ptr *ptr,
-  int sg_count, unsigned int offset, int tbl_off)
+static int talitos_sg_map_ext(struct device *dev, struct scatterlist *src,
+ unsigned int len, struct talitos_edesc *edesc,
+ struct talitos_ptr *ptr, int sg_count,
+ unsigned int offset, int tbl_off, int elen)
 {
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
@@ -1142,6 +1142,7 @@ static int talitos_sg_map(struct device *dev, struct 
scatterlist *src,
to_talitos_ptr(ptr, 0, 0, is_sec1);
return 1;
}
+   to_talitos_ptr_ext_set(ptr, elen, is_sec1);
if (sg_count == 1) {
to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1);
return sg_count;
@@ -1150,7 +1151,7 @@ static int talitos_sg_map(struct device *dev, struct 
scatterlist *src,
to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1);
return sg_count;
}
-   sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len,
+   sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len + elen,
 >link_tbl[tbl_off]);
if (sg_count == 1) {
/* Only one segment now, so no link tbl needed*/
@@ -1164,6 +1165,15 @@ static int talitos_sg_map(struct device *dev, struct 
scatterlist *src,
return sg_count;
 }
 
+static int talitos_sg_map(struct device *dev, struct scatterlist *src,
+ unsigned int len, struct talitos_edesc *edesc,
+ struct talitos_ptr *ptr, int sg_count,
+ unsigned int offset, int tbl_off)
+{
+   return talitos_sg_map_ext(dev, src, len, edesc, ptr, sg_count, offset,
+ tbl_off, 0);
+}
+
 /*
  * fill in and submit ipsec_esp descriptor
  */
@@ -1181,7 +1191,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
unsigned int ivsize = crypto_aead_ivsize(aead);
int tbl_off = 0;
int sg_count, ret;
-   int sg_link_tbl_len;
+   int elen = 0;
bool sync_needed = false;
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
@@ -1223,17 +1233,11 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
 * extent is bytes of HMAC postpended to ciphertext,
 * typically 12 for ipsec
 */
-   sg_link_tbl_len = cryptlen;
-
-   if (is_ipsec_esp) {
-   to_talitos_ptr_ext_set(>ptr[4], authsize, is_sec1);
-
-   if (desc->hdr & DESC_HDR_MODE1_MDEU_CICV)
-   sg_link_tbl_len += authsize;
-   }
+   if (is_ipsec_esp && (desc->hdr & DESC_HDR_MODE1_MDEU_CICV))
+   elen = authsize;
 
-   ret = talitos_sg_map(dev, areq->src, sg_link_tbl_len, edesc,
->ptr[4], sg_count, areq->assoclen, tbl_off);
+   ret = talitos_sg_map_ext(dev, areq->src, cryptlen, edesc, >ptr[4],
+sg_count, areq->assoclen, tbl_off, elen);
 
if (ret > 1) {
tbl_off += ret;
-- 
2.13.3



Re: [PATCH 9/9] crypto: talitos - don't leak pointers to authenc keys

2018-03-22 Thread Christophe LEROY



Le 21/03/2018 à 18:00, Tudor Ambarus a écrit :

Signed-off-by: Tudor Ambarus <tudor.amba...@microchip.com>


Reviewed-by: Christophe Leroy <christophe.le...@c-s.fr>


---
  drivers/crypto/talitos.c | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 447cb8b..c92efc7 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -904,10 +904,12 @@ static int aead_setkey(struct crypto_aead *authenc,
ctx->dma_key = dma_map_single(dev, ctx->key, ctx->keylen,
  DMA_TO_DEVICE);
  
+	memzero_explicit(, sizeof(keys));

return 0;
  
  badkey:

crypto_aead_set_flags(authenc, CRYPTO_TFM_RES_BAD_KEY_LEN);
+   memzero_explicit(, sizeof(keys));
return -EINVAL;
  }
  



Re: [PATCH] crypto: talitos - fix IPsec cipher in length

2018-03-16 Thread Christophe LEROY



Le 16/03/2018 à 09:48, Horia Geantă a écrit :

For SEC 2.x+, cipher in length must contain only the ciphertext length.
In case of using hardware ICV checking, the ICV length is provided via
the "extent" field of the descriptor pointer.

Cc:  # 4.8+
Fixes: 549bd8bc5987 ("crypto: talitos - Implement AEAD for SEC1 using 
HMAC_SNOOP_NO_AFEU")


It looks like the issue comes more from commit fbb22137c4d9b ("crypto: 
talitos - fix use of sg_link_tbl_len"), doesn't it ?




Signed-off-by: Horia Geantă 
---
  drivers/crypto/talitos.c | 7 +++
  1 file changed, 7 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 447cb8b1b16a..61a30704847f 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1251,6 +1251,13 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
ret = talitos_sg_map(dev, areq->src, sg_link_tbl_len, edesc,
 >ptr[4], sg_count, areq->assoclen, tbl_off);
  
+	/*

+* In case of SEC 2.x+, cipher in len must include only the ciphertext,
+* while extent is used for ICV len.
+*/
+   if (is_ipsec_esp && (desc->hdr & DESC_HDR_MODE1_MDEU_CICV))
+   desc->ptr[4].len = cpu_to_be16(cryptlen);


I don't like too much the idea of modifying ptr[4] without using the
helpers, although I don't have any other suggestion yet.

Christophe


+
if (ret > 1) {
tbl_off += ret;
sync_needed = true;



Re: [PATCH 2/2] crypto: talitos: Delete an error message for a failed memory allocation in talitos_edesc_alloc()

2018-03-12 Thread Christophe LEROY



Le 12/03/2018 à 14:32, SF Markus Elfring a écrit :

From: Markus Elfring <elfr...@users.sourceforge.net>
Date: Mon, 12 Mar 2018 14:18:23 +0100

Omit an extra message for a memory allocation failure in this function.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfr...@users.sourceforge.net>


Reviewed-by: Christophe Leroy <christophe.le...@c-s.fr>


---
  drivers/crypto/talitos.c | 1 -
  1 file changed, 1 deletion(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index a2271322db34..4c7318981d28 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1399,7 +1399,6 @@ static struct talitos_edesc *talitos_edesc_alloc(struct 
device *dev,
  
  	edesc = kmalloc(alloc_len, GFP_DMA | flags);

if (!edesc) {
-   dev_err(dev, "could not allocate edescriptor\n");
err = ERR_PTR(-ENOMEM);
goto error_sg;
}



Re: [PATCH 1/2] crypto: talitos: Use common error handling code in talitos_edesc_alloc()

2018-03-12 Thread Christophe LEROY



Le 12/03/2018 à 14:31, SF Markus Elfring a écrit :

From: Markus Elfring 
Date: Mon, 12 Mar 2018 14:08:55 +0100

Add jump targets so that an error message and the setting of a specific
error code is stored only once at the end of this function.

Signed-off-by: Markus Elfring 
---
  drivers/crypto/talitos.c | 24 
  1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 6882fa2f8bad..a2271322db34 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1352,29 +1352,24 @@ static struct talitos_edesc *talitos_edesc_alloc(struct 
device *dev,
if (!dst || dst == src) {
src_len = assoclen + cryptlen + authsize;
src_nents = sg_nents_for_len(src, src_len);
-   if (src_nents < 0) {
-   dev_err(dev, "Invalid number of src SG.\n");


I don't think this is a good idea to move this dev_err(), just because
the text is identical twice.
The code is more clear when the text of the error is at the error.
Also, as this text is for the case where SRC SG is identical to DST SG,
the text could instead be "Invalid number of SG"


-   err = ERR_PTR(-EINVAL);
-   goto error_sg;
-   }
+   if (src_nents < 0)
+   goto report_failure;
+
src_nents = (src_nents == 1) ? 0 : src_nents;
dst_nents = dst ? src_nents : 0;
dst_len = 0;
} else { /* dst && dst != src*/
src_len = assoclen + cryptlen + (encrypt ? 0 : authsize);
src_nents = sg_nents_for_len(src, src_len);
-   if (src_nents < 0) {
-   dev_err(dev, "Invalid number of src SG.\n");
-   err = ERR_PTR(-EINVAL);
-   goto error_sg;
-   }
+   if (src_nents < 0)
+   goto report_failure;
+
src_nents = (src_nents == 1) ? 0 : src_nents;
dst_len = assoclen + cryptlen + (encrypt ? authsize : 0);
dst_nents = sg_nents_for_len(dst, dst_len);
if (dst_nents < 0) {
dev_err(dev, "Invalid number of dst SG.\n");


To be consistant, this one should also go at the end if we want to be 
consistant.



-   err = ERR_PTR(-EINVAL);
-   goto error_sg;
+   goto set_error_code;
}
dst_nents = (dst_nents == 1) ? 0 : dst_nents;
}
@@ -1424,6 +1419,11 @@ static struct talitos_edesc *talitos_edesc_alloc(struct 
device *dev,
 DMA_BIDIRECTIONAL);
}
return edesc;
+
+report_failure:
+   dev_err(dev, "Invalid number of src SG.\n");
+set_error_code:
+   err = ERR_PTR(-EINVAL);
  error_sg:
if (iv_dma)
dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);



Another solution could be to move the dma_map_single() of iv_dma after 
the kmalloc(), in that case we could directly return from the other 
error cases instead of having the unmap iv_dma first.


Christophe


Re: [PATCH 17/18] crypto: talitos - chain in buffered data for ahash on SEC1

2018-03-02 Thread Christophe LEROY



Le 02/03/2018 à 18:27, Horia Geantă a écrit :

On 10/6/2017 4:05 PM, Christophe Leroy wrote:
[...]

@@ -1778,6 +1814,36 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
if (is_sec1 && from_talitos_ptr_len(>ptr[3], true) == 0)
talitos_handle_buggy_hash(ctx, edesc, >ptr[3]);
  
+	if (is_sec1 && req_ctx->nbuf && length) {

+   struct talitos_desc *desc2 = desc + 1;
+   dma_addr_t next_desc;

[...]

+   next_desc = dma_map_single(dev, >hdr1, TALITOS_DESC_SIZE,
+  DMA_BIDIRECTIONAL);
+   desc->next_desc = cpu_to_be32(next_desc);

Where is desc->next_desc initialized for the !is_sec1 case?
Memory allocation is done using kmalloc(), and since desc->next_desc is checked
in some cases also for SEC 2.x+, it should be initialized to 0.


See 
https://elixir.bootlin.com/linux/v4.16-rc3/source/drivers/crypto/talitos.c#L1411


edesc = kmalloc(alloc_len, GFP_DMA | flags);
if (!edesc) {
dev_err(dev, "could not allocate edescriptor\n");
err = ERR_PTR(-ENOMEM);
goto error_sg;
}
memset(>desc, 0, sizeof(edesc->desc));


Christophe


[PATCH 1/2] crypto: talitos - don't persistently map req_ctx->hw_context and req_ctx->buf

2018-02-26 Thread Christophe Leroy
Commit 49f9783b0cea ("crypto: talitos - do hw_context DMA mapping
outside the requests") introduced a persistent dma mapping of
req_ctx->hw_context
Commit 37b5e8897eb5 ("crypto: talitos - chain in buffered data for ahash
on SEC1") introduced a persistent dma mapping of req_ctx->buf

As there is no destructor for req_ctx (the request context), the
associated dma handlers where set in ctx (the tfm context). This is
wrong as several hash operations can run with the same ctx.

This patch removes this persistent mapping.

Reported-by: Horia Geanta <horia.gea...@nxp.com>
Fixes: 49f9783b0cea ("crypto: talitos - do hw_context DMA mapping outside the 
requests")
Fixes: 37b5e8897eb5 ("crypto: talitos - chain in buffered data for ahash on 
SEC1")
Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 132 ---
 1 file changed, 44 insertions(+), 88 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 6882fa2f8bad..bb44df1c1f2d 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -832,8 +832,6 @@ struct talitos_ctx {
unsigned int keylen;
unsigned int enckeylen;
unsigned int authkeylen;
-   dma_addr_t dma_buf;
-   dma_addr_t dma_hw_context;
 };
 
 #define HASH_MAX_BLOCK_SIZESHA512_BLOCK_SIZE
@@ -1690,9 +1688,30 @@ static void common_nonsnoop_hash_unmap(struct device 
*dev,
   struct ahash_request *areq)
 {
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
+   struct talitos_desc *desc = >desc;
+   struct talitos_desc *desc2 = desc + 1;
+
+   unmap_single_talitos_ptr(dev, >desc.ptr[5], DMA_FROM_DEVICE);
+   if (desc->next_desc &&
+   desc->ptr[5].ptr != desc2->ptr[5].ptr)
+   unmap_single_talitos_ptr(dev, >ptr[5], DMA_FROM_DEVICE);
 
talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0);
 
+   /* When using hashctx-in, must unmap it. */
+   if (from_talitos_ptr_len(>desc.ptr[1], is_sec1))
+   unmap_single_talitos_ptr(dev, >desc.ptr[1],
+DMA_TO_DEVICE);
+   else if (desc->next_desc)
+   unmap_single_talitos_ptr(dev, >ptr[1],
+DMA_TO_DEVICE);
+
+   if (is_sec1 && req_ctx->nbuf)
+   unmap_single_talitos_ptr(dev, >ptr[3],
+DMA_TO_DEVICE);
+
if (edesc->dma_len)
dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
 DMA_BIDIRECTIONAL);
@@ -1766,8 +1785,10 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
 
/* hash context in */
if (!req_ctx->first || req_ctx->swinit) {
-   to_talitos_ptr(>ptr[1], ctx->dma_hw_context,
-  req_ctx->hw_context_size, is_sec1);
+   map_single_talitos_ptr(dev, >ptr[1],
+  req_ctx->hw_context_size,
+  (char *)req_ctx->hw_context,
+  DMA_TO_DEVICE);
req_ctx->swinit = 0;
}
/* Indicate next op is not the first. */
@@ -1793,10 +1814,9 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
 * data in
 */
if (is_sec1 && req_ctx->nbuf) {
-   dma_addr_t dma_buf = ctx->dma_buf + req_ctx->buf_idx *
-   HASH_MAX_BLOCK_SIZE;
-
-   to_talitos_ptr(>ptr[3], dma_buf, req_ctx->nbuf, is_sec1);
+   map_single_talitos_ptr(dev, >ptr[3], req_ctx->nbuf,
+  req_ctx->buf[req_ctx->buf_idx],
+  DMA_TO_DEVICE);
} else {
sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
  >ptr[3], sg_count, offset, 0);
@@ -1812,8 +1832,9 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
   crypto_ahash_digestsize(tfm),
   areq->result, DMA_FROM_DEVICE);
else
-   to_talitos_ptr(>ptr[5], ctx->dma_hw_context,
-  req_ctx->hw_context_size, is_sec1);
+   map_single_talitos_ptr(dev, >ptr[5],
+  req_ctx->hw_context_size,
+  req_ctx->hw_context, DMA_FROM_DEVICE);
 
/* last DWORD empty */
 
@@ -1832,9 +1853,14 @@ static int common_n

[PATCH 2/2] crypto: talitos - do not perform unnecessary dma synchronisation

2018-02-26 Thread Christophe Leroy
req_ctx->hw_context is mainly used only by the HW. So it is not needed
to sync the HW and the CPU each time hw_context in DMA mapped.
This patch modifies the DMA mapping in order to limit synchronisation
to necessary situations.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 85 +++-
 1 file changed, 63 insertions(+), 22 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index bb44df1c1f2d..447cb8b1b16a 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -104,16 +104,34 @@ static void to_talitos_ptr_ext_or(struct talitos_ptr 
*ptr, u8 val, bool is_sec1)
 /*
  * map virtual single (contiguous) pointer to h/w descriptor pointer
  */
+static void __map_single_talitos_ptr(struct device *dev,
+struct talitos_ptr *ptr,
+unsigned int len, void *data,
+enum dma_data_direction dir,
+unsigned long attrs)
+{
+   dma_addr_t dma_addr = dma_map_single_attrs(dev, data, len, dir, attrs);
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
+
+   to_talitos_ptr(ptr, dma_addr, len, is_sec1);
+}
+
 static void map_single_talitos_ptr(struct device *dev,
   struct talitos_ptr *ptr,
   unsigned int len, void *data,
   enum dma_data_direction dir)
 {
-   dma_addr_t dma_addr = dma_map_single(dev, data, len, dir);
-   struct talitos_private *priv = dev_get_drvdata(dev);
-   bool is_sec1 = has_ftr_sec1(priv);
+   __map_single_talitos_ptr(dev, ptr, len, data, dir, 0);
+}
 
-   to_talitos_ptr(ptr, dma_addr, len, is_sec1);
+static void map_single_talitos_ptr_nosync(struct device *dev,
+ struct talitos_ptr *ptr,
+ unsigned int len, void *data,
+ enum dma_data_direction dir)
+{
+   __map_single_talitos_ptr(dev, ptr, len, data, dir,
+DMA_ATTR_SKIP_CPU_SYNC);
 }
 
 /*
@@ -1785,10 +1803,10 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
 
/* hash context in */
if (!req_ctx->first || req_ctx->swinit) {
-   map_single_talitos_ptr(dev, >ptr[1],
-  req_ctx->hw_context_size,
-  (char *)req_ctx->hw_context,
-  DMA_TO_DEVICE);
+   map_single_talitos_ptr_nosync(dev, >ptr[1],
+ req_ctx->hw_context_size,
+ req_ctx->hw_context,
+ DMA_TO_DEVICE);
req_ctx->swinit = 0;
}
/* Indicate next op is not the first. */
@@ -1832,9 +1850,10 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
   crypto_ahash_digestsize(tfm),
   areq->result, DMA_FROM_DEVICE);
else
-   map_single_talitos_ptr(dev, >ptr[5],
-  req_ctx->hw_context_size,
-  req_ctx->hw_context, DMA_FROM_DEVICE);
+   map_single_talitos_ptr_nosync(dev, >ptr[5],
+ req_ctx->hw_context_size,
+ req_ctx->hw_context,
+ DMA_FROM_DEVICE);
 
/* last DWORD empty */
 
@@ -1857,10 +1876,10 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
copy_talitos_ptr(>ptr[1], >ptr[1],
 is_sec1);
else
-   map_single_talitos_ptr(dev, >ptr[1],
-  req_ctx->hw_context_size,
-  req_ctx->hw_context,
-  DMA_TO_DEVICE);
+   map_single_talitos_ptr_nosync(dev, >ptr[1],
+ req_ctx->hw_context_size,
+ req_ctx->hw_context,
+ DMA_TO_DEVICE);
copy_talitos_ptr(>ptr[2], >ptr[2], is_sec1);
sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
  >ptr[3], sg_count, offset, 0);
@@ -1868,10 +1887,10 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
sync_needed = true;
 

Re: [PATCH 4.14, 4.9] crypto: talitos - fix Kernel Oops on hashing an empty file

2018-02-22 Thread Christophe LEROY



Le 22/02/2018 à 09:30, Horia Geantă a écrit :

On 2/22/2018 9:08 AM, Christophe Leroy wrote:

Upstream 87a81dce53b1ea61acaeefa5191a0376a2d1d721

Performing the hash of an empty file leads to a kernel Oops

[   44.504600] Unable to handle kernel paging request for data at address 
0x000c
[   44.512819] Faulting instruction address: 0xc02d2be8
[   44.524088] Oops: Kernel access of bad area, sig: 11 [#1]
[   44.529171] BE PREEMPT CMPC885
[   44.532232] CPU: 0 PID: 491 Comm: md5sum Not tainted 
4.15.0-rc8-00211-g3a968610b6ea #81
[   44.540814] NIP:  c02d2be8 LR: c02d2984 CTR: 
[   44.545812] REGS: c6813c90 TRAP: 0300   Not tainted  
(4.15.0-rc8-00211-g3a968610b6ea)
[   44.554223] MSR:  9032 <EE,ME,IR,DR,RI>  CR: 48222822  XER: 2000
[   44.560855] DAR: 000c DSISR: c000
[   44.560855] GPR00: c02d28fc c6813d40 c6828000 c646fa40 0001 0001 
0001 
[   44.560855] GPR08: 004c  c000bfcc  28222822 100280d4 
 10020008
[   44.560855] GPR16:  0020   10024008  
c646f9f0 c6179a10
[   44.560855] GPR24:  0001 c62f0018 c6179a10  c6367a30 
c62f c646f9c0
[   44.598542] NIP [c02d2be8] ahash_process_req+0x448/0x700
[   44.603751] LR [c02d2984] ahash_process_req+0x1e4/0x700
[   44.608868] Call Trace:
[   44.611329] [c6813d40] [c02d28fc] ahash_process_req+0x15c/0x700 (unreliable)
[   44.618302] [c6813d90] [c02060c4] hash_recvmsg+0x11c/0x210
[   44.623716] [c6813db0] [c0331354] ___sys_recvmsg+0x98/0x138
[   44.629226] [c6813eb0] [c03332c0] __sys_recvmsg+0x40/0x84
[   44.634562] [c6813f10] [c03336c0] SyS_socketcall+0xb8/0x1d4
[   44.640073] [c6813f40] [c000d1ac] ret_from_syscall+0x0/0x38
[   44.645530] Instruction dump:
[   44.648465] 38c1 7f63db78 4e800421 7c791b78 54690ffe 0f09 80ff0190 
2f87
[   44.656122] 40befe50 2f990001 409e0210 813f01bc <8129000c> b39e003a 7d29c214 
913e003c

This patch fixes that Oops by checking if src is NULL.

Fixes: 6a1e8d14156d4 ("crypto: talitos - making mapping helpers more generic")
Cc: <sta...@vger.kernel.org>
Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>


Isn't this needed also in 4.15.y?


It is already in 4.15, see 
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit/drivers/crypto/talitos.c?h=v4.15.4=e76a4b126d1e7fbd0124cb885331a45e9a24f32b


Christophe



Thanks,
Horia



[PATCH 4.14, 4.9] crypto: talitos - fix Kernel Oops on hashing an empty file

2018-02-21 Thread Christophe Leroy
Upstream 87a81dce53b1ea61acaeefa5191a0376a2d1d721

Performing the hash of an empty file leads to a kernel Oops

[   44.504600] Unable to handle kernel paging request for data at address 
0x000c
[   44.512819] Faulting instruction address: 0xc02d2be8
[   44.524088] Oops: Kernel access of bad area, sig: 11 [#1]
[   44.529171] BE PREEMPT CMPC885
[   44.532232] CPU: 0 PID: 491 Comm: md5sum Not tainted 
4.15.0-rc8-00211-g3a968610b6ea #81
[   44.540814] NIP:  c02d2be8 LR: c02d2984 CTR: 
[   44.545812] REGS: c6813c90 TRAP: 0300   Not tainted  
(4.15.0-rc8-00211-g3a968610b6ea)
[   44.554223] MSR:  9032 <EE,ME,IR,DR,RI>  CR: 48222822  XER: 2000
[   44.560855] DAR: 000c DSISR: c000
[   44.560855] GPR00: c02d28fc c6813d40 c6828000 c646fa40 0001 0001 
0001 
[   44.560855] GPR08: 004c  c000bfcc  28222822 100280d4 
 10020008
[   44.560855] GPR16:  0020   10024008  
c646f9f0 c6179a10
[   44.560855] GPR24:  0001 c62f0018 c6179a10  c6367a30 
c62f c646f9c0
[   44.598542] NIP [c02d2be8] ahash_process_req+0x448/0x700
[   44.603751] LR [c02d2984] ahash_process_req+0x1e4/0x700
[   44.608868] Call Trace:
[   44.611329] [c6813d40] [c02d28fc] ahash_process_req+0x15c/0x700 (unreliable)
[   44.618302] [c6813d90] [c02060c4] hash_recvmsg+0x11c/0x210
[   44.623716] [c6813db0] [c0331354] ___sys_recvmsg+0x98/0x138
[   44.629226] [c6813eb0] [c03332c0] __sys_recvmsg+0x40/0x84
[   44.634562] [c6813f10] [c03336c0] SyS_socketcall+0xb8/0x1d4
[   44.640073] [c6813f40] [c000d1ac] ret_from_syscall+0x0/0x38
[   44.645530] Instruction dump:
[   44.648465] 38c1 7f63db78 4e800421 7c791b78 54690ffe 0f09 80ff0190 
2f87
[   44.656122] 40befe50 2f990001 409e0210 813f01bc <8129000c> b39e003a 7d29c214 
913e003c

This patch fixes that Oops by checking if src is NULL.

Fixes: 6a1e8d14156d4 ("crypto: talitos - making mapping helpers more generic")
Cc: <sta...@vger.kernel.org>
Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index dff88838dce7..42913116620a 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1124,6 +1124,11 @@ int talitos_sg_map(struct device *dev, struct 
scatterlist *src,
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
 
+   if (!src) {
+   *ptr = zero_entry;
+   return 1;
+   }
+
to_talitos_ptr_len(ptr, len, is_sec1);
to_talitos_ptr_ext_set(ptr, 0, is_sec1);
 
-- 
2.13.3



Re: [PATCH 16/18] crypto: talitos - do hw_context DMA mapping outside the requests

2018-02-19 Thread Christophe LEROY



Le 19/02/2018 à 09:30, Horia Geantă a écrit :

On 2/19/2018 9:58 AM, Christophe LEROY wrote:

Le 18/02/2018 à 18:14, Horia Geantă a écrit :

There is no ahash_exit() callback mirroring ahash_init().

The clean-up of request ctx should be done in the last states of the hash flows
described here:
https://www.kernel.org/doc/html/latest/crypto/devel-algos.html#cipher-definition-with-struct-shash-alg-and-ahash-alg
for e.g. in the final() callback.


Unfortunatly it seems that we can't rely on those finalising functions
being called all the time.
If you look into test_ahash_jiffies() for instance, in case of error the
call of crypto_hash_final() is skipped.


If test_ahash_jiffies() errors before calling crypto_ahash_final(req), this
means a previous callback failed.
Accordingly, DMA unmapping should be performed also on the corresponding errors
paths in the driver.



And what about ALGIF path from user space ?
What if the user never calls the last sendmsg() which will call 
hash_finup() ?


Christophe


Re: [PATCH 16/18] crypto: talitos - do hw_context DMA mapping outside the requests

2018-02-18 Thread Christophe LEROY



Le 18/02/2018 à 18:14, Horia Geantă a écrit :

On 2/17/2018 6:32 PM, Christophe LEROY wrote:



Le 07/02/2018 à 15:39, Horia Geantă a écrit :

On 10/6/2017 4:06 PM, Christophe Leroy wrote:

At every request, we map and unmap the same hash hw_context.

This patch moves the dma mapping/unmapping in functions ahash_init()
and ahash_import().

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
   drivers/crypto/talitos.c | 80 
++--
   1 file changed, 57 insertions(+), 23 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index ebfd6d982ed6..d495649d5267 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -819,6 +819,7 @@ struct talitos_ctx {
unsigned int keylen;
unsigned int enckeylen;
unsigned int authkeylen;
+   dma_addr_t dma_hw_context;

This doesn't look correct.

talitos_ctx structure is the tfm context.
dma_hw_context is the IOVA of hw_context, located in talitos_ahash_req_ctx
structure (request context).


Yes but I have now found how I can know that the request context is
being released in order to unmap() dma at that time.
It is tricky to use the tmf context I agree, but at least I know when
tmf context get destroyed, ie in talitos_cra_exit_ahash()
The request context is created by ahash_request_alloc() and released by
ahash_request_free(). I have not found the way to call dma_unmap()
before ahash_request_free() gets called.



If there are multiple requests in flight for the same tfm, dma_hw_context will
be overwritten.


Before overwritting dma_hw_context, it is always released, see
talitos_cra_exit_ahash(), ahash_init(), ahash_import()


The problem is not the unmapping.
If there are two requests for the same tfm, then given the following sequence
1. tfm->ahash_init(req1)
tfm_ctx->dma_hw_context points to req1_ctx->hw_context
2. tfm->ahash_init(req2)
tfm_ctx->dma_hw_context [unmapped, then] points to req2_ctx->hw_context
i.e. req1 will use the hw_context of req2.



dma_hw_context needs to be moved in request context (talitos_ahash_req_ctx 
struct).


Any suggestion then on how to handle the issue explained above ?


There is no ahash_exit() callback mirroring ahash_init().

The clean-up of request ctx should be done in the last states of the hash flows
described here:
https://www.kernel.org/doc/html/latest/crypto/devel-algos.html#cipher-definition-with-struct-shash-alg-and-ahash-alg
for e.g. in the final() callback.


Unfortunatly it seems that we can't rely on those finalising functions 
being called all the time.
If you look into test_ahash_jiffies() for instance, in case of error the 
call of crypto_hash_final() is skipped.
So at the time being, I can't see any place to put the unmapping to be 
100% sure it will be done before the call of ahash_request_free()


Christophe



Hope this helps,
Horia



Re: [PATCH 16/18] crypto: talitos - do hw_context DMA mapping outside the requests

2018-02-17 Thread Christophe LEROY



Le 07/02/2018 à 15:39, Horia Geantă a écrit :

On 10/6/2017 4:06 PM, Christophe Leroy wrote:

At every request, we map and unmap the same hash hw_context.

This patch moves the dma mapping/unmapping in functions ahash_init()
and ahash_import().

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
  drivers/crypto/talitos.c | 80 ++--
  1 file changed, 57 insertions(+), 23 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index ebfd6d982ed6..d495649d5267 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -819,6 +819,7 @@ struct talitos_ctx {
unsigned int keylen;
unsigned int enckeylen;
unsigned int authkeylen;
+   dma_addr_t dma_hw_context;

This doesn't look correct.

talitos_ctx structure is the tfm context.
dma_hw_context is the IOVA of hw_context, located in talitos_ahash_req_ctx
structure (request context).


Yes but I have now found how I can know that the request context is 
being released in order to unmap() dma at that time.
It is tricky to use the tmf context I agree, but at least I know when 
tmf context get destroyed, ie in talitos_cra_exit_ahash()

The request context is created by ahash_request_alloc() and released by
ahash_request_free(). I have not found the way to call dma_unmap() 
before ahash_request_free() gets called.




If there are multiple requests in flight for the same tfm, dma_hw_context will
be overwritten.


Before overwritting dma_hw_context, it is always released, see 
talitos_cra_exit_ahash(), ahash_init(), ahash_import()




dma_hw_context needs to be moved in request context (talitos_ahash_req_ctx 
struct).


Any suggestion then on how to handle the issue explained above ?

Thanks
Christophe



Thanks,
Horia



[PATCH] crypto: talitos: fix Kernel Oops on hashing an empty file

2018-01-26 Thread Christophe Leroy
Performing the hash of an empty file leads to a kernel Oops

[   44.504600] Unable to handle kernel paging request for data at address 
0x000c
[   44.512819] Faulting instruction address: 0xc02d2be8
[   44.524088] Oops: Kernel access of bad area, sig: 11 [#1]
[   44.529171] BE PREEMPT CMPC885
[   44.532232] CPU: 0 PID: 491 Comm: md5sum Not tainted 
4.15.0-rc8-00211-g3a968610b6ea #81
[   44.540814] NIP:  c02d2be8 LR: c02d2984 CTR: 
[   44.545812] REGS: c6813c90 TRAP: 0300   Not tainted  
(4.15.0-rc8-00211-g3a968610b6ea)
[   44.554223] MSR:  9032 <EE,ME,IR,DR,RI>  CR: 48222822  XER: 2000
[   44.560855] DAR: 000c DSISR: c000
[   44.560855] GPR00: c02d28fc c6813d40 c6828000 c646fa40 0001 0001 
0001 
[   44.560855] GPR08: 004c  c000bfcc  28222822 100280d4 
 10020008
[   44.560855] GPR16:  0020   10024008  
c646f9f0 c6179a10
[   44.560855] GPR24:  0001 c62f0018 c6179a10  c6367a30 
c62f c646f9c0
[   44.598542] NIP [c02d2be8] ahash_process_req+0x448/0x700
[   44.603751] LR [c02d2984] ahash_process_req+0x1e4/0x700
[   44.608868] Call Trace:
[   44.611329] [c6813d40] [c02d28fc] ahash_process_req+0x15c/0x700 (unreliable)
[   44.618302] [c6813d90] [c02060c4] hash_recvmsg+0x11c/0x210
[   44.623716] [c6813db0] [c0331354] ___sys_recvmsg+0x98/0x138
[   44.629226] [c6813eb0] [c03332c0] __sys_recvmsg+0x40/0x84
[   44.634562] [c6813f10] [c03336c0] SyS_socketcall+0xb8/0x1d4
[   44.640073] [c6813f40] [c000d1ac] ret_from_syscall+0x0/0x38
[   44.645530] Instruction dump:
[   44.648465] 38c1 7f63db78 4e800421 7c791b78 54690ffe 0f09 80ff0190 
2f87
[   44.656122] 40befe50 2f990001 409e0210 813f01bc <8129000c> b39e003a 7d29c214 
913e003c

This patch fixes that Oops by checking if src is NULL.

Fixes: 6a1e8d14156d4 ("crypto: talitos - making mapping helpers more generic")
Cc: <sta...@vger.kernel.org>
Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 9c80e0cb1664..6882fa2f8bad 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1138,6 +1138,10 @@ static int talitos_sg_map(struct device *dev, struct 
scatterlist *src,
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
 
+   if (!src) {
+   to_talitos_ptr(ptr, 0, 0, is_sec1);
+   return 1;
+   }
if (sg_count == 1) {
to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1);
return sg_count;
-- 
2.13.3



Re: [PATCH v9 17/20] crypto: talitos: move to generic async completion

2017-10-17 Thread Christophe LEROY

Le 15/10/2017 à 11:20, Gilad Ben-Yossef a écrit :

The talitos driver starts several async crypto ops and  waits for their
completions. Move it over to generic code doing the same.

Signed-off-by: Gilad Ben-Yossef <gi...@benyossef.com>


Tested-by: Christophe Leroy <christophe.le...@c-s.fr>


---
  drivers/crypto/talitos.c | 38 +-
  1 file changed, 5 insertions(+), 33 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 5bd8191..9c80e0c 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -2160,22 +2160,6 @@ static int ahash_import(struct ahash_request *areq, 
const void *in)
return 0;
  }
  
-struct keyhash_result {

-   struct completion completion;
-   int err;
-};
-
-static void keyhash_complete(struct crypto_async_request *req, int err)
-{
-   struct keyhash_result *res = req->data;
-
-   if (err == -EINPROGRESS)
-   return;
-
-   res->err = err;
-   complete(>completion);
-}
-
  static int keyhash(struct crypto_ahash *tfm, const u8 *key, unsigned int 
keylen,
   u8 *hash)
  {
@@ -2183,10 +2167,10 @@ static int keyhash(struct crypto_ahash *tfm, const u8 
*key, unsigned int keylen,
  
  	struct scatterlist sg[1];

struct ahash_request *req;
-   struct keyhash_result hresult;
+   struct crypto_wait wait;
int ret;
  
-	init_completion();

+   crypto_init_wait();
  
  	req = ahash_request_alloc(tfm, GFP_KERNEL);

if (!req)
@@ -2195,25 +2179,13 @@ static int keyhash(struct crypto_ahash *tfm, const u8 
*key, unsigned int keylen,
/* Keep tfm keylen == 0 during hash of the long key */
ctx->keylen = 0;
ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
-  keyhash_complete, );
+  crypto_req_done, );
  
  	sg_init_one([0], key, keylen);
  
  	ahash_request_set_crypt(req, sg, hash, keylen);

-   ret = crypto_ahash_digest(req);
-   switch (ret) {
-   case 0:
-   break;
-   case -EINPROGRESS:
-   case -EBUSY:
-   ret = wait_for_completion_interruptible(
-   );
-   if (!ret)
-   ret = hresult.err;
-   break;
-   default:
-   break;
-   }
+   ret = crypto_wait_req(crypto_ahash_digest(req), );
+
ahash_request_free(req);
  
  	return ret;




Re: md5sum (from libkcapi) fails on kernel 4.9 but not on 4.13

2017-10-17 Thread Christophe LEROY

Hi Again Stephan

Le 17/10/2017 à 09:58, Christophe LEROY a écrit :

Hi Stephan,

Le 16/10/2017 à 23:10, Stephan Mueller a écrit :

Am Montag, 16. Oktober 2017, 08:53:00 CEST schrieb Christophe LEROY:

Hi Christophe,


Hi Stephan,

I get an issue with md5sum of a big file with kernel 4.9. It don't get
that issue with kernel 4.13.


The key to the difference in libkcapi is the following code:

static void _kcapi_handle_flags(struct kcapi_handle *handle)
...
 /* older interfaces only processed 16 pages in a row */
 handle->flags.alg_max_pages = _kcapi_kernver_ge(handle, 4, 
11, 0) ?

   UINT_MAX : ALG_MAX_PAGES;
...

This check is mainly for skcipher but it affects all cipher types. 
Thus, on
older kernels, only 16 pages are injected into the kernel with splice 
and then
it is reverted to sendmsg. Again, this logic is not so much of an 
issue for

algif_hash, but rather for algif_skcipher and algif_aead.


When I do an strace, I see a difference in the calls: at the end of the
file, with 4.9 md5sum uses sendmsg() for the last block while with 4.13
it uses splice() as for all the previous blocks.

The problem is that the last block has a size over 32kbytes, which is
the maximum size the talitos driver accepts to hash at once.
It looks like sendmsg() sends the entire block to the crypto driver
while splice() calls the crypto driver with blocks of page size.


I understand that your driver has this 32kb limit. But I am not sure 
what the
difference between the handling of the sendmsg and the splice 
invocation is.
According to the strace, the splice accepted 256kb of data. Looking 
into the
hash_sendpage function implementing the backend of this splice system 
call, it
simply performs an update invocation with this buffer size. I.e. it 
invokes
your driver with 256kb of data. The sendmsg first performs a 
copy_from_user

with the maximum limit of 16 * PAGE_SIZE (see the limit variable in
hash_sendmsg) and then invokes the update function.


As far as I can see, hash_sendpage() is called with one single page, of 
size 16kb in my setup. If I understand correct, the loop over every page 
is implemented in __splice_from_pipe().




So, I am not sure why the sendmsg call chokes where the sendpage call
succeeds.


As far as I can see, the sendmsg() calls the update function with the 
full buffer, which in my case is over the 32kb limit of the driver.




If you tamper with the code shown above from libkcapi and set 
alg_max_pages to
a low value, the library reverts to sendmsg after the given number of 
pages.


Couldn't we get the libkcapi to splice until the last full page, then 
only use sendmsg() for the last chunk once it is smaller than an entire 
page ?





Note that the test reported above is done with version 0.14.0

I've now tried a test with 1.0.0, and there seems to be another big 
issue: the error returned by sendmsg() is not taken into account anymore:


...
vmsplice(5, 
[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
558080}], 1, SPLICE_F_MORE|SPLICE_F_GIFT) = 262144

splice(4, NULL, 7, NULL, 262144, SPLICE_F_MORE) = 262144
vmsplice(5, 
[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
295936}], 1, SPLICE_F_MORE|SPLICE_F_GIFT) = 262144

splice(4, NULL, 7, NULL, 262144, SPLICE_F_MORE) = 262144
sendmsg(7, {msg_name(0)=NULL, 
msg_iov(1)=[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
33792}], msg_controllen=0, msg_flags=0}, MSG_MORE) = -1 EINVAL (Invalid 
argument)
sendmsg(7, {msg_name(0)=NULL, 
msg_iov(1)=[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
33814}], msg_controllen=0, msg_flags=0}, MSG_MORE) = -1 EINVAL (Invalid 
argument)
sendmsg(7, {msg_name(0)=NULL, 
msg_iov(1)=[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
33836}], msg_controllen=0, msg_flags=0}, MSG_MORE) = -1 EINVAL (Invalid 
argument)
sendmsg(7, {msg_name(0)=NULL, 
msg_iov(1)=[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
33858}], msg_controllen=0, msg_flags=0}, MSG_MORE) = -1 EINVAL (Invalid 
argument)
sendmsg(7, {msg_name(0)=NULL, 
msg_iov(1)=[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
33880}], msg_controllen=0, msg_flags=0}, MSG_MORE) = -1 EINVAL (Invalid 
argument)
sendmsg(7, {msg_name(0)=NULL, 
msg_iov(1)=[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
33902}], msg_controllen=0, msg_flags=0}, MSG_MORE) = -1 EINVAL (Invalid 
argument)
sendmsg(7, {msg_name(0)=NULL, 
msg_iov(1)=[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
33924}], msg_controllen=0, msg_flags=0}, MSG_MORE) = -1 EINVAL (Invalid 
argument)
sendmsg(7, {msg_name(0)=NULL, 
msg_iov(1)=[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
33946}], msg_controllen=0, 

Re: md5sum (from libkcapi) fails on kernel 4.9 but not on 4.13

2017-10-17 Thread Christophe LEROY

Hi Stephan,

Le 16/10/2017 à 23:10, Stephan Mueller a écrit :

Am Montag, 16. Oktober 2017, 08:53:00 CEST schrieb Christophe LEROY:

Hi Christophe,


Hi Stephan,

I get an issue with md5sum of a big file with kernel 4.9. It don't get
that issue with kernel 4.13.


The key to the difference in libkcapi is the following code:

static void _kcapi_handle_flags(struct kcapi_handle *handle)
...
 /* older interfaces only processed 16 pages in a row */
 handle->flags.alg_max_pages = _kcapi_kernver_ge(handle, 4, 11, 0) ?
   UINT_MAX : ALG_MAX_PAGES;
...

This check is mainly for skcipher but it affects all cipher types. Thus, on
older kernels, only 16 pages are injected into the kernel with splice and then
it is reverted to sendmsg. Again, this logic is not so much of an issue for
algif_hash, but rather for algif_skcipher and algif_aead.


When I do an strace, I see a difference in the calls: at the end of the
file, with 4.9 md5sum uses sendmsg() for the last block while with 4.13
it uses splice() as for all the previous blocks.

The problem is that the last block has a size over 32kbytes, which is
the maximum size the talitos driver accepts to hash at once.
It looks like sendmsg() sends the entire block to the crypto driver
while splice() calls the crypto driver with blocks of page size.


I understand that your driver has this 32kb limit. But I am not sure what the
difference between the handling of the sendmsg and the splice invocation is.
According to the strace, the splice accepted 256kb of data. Looking into the
hash_sendpage function implementing the backend of this splice system call, it
simply performs an update invocation with this buffer size. I.e. it invokes
your driver with 256kb of data. The sendmsg first performs a copy_from_user
with the maximum limit of 16 * PAGE_SIZE (see the limit variable in
hash_sendmsg) and then invokes the update function.


As far as I can see, hash_sendpage() is called with one single page, of 
size 16kb in my setup. If I understand correct, the loop over every page 
is implemented in __splice_from_pipe().




So, I am not sure why the sendmsg call chokes where the sendpage call
succeeds.


As far as I can see, the sendmsg() calls the update function with the 
full buffer, which in my case is over the 32kb limit of the driver.




If you tamper with the code shown above from libkcapi and set alg_max_pages to
a low value, the library reverts to sendmsg after the given number of pages.


Couldn't we get the libkcapi to splice until the last full page, then 
only use sendmsg() for the last chunk once it is smaller than an entire 
page ?


Thanks
Christophe


md5sum (from libkcapi) fails on kernel 4.9 but not on 4.13

2017-10-16 Thread Christophe LEROY

Hi Stephan,

I get an issue with md5sum of a big file with kernel 4.9. It don't get 
that issue with kernel 4.13.


When I do an strace, I see a difference in the calls: at the end of the 
file, with 4.9 md5sum uses sendmsg() for the last block while with 4.13 
it uses splice() as for all the previous blocks.


The problem is that the last block has a size over 32kbytes, which is 
the maximum size the talitos driver accepts to hash at once.
It looks like sendmsg() sends the entire block to the crypto driver 
while splice() calls the crypto driver with blocks of page size.


Is there a way to workaround this issue on 4.9 ? Is there a way to avoid 
talitos ahash being called with more than 32kbytes of data ?


strace with 4.9 kernel:

...
vmsplice(5, 
[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
558080}], 1, SPLICE_F_MORE|SPLICE_F_GIFT) = 262144

splice(4, NULL, 7, NULL, 262144, SPLICE_F_MORE) = 262144
vmsplice(5, 
[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
295936}], 1, SPLICE_F_MORE|SPLICE_F_GIFT) = 262144

splice(4, NULL, 7, NULL, 262144, SPLICE_F_MORE) = 262144
sendmsg(7, {msg_name(0)=NULL, 
msg_iov(1)=[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
33792}], msg_controllen=0, msg_flags=0}, MSG_MORE) = -1 EINVAL (Invalid 
argument)

write(2, "Generation of hash for file test"..., 45) = 45
...


strace with 4.13 kernel:

...
vmsplice(5, 
[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
558080}], 1, SPLICE_F_MORE|SPLICE_F_GIFT) = 262144

splice(4, NULL, 7, NULL, 262144, SPLICE_F_MORE) = 262144
vmsplice(5, 
[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
295936}], 1, SPLICE_F_MORE|SPLICE_F_GIFT) = 262144

splice(4, NULL, 7, NULL, 262144, SPLICE_F_MORE) = 262144
vmsplice(5, 
[{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 
33792}], 1, SPLICE_F_MORE|SPLICE_F_GIFT) = 33792

splice(4, NULL, 7, NULL, 33792, SPLICE_F_MORE) = 33792
recvmsg(7, {msg_name(0)=NULL, 
msg_iov(1)=[{"\"\35|\3273\302\35\252\4\276l\210\315B\210^", 64}], 
msg_controllen=0, msg_flags=0}, 0) = 16

fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(204, 46), ...}) = 0
ioctl(1, TCGETS, {B115200 opost isig icanon echo ...}) = 0
write(1, "221d7cd733c21daa04be6c88cd42885e"..., 39) = 39
...

Thanks
Christophe


[PATCH 00/18] crypto: talitos - fixes and performance improvement

2017-10-06 Thread Christophe Leroy
This serie fixes and improves the talitos crypto driver.

First 6 patchs are fixes of failures reported by the new tests in the
kernel crypto test manager.

The 8 following patches are cleanups and simplifications.

The last 4 ones are performance improvement. The main improvement is
in the one before the last, it divides by 2 the time needed for a md5
hash on the SEC1.

Christophe Leroy (18):
  crypto: talitos - fix AEAD test failures
  crypto: talitos - fix memory corruption on SEC2
  crypto: talitos - fix setkey to check key weakness
  crypto: talitos - fix AEAD for sha224 on non sha224 capable chips
  crypto: talitos - fix use of sg_link_tbl_len
  crypto: talitos - fix ctr-aes-talitos
  crypto: talitos - zeroize the descriptor with memset()
  crypto: talitos - declare local functions static
  crypto: talitos - use devm_kmalloc()
  crypto: talitos - use of_property_read_u32()
  crypto: talitos - use devm_ioremap()
  crypto: talitos - don't check the number of channels at each interrupt
  crypto: talitos - remove to_talitos_ptr_len()
  crypto: talitos - simplify tests in ipsec_esp()
  crypto: talitos - DMA map key in setkey()
  crypto: talitos - do hw_context DMA mapping outside the requests
  crypto: talitos - chain in buffered data for ahash on SEC1
  crypto: talitos - avoid useless copy

 drivers/crypto/talitos.c | 544 ++-
 drivers/crypto/talitos.h |   7 +-
 2 files changed, 356 insertions(+), 195 deletions(-)

-- 
2.13.3



[PATCH 01/18] crypto: talitos - fix AEAD test failures

2017-10-06 Thread Christophe Leroy
 72 63
0040: 74 65 20 73 6f 54 20 6f 61 4d 79 6e 53 20 63 65
0050: 65 72 73 74 54 20 6f 6f 4d 20 6e 61 20 79 65 53
0060: 72 63 74 65 20 73 6f 54 20 6f 61 4d 79 6e 53 20
0070: 63 65 65 72 73 74 54 20 6f 6f 4d 20 6e 61 0a 79
0080: c0 50 f1 ac c0 50 f3 38 c0 50 f3 94 c0 50 f5 30
0090: c0 99 74 3c c0 96 e5 b8 c0 96 e9 20 c0 00 3d dc

This patch fixes that.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index dff88838dce7..cd8a37e60259 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1232,12 +1232,11 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
sg_link_tbl_len += authsize;
}
 
-   sg_count = talitos_sg_map(dev, areq->src, cryptlen, edesc,
- >ptr[4], sg_count, areq->assoclen,
- tbl_off);
+   ret = talitos_sg_map(dev, areq->src, cryptlen, edesc, >ptr[4],
+sg_count, areq->assoclen, tbl_off);
 
-   if (sg_count > 1) {
-   tbl_off += sg_count;
+   if (ret > 1) {
+   tbl_off += ret;
sync_needed = true;
}
 
-- 
2.13.3



[PATCH 05/18] crypto: talitos - fix use of sg_link_tbl_len

2017-10-06 Thread Christophe Leroy
sg_link_tbl_len shall be used instead of cryptlen, otherwise
SECs which perform HW CICV verification will fail.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index b7184f305867..cf5c9701b898 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1232,8 +1232,8 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
sg_link_tbl_len += authsize;
}
 
-   ret = talitos_sg_map(dev, areq->src, cryptlen, edesc, >ptr[4],
-sg_count, areq->assoclen, tbl_off);
+   ret = talitos_sg_map(dev, areq->src, sg_link_tbl_len, edesc,
+>ptr[4], sg_count, areq->assoclen, tbl_off);
 
if (ret > 1) {
tbl_off += ret;
-- 
2.13.3



[PATCH 03/18] crypto: talitos - fix setkey to check key weakness

2017-10-06 Thread Christophe Leroy
Crypto manager test report the following failures:
[3.061081] alg: skcipher: setkey failed on test 5 for ecb-des-talitos: 
flags=100
[3.069342] alg: skcipher-ddst: setkey failed on test 5 for ecb-des-talitos: 
flags=100
[3.077754] alg: skcipher-ddst: setkey failed on test 5 for ecb-des-talitos: 
flags=100

This is due to setkey being expected to detect weak keys.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 1e799886c57d..8aa1212086f4 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1507,12 +1507,20 @@ static int ablkcipher_setkey(struct crypto_ablkcipher 
*cipher,
 const u8 *key, unsigned int keylen)
 {
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+   u32 tmp[DES_EXPKEY_WORDS];
 
if (keylen > TALITOS_MAX_KEY_SIZE) {
crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
}
 
+   if (unlikely(crypto_ablkcipher_get_flags(cipher) &
+CRYPTO_TFM_REQ_WEAK_KEY) &&
+   !des_ekey(tmp, key)) {
+   crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_WEAK_KEY);
+   return -EINVAL;
+   }
+
memcpy(>key, key, keylen);
ctx->keylen = keylen;
 
-- 
2.13.3



[PATCH 04/18] crypto: talitos - fix AEAD for sha224 on non sha224 capable chips

2017-10-06 Thread Christophe Leroy
sha224 AEAD test fails with:

[2.803125] talitos ff02.crypto: DEUISR 0x_
[2.808743] talitos ff02.crypto: MDEUISR 0x8010_
[2.814678] talitos ff02.crypto: DESCBUF 0x20731f21_0018
[2.820616] talitos ff02.crypto: DESCBUF 0x0628d64c_0010
[2.826554] talitos ff02.crypto: DESCBUF 0x0631005c_0018
[2.832492] talitos ff02.crypto: DESCBUF 0x0628d664_0008
[2.838430] talitos ff02.crypto: DESCBUF 0x061b13a0_0080
[2.844369] talitos ff02.crypto: DESCBUF 0x0631006c_0080
[2.850307] talitos ff02.crypto: DESCBUF 0x0631006c_0018
[2.856245] talitos ff02.crypto: DESCBUF 0x063100ec_
[2.884972] talitos ff02.crypto: failed to reset channel 0
[2.890503] talitos ff02.crypto: done overflow, internal time out, or 
rngu error: ISR 0x2000_0002
[2.900652] alg: aead: encryption failed on test 1 for 
authenc-hmac-sha224-cbc-3des-talitos: ret=22

This is due to SHA224 not being supported by the HW. Allthough for
hash we are able to init the hash context by SW, it is not
possible for AEAD. Therefore SHA224 AEAD has to be deactivated.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 8aa1212086f4..b7184f305867 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -3068,6 +3068,11 @@ static struct talitos_crypto_alg 
*talitos_alg_alloc(struct device *dev,
t_alg->algt.alg.aead.setkey = aead_setkey;
t_alg->algt.alg.aead.encrypt = aead_encrypt;
t_alg->algt.alg.aead.decrypt = aead_decrypt;
+   if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
+   !strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) {
+   kfree(t_alg);
+   return ERR_PTR(-ENOTSUPP);
+   }
break;
case CRYPTO_ALG_TYPE_AHASH:
alg = _alg->algt.alg.hash.halg.base;
-- 
2.13.3



[PATCH 02/18] crypto: talitos - fix memory corruption on SEC2

2017-10-06 Thread Christophe Leroy
xc8
[2.930853] [c0d4bf60] [c007f064] cpu_startup_entry+0xe4/0x190
[2.936707] [c0d4bfb0] [c096c434] start_kernel+0x3f4/0x408
[2.942198] [c0d4bff0] [3438] 0x3438
[2.946137] FIX dma-kmalloc-256: Restoring 0xde858108-0xde85810b=0xcc
[2.946137]
[2.954158] FIX dma-kmalloc-256: Object at 0xde858008 not freed

This patch reworks the handling of the CICV out in order
to properly handle all cases.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 42 --
 1 file changed, 28 insertions(+), 14 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index cd8a37e60259..1e799886c57d 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1247,14 +1247,15 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
}
 
-   sg_count = talitos_sg_map(dev, areq->dst, cryptlen, edesc,
- >ptr[5], sg_count, areq->assoclen,
- tbl_off);
+   ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, >ptr[5],
+sg_count, areq->assoclen, tbl_off);
 
if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
to_talitos_ptr_ext_or(>ptr[5], authsize, is_sec1);
 
-   if (sg_count > 1) {
+   /* ICV data */
+   if (ret > 1) {
+   tbl_off += ret;
edesc->icv_ool = true;
sync_needed = true;
 
@@ -1264,9 +1265,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
 sizeof(struct talitos_ptr) + authsize;
 
/* Add an entry to the link table for ICV data */
-   tbl_ptr += sg_count - 1;
-   to_talitos_ptr_ext_set(tbl_ptr, 0, is_sec1);
-   tbl_ptr++;
+   to_talitos_ptr_ext_set(tbl_ptr - 1, 0, is_sec1);
to_talitos_ptr_ext_set(tbl_ptr, DESC_PTR_LNKTBL_RETURN,
   is_sec1);
to_talitos_ptr_len(tbl_ptr, authsize, is_sec1);
@@ -1274,18 +1273,33 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
/* icv data follows link tables */
to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl + offset,
   is_sec1);
+   } else {
+   dma_addr_t addr = edesc->dma_link_tbl;
+
+   if (is_sec1)
+   addr += areq->assoclen + cryptlen;
+   else
+   addr += sizeof(struct talitos_ptr) * tbl_off;
+
+   to_talitos_ptr(>ptr[6], addr, is_sec1);
+   to_talitos_ptr_len(>ptr[6], authsize, is_sec1);
+   }
+   } else if (!(desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)) {
+   ret = talitos_sg_map(dev, areq->dst, authsize, edesc,
+>ptr[6], sg_count, areq->assoclen +
+ cryptlen,
+tbl_off);
+   if (ret > 1) {
+   tbl_off += ret;
+   edesc->icv_ool = true;
+   sync_needed = true;
+   } else {
+   edesc->icv_ool = false;
}
} else {
edesc->icv_ool = false;
}
 
-   /* ICV data */
-   if (!(desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)) {
-   to_talitos_ptr_len(>ptr[6], authsize, is_sec1);
-   to_talitos_ptr(>ptr[6], edesc->dma_link_tbl +
-  areq->assoclen + cryptlen, is_sec1);
-   }
-
/* iv out */
if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
map_single_talitos_ptr(dev, >ptr[6], ivsize, ctx->iv,
-- 
2.13.3



[PATCH 08/18] crypto: talitos - declare local functions static

2017-10-06 Thread Christophe Leroy
talitos_handle_buggy_hash() and talitos_sg_map() are only used
locally, make them static

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 266e7e626e12..dd6b1fc90020 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1113,7 +1113,7 @@ static int sg_to_link_tbl_offset(struct scatterlist *sg, 
int sg_count,
return count;
 }
 
-int talitos_sg_map(struct device *dev, struct scatterlist *src,
+static int talitos_sg_map(struct device *dev, struct scatterlist *src,
   unsigned int len, struct talitos_edesc *edesc,
   struct talitos_ptr *ptr,
   int sg_count, unsigned int offset, int tbl_off)
@@ -1721,7 +1721,7 @@ static void ahash_done(struct device *dev,
  * SEC1 doesn't like hashing of 0 sized message, so we do the padding
  * ourself and submit a padded block
  */
-void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
+static void talitos_handle_buggy_hash(struct talitos_ctx *ctx,
   struct talitos_edesc *edesc,
   struct talitos_ptr *ptr)
 {
-- 
2.13.3



[PATCH 09/18] crypto: talitos - use devm_kmalloc()

2017-10-06 Thread Christophe Leroy
Replace kmalloc() by devm_kmalloc()

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 30 --
 1 file changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index dd6b1fc90020..2a53d0f2a869 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -2993,17 +2993,11 @@ static int talitos_remove(struct platform_device *ofdev)
break;
}
list_del(_alg->entry);
-   kfree(t_alg);
}
 
if (hw_supports(dev, DESC_HDR_SEL0_RNG))
talitos_unregister_rng(dev);
 
-   for (i = 0; priv->chan && i < priv->num_channels; i++)
-   kfree(priv->chan[i].fifo);
-
-   kfree(priv->chan);
-
for (i = 0; i < 2; i++)
if (priv->irq[i]) {
free_irq(priv->irq[i], dev);
@@ -3016,8 +3010,6 @@ static int talitos_remove(struct platform_device *ofdev)
 
iounmap(priv->reg);
 
-   kfree(priv);
-
return 0;
 }
 
@@ -3029,7 +3021,8 @@ static struct talitos_crypto_alg 
*talitos_alg_alloc(struct device *dev,
struct talitos_crypto_alg *t_alg;
struct crypto_alg *alg;
 
-   t_alg = kzalloc(sizeof(struct talitos_crypto_alg), GFP_KERNEL);
+   t_alg = devm_kzalloc(dev, sizeof(struct talitos_crypto_alg),
+GFP_KERNEL);
if (!t_alg)
return ERR_PTR(-ENOMEM);
 
@@ -3053,7 +3046,7 @@ static struct talitos_crypto_alg 
*talitos_alg_alloc(struct device *dev,
t_alg->algt.alg.aead.decrypt = aead_decrypt;
if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
!strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) {
-   kfree(t_alg);
+   devm_kfree(dev, t_alg);
return ERR_PTR(-ENOTSUPP);
}
break;
@@ -3073,7 +3066,7 @@ static struct talitos_crypto_alg 
*talitos_alg_alloc(struct device *dev,
 
if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
!strncmp(alg->cra_name, "hmac", 4)) {
-   kfree(t_alg);
+   devm_kfree(dev, t_alg);
return ERR_PTR(-ENOTSUPP);
}
if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
@@ -3088,7 +3081,7 @@ static struct talitos_crypto_alg 
*talitos_alg_alloc(struct device *dev,
break;
default:
dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type);
-   kfree(t_alg);
+   devm_kfree(dev, t_alg);
return ERR_PTR(-EINVAL);
}
 
@@ -3169,7 +3162,7 @@ static int talitos_probe(struct platform_device *ofdev)
int i, err;
int stride;
 
-   priv = kzalloc(sizeof(struct talitos_private), GFP_KERNEL);
+   priv = devm_kzalloc(dev, sizeof(struct talitos_private), GFP_KERNEL);
if (!priv)
return -ENOMEM;
 
@@ -3267,8 +3260,8 @@ static int talitos_probe(struct platform_device *ofdev)
}
}
 
-   priv->chan = kzalloc(sizeof(struct talitos_channel) *
-priv->num_channels, GFP_KERNEL);
+   priv->chan = devm_kzalloc(dev, sizeof(struct talitos_channel) *
+  priv->num_channels, GFP_KERNEL);
if (!priv->chan) {
dev_err(dev, "failed to allocate channel management space\n");
err = -ENOMEM;
@@ -3285,8 +3278,9 @@ static int talitos_probe(struct platform_device *ofdev)
spin_lock_init(>chan[i].head_lock);
spin_lock_init(>chan[i].tail_lock);
 
-   priv->chan[i].fifo = kzalloc(sizeof(struct talitos_request) *
-priv->fifo_len, GFP_KERNEL);
+   priv->chan[i].fifo = devm_kzalloc(dev,
+   sizeof(struct talitos_request) *
+   priv->fifo_len, GFP_KERNEL);
if (!priv->chan[i].fifo) {
dev_err(dev, "failed to allocate request fifo %d\n", i);
err = -ENOMEM;
@@ -3352,7 +3346,7 @@ static int talitos_probe(struct platform_device *ofdev)
if (err) {
dev_err(dev, "%s alg registration failed\n",
alg->cra_driver_name);
-   kfree(t_alg);
+   devm_kfree(dev, t_alg);
} else
list_add_tail(_alg->entry, >alg_list);
}
-- 
2.13.3



[PATCH 12/18] crypto: talitos - don't check the number of channels at each interrupt

2017-10-06 Thread Christophe Leroy
The number of channels is known from the beginning, no need to
test it everytime.
This patch defines two additional done functions handling only channel 0.
Then the probe registers the correct one based on the number of channels.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 27 +++
 drivers/crypto/talitos.h |  4 
 2 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 83b2a70a1ba7..e7e1bada03df 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -390,8 +390,6 @@ static void talitos1_done_##name(unsigned long data)
\
\
if (ch_done_mask & 0x1000)  \
flush_channel(dev, 0, 0, 0);\
-   if (priv->num_channels == 1)\
-   goto out;   \
if (ch_done_mask & 0x4000)  \
flush_channel(dev, 1, 0, 0);\
if (ch_done_mask & 0x0001)  \
@@ -399,7 +397,6 @@ static void talitos1_done_##name(unsigned long data)
\
if (ch_done_mask & 0x0004)  \
flush_channel(dev, 3, 0, 0);\
\
-out:   \
/* At this point, all completed channels have been processed */ \
/* Unmask done interrupts for channels completed later on. */   \
spin_lock_irqsave(>reg_lock, flags);  \
@@ -409,6 +406,7 @@ out:
\
 }
 
 DEF_TALITOS1_DONE(4ch, TALITOS1_ISR_4CHDONE)
+DEF_TALITOS1_DONE(ch0, TALITOS1_ISR_CH_0_DONE)
 
 #define DEF_TALITOS2_DONE(name, ch_done_mask)  \
 static void talitos2_done_##name(unsigned long data)   \
@@ -419,8 +417,6 @@ static void talitos2_done_##name(unsigned long data)
\
\
if (ch_done_mask & 1)   \
flush_channel(dev, 0, 0, 0);\
-   if (priv->num_channels == 1)\
-   goto out;   \
if (ch_done_mask & (1 << 2))\
flush_channel(dev, 1, 0, 0);\
if (ch_done_mask & (1 << 4))\
@@ -428,7 +424,6 @@ static void talitos2_done_##name(unsigned long data)
\
if (ch_done_mask & (1 << 6))\
flush_channel(dev, 3, 0, 0);\
\
-out:   \
/* At this point, all completed channels have been processed */ \
/* Unmask done interrupts for channels completed later on. */   \
spin_lock_irqsave(>reg_lock, flags);  \
@@ -438,6 +433,7 @@ out:
\
 }
 
 DEF_TALITOS2_DONE(4ch, TALITOS2_ISR_4CHDONE)
+DEF_TALITOS2_DONE(ch0, TALITOS2_ISR_CH_0_DONE)
 DEF_TALITOS2_DONE(ch0_2, TALITOS2_ISR_CH_0_2_DONE)
 DEF_TALITOS2_DONE(ch1_3, TALITOS2_ISR_CH_1_3_DONE)
 
@@ -3237,17 +3233,24 @@ static int talitos_probe(struct platform_device *ofdev)
goto err_out;
 
if (of_device_is_compatible(np, "fsl,sec1.0")) {
-   tasklet_init(>done_task[0], talitos1_done_4ch,
-(unsigned long)dev);
-   } else {
-   if (!priv->irq[1]) {
-   tasklet_init(>done_task[0], talitos2_done_4ch,
+   if (priv->num_channels == 1)
+   tasklet_init(>done_task[0], talitos1_done_ch0,
 (unsigned long)dev);
-   } else {
+   else
+   tasklet_init(>done_task[0], talitos1_done_4ch,
+(unsigned long)dev);
+   } else {
+   if (priv->irq[1]) {
tasklet_init(>done_task[0], talitos2_done_ch0_2,
 (unsigned long)dev);
tasklet_init(>done_task[1], talitos2_done_ch1_3,
   

[PATCH 10/18] crypto: talitos - use of_property_read_u32()

2017-10-06 Thread Christophe Leroy
Use of_property_read_u32() to simplify DT read

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 21 +
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 2a53d0f2a869..f139a0cef2e2 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -3158,7 +3158,6 @@ static int talitos_probe(struct platform_device *ofdev)
struct device *dev = >dev;
struct device_node *np = ofdev->dev.of_node;
struct talitos_private *priv;
-   const unsigned int *prop;
int i, err;
int stride;
 
@@ -3182,21 +3181,11 @@ static int talitos_probe(struct platform_device *ofdev)
}
 
/* get SEC version capabilities from device tree */
-   prop = of_get_property(np, "fsl,num-channels", NULL);
-   if (prop)
-   priv->num_channels = *prop;
-
-   prop = of_get_property(np, "fsl,channel-fifo-len", NULL);
-   if (prop)
-   priv->chfifo_len = *prop;
-
-   prop = of_get_property(np, "fsl,exec-units-mask", NULL);
-   if (prop)
-   priv->exec_units = *prop;
-
-   prop = of_get_property(np, "fsl,descriptor-types-mask", NULL);
-   if (prop)
-   priv->desc_types = *prop;
+   of_property_read_u32(np, "fsl,num-channels", >num_channels);
+   of_property_read_u32(np, "fsl,channel-fifo-len", >chfifo_len);
+   of_property_read_u32(np, "fsl,exec-units-mask", >exec_units);
+   of_property_read_u32(np, "fsl,descriptor-types-mask",
+>desc_types);
 
if (!is_power_of_2(priv->num_channels) || !priv->chfifo_len ||
!priv->exec_units || !priv->desc_types) {
-- 
2.13.3



[PATCH 14/18] crypto: talitos - simplify tests in ipsec_esp()

2017-10-06 Thread Christophe Leroy
Do (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) only once.
Limit number of if/else paths

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 42 --
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 7e96db75347a..307d534a0f2f 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -938,12 +938,15 @@ static void ipsec_esp_unmap(struct device *dev,
struct crypto_aead *aead = crypto_aead_reqtfm(areq);
struct talitos_ctx *ctx = crypto_aead_ctx(aead);
unsigned int ivsize = crypto_aead_ivsize(aead);
+   bool is_ipsec_esp = edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP;
+   struct talitos_ptr *civ_ptr = >desc.ptr[is_ipsec_esp ? 2 : 3];
+   struct talitos_ptr *ckey_ptr = >desc.ptr[is_ipsec_esp ? 3 : 2];
 
-   if (edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP)
+   if (is_ipsec_esp)
unmap_single_talitos_ptr(dev, >desc.ptr[6],
 DMA_FROM_DEVICE);
-   unmap_single_talitos_ptr(dev, >desc.ptr[3], DMA_TO_DEVICE);
-   unmap_single_talitos_ptr(dev, >desc.ptr[2], DMA_TO_DEVICE);
+   unmap_single_talitos_ptr(dev, ckey_ptr, DMA_TO_DEVICE);
+   unmap_single_talitos_ptr(dev, civ_ptr, DMA_TO_DEVICE);
unmap_single_talitos_ptr(dev, >desc.ptr[0], DMA_TO_DEVICE);
 
talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen,
@@ -953,7 +956,7 @@ static void ipsec_esp_unmap(struct device *dev,
dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
 DMA_BIDIRECTIONAL);
 
-   if (!(edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP)) {
+   if (!is_ipsec_esp) {
unsigned int dst_nents = edesc->dst_nents ? : 1;
 
sg_pcopy_to_buffer(areq->dst, dst_nents, ctx->iv, ivsize,
@@ -1156,6 +1159,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
bool sync_needed = false;
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
+   bool is_ipsec_esp = desc->hdr & DESC_HDR_TYPE_IPSEC_ESP;
+   struct talitos_ptr *civ_ptr = >ptr[is_ipsec_esp ? 2 : 3];
+   struct talitos_ptr *ckey_ptr = >ptr[is_ipsec_esp ? 3 : 2];
 
/* hmac key */
map_single_talitos_ptr(dev, >ptr[0], ctx->authkeylen, >key,
@@ -1180,20 +1186,12 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
}
 
/* cipher iv */
-   if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
-   to_talitos_ptr(>ptr[2], edesc->iv_dma, ivsize, is_sec1);
-   else
-   to_talitos_ptr(>ptr[3], edesc->iv_dma, ivsize, is_sec1);
+   to_talitos_ptr(civ_ptr, edesc->iv_dma, ivsize, is_sec1);
 
/* cipher key */
-   if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
-   map_single_talitos_ptr(dev, >ptr[3], ctx->enckeylen,
-  (char *)>key + ctx->authkeylen,
-  DMA_TO_DEVICE);
-   else
-   map_single_talitos_ptr(dev, >ptr[2], ctx->enckeylen,
-  (char *)>key + ctx->authkeylen,
-  DMA_TO_DEVICE);
+   map_single_talitos_ptr(dev, ckey_ptr, ctx->enckeylen,
+  (char *)>key + ctx->authkeylen,
+  DMA_TO_DEVICE);
 
/*
 * cipher in
@@ -1203,10 +1201,10 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
 */
sg_link_tbl_len = cryptlen;
 
-   if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
+   if (is_ipsec_esp) {
to_talitos_ptr_ext_set(>ptr[4], authsize, is_sec1);
 
-   if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV)
+   if (desc->hdr & DESC_HDR_MODE1_MDEU_CICV)
sg_link_tbl_len += authsize;
}
 
@@ -1228,7 +1226,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, >ptr[5],
 sg_count, areq->assoclen, tbl_off);
 
-   if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
+   if (is_ipsec_esp)
to_talitos_ptr_ext_or(>ptr[5], authsize, is_sec1);
 
/* ICV data */
@@ -1237,7 +1235,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
edesc->icv_ool = true;
sync_needed = true;
 
-   if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
+   if (is_ipsec_esp) {
struct talitos_ptr *tbl_ptr = >li

[PATCH 15/18] crypto: talitos - DMA map key in setkey()

2017-10-06 Thread Christophe Leroy
dma_map_single() is an heavy operation which doesn't need to
be done at each request as the key doesn't change.

Instead of DMA mapping the key at every request, this patch maps it
once in setkey()

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 56 +---
 1 file changed, 39 insertions(+), 17 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 307d534a0f2f..ebfd6d982ed6 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -815,6 +815,7 @@ struct talitos_ctx {
__be32 desc_hdr_template;
u8 key[TALITOS_MAX_KEY_SIZE];
u8 iv[TALITOS_MAX_IV_LENGTH];
+   dma_addr_t dma_key;
unsigned int keylen;
unsigned int enckeylen;
unsigned int authkeylen;
@@ -851,6 +852,7 @@ static int aead_setkey(struct crypto_aead *authenc,
   const u8 *key, unsigned int keylen)
 {
struct talitos_ctx *ctx = crypto_aead_ctx(authenc);
+   struct device *dev = ctx->dev;
struct crypto_authenc_keys keys;
 
if (crypto_authenc_extractkeys(, key, keylen) != 0)
@@ -859,12 +861,17 @@ static int aead_setkey(struct crypto_aead *authenc,
if (keys.authkeylen + keys.enckeylen > TALITOS_MAX_KEY_SIZE)
goto badkey;
 
+   if (ctx->keylen)
+   dma_unmap_single(dev, ctx->dma_key, ctx->keylen, DMA_TO_DEVICE);
+
memcpy(ctx->key, keys.authkey, keys.authkeylen);
memcpy(>key[keys.authkeylen], keys.enckey, keys.enckeylen);
 
ctx->keylen = keys.authkeylen + keys.enckeylen;
ctx->enckeylen = keys.enckeylen;
ctx->authkeylen = keys.authkeylen;
+   ctx->dma_key = dma_map_single(dev, ctx->key, ctx->keylen,
+ DMA_TO_DEVICE);
 
return 0;
 
@@ -940,14 +947,11 @@ static void ipsec_esp_unmap(struct device *dev,
unsigned int ivsize = crypto_aead_ivsize(aead);
bool is_ipsec_esp = edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP;
struct talitos_ptr *civ_ptr = >desc.ptr[is_ipsec_esp ? 2 : 3];
-   struct talitos_ptr *ckey_ptr = >desc.ptr[is_ipsec_esp ? 3 : 2];
 
if (is_ipsec_esp)
unmap_single_talitos_ptr(dev, >desc.ptr[6],
 DMA_FROM_DEVICE);
-   unmap_single_talitos_ptr(dev, ckey_ptr, DMA_TO_DEVICE);
unmap_single_talitos_ptr(dev, civ_ptr, DMA_TO_DEVICE);
-   unmap_single_talitos_ptr(dev, >desc.ptr[0], DMA_TO_DEVICE);
 
talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen,
 areq->assoclen);
@@ -976,6 +980,7 @@ static void ipsec_esp_encrypt_done(struct device *dev,
struct aead_request *areq = context;
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
unsigned int authsize = crypto_aead_authsize(authenc);
+   unsigned int ivsize = crypto_aead_ivsize(authenc);
struct talitos_edesc *edesc;
struct scatterlist *sg;
void *icvdata;
@@ -996,6 +1001,8 @@ static void ipsec_esp_encrypt_done(struct device *dev,
   icvdata, authsize);
}
 
+   dma_unmap_single(dev, edesc->iv_dma, ivsize, DMA_TO_DEVICE);
+
kfree(edesc);
 
aead_request_complete(areq, err);
@@ -1164,8 +1171,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
struct talitos_ptr *ckey_ptr = >ptr[is_ipsec_esp ? 3 : 2];
 
/* hmac key */
-   map_single_talitos_ptr(dev, >ptr[0], ctx->authkeylen, >key,
-  DMA_TO_DEVICE);
+   to_talitos_ptr(>ptr[0], ctx->dma_key, ctx->authkeylen, is_sec1);
 
sg_count = edesc->src_nents ?: 1;
if (is_sec1 && sg_count > 1)
@@ -1189,9 +1195,8 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
to_talitos_ptr(civ_ptr, edesc->iv_dma, ivsize, is_sec1);
 
/* cipher key */
-   map_single_talitos_ptr(dev, ckey_ptr, ctx->enckeylen,
-  (char *)>key + ctx->authkeylen,
-  DMA_TO_DEVICE);
+   to_talitos_ptr(ckey_ptr, ctx->dma_key  + ctx->authkeylen,
+  ctx->enckeylen, is_sec1);
 
/*
 * cipher in
@@ -1481,6 +1486,7 @@ static int ablkcipher_setkey(struct crypto_ablkcipher 
*cipher,
 const u8 *key, unsigned int keylen)
 {
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+   struct device *dev = ctx->dev;
u32 tmp[DES_EXPKEY_WORDS];
 
if (keylen > TALITOS_MAX_KEY_SIZE) {
@@ -1495,9 +1501,14 @@ static int ablkcipher_setkey(struct crypto_ablkcipher 
*cipher,
return -EINVAL;
}
 
+   if (ctx->keylen)
+   dma_unmap_single(dev, ctx->dma_key, ct

[PATCH 16/18] crypto: talitos - do hw_context DMA mapping outside the requests

2017-10-06 Thread Christophe Leroy
At every request, we map and unmap the same hash hw_context.

This patch moves the dma mapping/unmapping in functions ahash_init()
and ahash_import().

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 80 ++--
 1 file changed, 57 insertions(+), 23 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index ebfd6d982ed6..d495649d5267 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -819,6 +819,7 @@ struct talitos_ctx {
unsigned int keylen;
unsigned int enckeylen;
unsigned int authkeylen;
+   dma_addr_t dma_hw_context;
 };
 
 #define HASH_MAX_BLOCK_SIZESHA512_BLOCK_SIZE
@@ -1663,18 +1664,9 @@ static void common_nonsnoop_hash_unmap(struct device 
*dev,
   struct ahash_request *areq)
 {
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
-   struct talitos_private *priv = dev_get_drvdata(dev);
-   bool is_sec1 = has_ftr_sec1(priv);
-
-   unmap_single_talitos_ptr(dev, >desc.ptr[5], DMA_FROM_DEVICE);
 
talitos_sg_unmap(dev, edesc, req_ctx->psrc, NULL, 0, 0);
 
-   /* When using hashctx-in, must unmap it. */
-   if (from_talitos_ptr_len(>desc.ptr[1], is_sec1))
-   unmap_single_talitos_ptr(dev, >desc.ptr[1],
-DMA_TO_DEVICE);
-
if (edesc->dma_len)
dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
 DMA_BIDIRECTIONAL);
@@ -1744,10 +1736,8 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
 
/* hash context in */
if (!req_ctx->first || req_ctx->swinit) {
-   map_single_talitos_ptr(dev, >ptr[1],
-  req_ctx->hw_context_size,
-  (char *)req_ctx->hw_context,
-  DMA_TO_DEVICE);
+   to_talitos_ptr(>ptr[1], ctx->dma_hw_context,
+  req_ctx->hw_context_size, is_sec1);
req_ctx->swinit = 0;
}
/* Indicate next op is not the first. */
@@ -1780,9 +1770,8 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
   crypto_ahash_digestsize(tfm),
   areq->result, DMA_FROM_DEVICE);
else
-   map_single_talitos_ptr(dev, >ptr[5],
-  req_ctx->hw_context_size,
-  req_ctx->hw_context, DMA_FROM_DEVICE);
+   to_talitos_ptr(>ptr[5], ctx->dma_hw_context,
+  req_ctx->hw_context_size, is_sec1);
 
/* last DWORD empty */
 
@@ -1815,17 +1804,25 @@ static struct talitos_edesc *ahash_edesc_alloc(struct 
ahash_request *areq,
 static int ahash_init(struct ahash_request *areq)
 {
struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+   struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+   struct device *dev = ctx->dev;
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+   unsigned int size;
 
/* Initialize the context */
req_ctx->nbuf = 0;
req_ctx->first = 1; /* first indicates h/w must init its context */
req_ctx->swinit = 0; /* assume h/w init of context */
-   req_ctx->hw_context_size =
-   (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
+   size =  (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
+   req_ctx->hw_context_size = size;
 
+   if (ctx->dma_hw_context)
+   dma_unmap_single(dev, ctx->dma_hw_context, size,
+DMA_BIDIRECTIONAL);
+   ctx->dma_hw_context = dma_map_single(dev, req_ctx->hw_context, size,
+DMA_BIDIRECTIONAL);
return 0;
 }
 
@@ -1836,6 +1833,9 @@ static int ahash_init(struct ahash_request *areq)
 static int ahash_init_sha224_swinit(struct ahash_request *areq)
 {
struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
+   struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
+   struct talitos_ctx *ctx = crypto_ahash_ctx(tfm);
+   struct device *dev = ctx->dev;
 
ahash_init(areq);
req_ctx->swinit = 1;/* prevent h/w initting context with sha256 values*/
@@ -1853,6 +1853,9 @@ static int ahash_init_sha224_swinit(struct ahash_request 
*areq)
req_ctx->hw_context[8] = 0;
req_ctx->hw_context[9] = 0;
 
+   dma_sync_single_for_device(dev, ctx->dma_hw_context,
+  req_ctx->hw_conte

[PATCH 13/18] crypto: talitos - remove to_talitos_ptr_len()

2017-10-06 Thread Christophe Leroy
to_talitos_ptr() and to_talitos_ptr_len() are always called together
in order to fully set a ptr, so lets merge them into a single
helper.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 56 ++--
 1 file changed, 21 insertions(+), 35 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index e7e1bada03df..7e96db75347a 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -56,28 +56,26 @@
 #include "talitos.h"
 
 static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
-  bool is_sec1)
+  unsigned int len, bool is_sec1)
 {
ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
-   if (!is_sec1)
+   if (is_sec1) {
+   ptr->len1 = cpu_to_be16(len);
+   } else {
+   ptr->len = cpu_to_be16(len);
ptr->eptr = upper_32_bits(dma_addr);
+   }
 }
 
 static void copy_talitos_ptr(struct talitos_ptr *dst_ptr,
 struct talitos_ptr *src_ptr, bool is_sec1)
 {
dst_ptr->ptr = src_ptr->ptr;
-   if (!is_sec1)
-   dst_ptr->eptr = src_ptr->eptr;
-}
-
-static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned int len,
-  bool is_sec1)
-{
if (is_sec1) {
-   ptr->len1 = cpu_to_be16(len);
+   dst_ptr->len1 = src_ptr->len1;
} else {
-   ptr->len = cpu_to_be16(len);
+   dst_ptr->len = src_ptr->len;
+   dst_ptr->eptr = src_ptr->eptr;
}
 }
 
@@ -115,8 +113,7 @@ static void map_single_talitos_ptr(struct device *dev,
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
 
-   to_talitos_ptr_len(ptr, len, is_sec1);
-   to_talitos_ptr(ptr, dma_addr, is_sec1);
+   to_talitos_ptr(ptr, dma_addr, len, is_sec1);
 }
 
 /*
@@ -1090,8 +1087,7 @@ static int sg_to_link_tbl_offset(struct scatterlist *sg, 
int sg_count,
len = cryptlen;
 
to_talitos_ptr(link_tbl_ptr + count,
-  sg_dma_address(sg) + offset, 0);
-   to_talitos_ptr_len(link_tbl_ptr + count, len, 0);
+  sg_dma_address(sg) + offset, len, 0);
to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
count++;
cryptlen -= len;
@@ -1117,14 +1113,12 @@ static int talitos_sg_map(struct device *dev, struct 
scatterlist *src,
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
 
-   to_talitos_ptr_len(ptr, len, is_sec1);
-
if (sg_count == 1) {
-   to_talitos_ptr(ptr, sg_dma_address(src) + offset, is_sec1);
+   to_talitos_ptr(ptr, sg_dma_address(src) + offset, len, is_sec1);
return sg_count;
}
if (is_sec1) {
-   to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, is_sec1);
+   to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, len, is_sec1);
return sg_count;
}
sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len,
@@ -1135,7 +1129,7 @@ static int talitos_sg_map(struct device *dev, struct 
scatterlist *src,
return sg_count;
}
to_talitos_ptr(ptr, edesc->dma_link_tbl +
-   tbl_off * sizeof(struct talitos_ptr), is_sec1);
+   tbl_off * sizeof(struct talitos_ptr), len, is_sec1);
to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1);
 
return sg_count;
@@ -1186,13 +1180,10 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
}
 
/* cipher iv */
-   if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
-   to_talitos_ptr(>ptr[2], edesc->iv_dma, is_sec1);
-   to_talitos_ptr_len(>ptr[2], ivsize, is_sec1);
-   } else {
-   to_talitos_ptr(>ptr[3], edesc->iv_dma, is_sec1);
-   to_talitos_ptr_len(>ptr[3], ivsize, is_sec1);
-   }
+   if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
+   to_talitos_ptr(>ptr[2], edesc->iv_dma, ivsize, is_sec1);
+   else
+   to_talitos_ptr(>ptr[3], edesc->iv_dma, ivsize, is_sec1);
 
/* cipher key */
if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
@@ -1210,8 +1201,6 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
 * extent is bytes of HMAC postpended to ciphertext,
 * typically 12 for ipsec
 */
-   to_talitos_ptr_len(>ptr[4], cryptlen, is_sec1);
-
sg_link_tbl_len = cryptlen;
 
if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
@@ -1257,11 +1246,10 @@ static int ips

[PATCH 18/18] crypto: talitos - avoid useless copy

2017-10-06 Thread Christophe Leroy
This patch avoids copy of buffered data to hash from bufnext to buf

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 36 ++--
 1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 5c4499a85611..5bd8191405d8 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -842,8 +842,8 @@ struct talitos_ctx {
 struct talitos_ahash_req_ctx {
u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
unsigned int hw_context_size;
-   u8 buf[HASH_MAX_BLOCK_SIZE];
-   u8 bufnext[HASH_MAX_BLOCK_SIZE];
+   u8 buf[2][HASH_MAX_BLOCK_SIZE];
+   int buf_idx;
unsigned int swinit;
unsigned int first;
unsigned int last;
@@ -1709,7 +1709,7 @@ static void ahash_done(struct device *dev,
 
if (!req_ctx->last && req_ctx->to_hash_later) {
/* Position any partial block for next update/final/finup */
-   memcpy(req_ctx->buf, req_ctx->bufnext, req_ctx->to_hash_later);
+   req_ctx->buf_idx = (req_ctx->buf_idx + 1) & 1;
req_ctx->nbuf = req_ctx->to_hash_later;
}
common_nonsnoop_hash_unmap(dev, edesc, areq);
@@ -1789,8 +1789,10 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
 * data in
 */
if (is_sec1 && req_ctx->nbuf) {
-   to_talitos_ptr(>ptr[3], ctx->dma_buf, req_ctx->nbuf,
-  is_sec1);
+   dma_addr_t dma_buf = ctx->dma_buf + req_ctx->buf_idx *
+   HASH_MAX_BLOCK_SIZE;
+
+   to_talitos_ptr(>ptr[3], dma_buf, req_ctx->nbuf, is_sec1);
} else {
sg_count = talitos_sg_map(dev, req_ctx->psrc, length, edesc,
  >ptr[3], sg_count, offset, 0);
@@ -1883,6 +1885,7 @@ static int ahash_init(struct ahash_request *areq)
bool is_sec1 = has_ftr_sec1(priv);
 
/* Initialize the context */
+   req_ctx->buf_idx = 0;
req_ctx->nbuf = 0;
req_ctx->first = 1; /* first indicates h/w must init its context */
req_ctx->swinit = 0; /* assume h/w init of context */
@@ -1955,6 +1958,7 @@ static int ahash_process_req(struct ahash_request *areq, 
unsigned int nbytes)
struct talitos_private *priv = dev_get_drvdata(dev);
bool is_sec1 = has_ftr_sec1(priv);
int offset = 0;
+   u8 *ctx_buf = req_ctx->buf[req_ctx->buf_idx];
 
if (!req_ctx->last && (nbytes + req_ctx->nbuf <= blocksize)) {
/* Buffer up to one whole block */
@@ -1964,7 +1968,7 @@ static int ahash_process_req(struct ahash_request *areq, 
unsigned int nbytes)
return nents;
}
sg_copy_to_buffer(areq->src, nents,
- req_ctx->buf + req_ctx->nbuf, nbytes);
+ ctx_buf + req_ctx->nbuf, nbytes);
req_ctx->nbuf += nbytes;
return 0;
}
@@ -1988,7 +1992,7 @@ static int ahash_process_req(struct ahash_request *areq, 
unsigned int nbytes)
if (!is_sec1 && req_ctx->nbuf) {
nsg = (req_ctx->nbuf < nbytes_to_hash) ? 2 : 1;
sg_init_table(req_ctx->bufsl, nsg);
-   sg_set_buf(req_ctx->bufsl, req_ctx->buf, req_ctx->nbuf);
+   sg_set_buf(req_ctx->bufsl, ctx_buf, req_ctx->nbuf);
if (nsg > 1)
sg_chain(req_ctx->bufsl, 2, areq->src);
req_ctx->psrc = req_ctx->bufsl;
@@ -2003,7 +2007,7 @@ static int ahash_process_req(struct ahash_request *areq, 
unsigned int nbytes)
return nents;
}
sg_copy_to_buffer(areq->src, nents,
- req_ctx->buf + req_ctx->nbuf, offset);
+ ctx_buf + req_ctx->nbuf, offset);
req_ctx->nbuf += offset;
req_ctx->psrc = areq->src;
} else
@@ -2016,7 +2020,7 @@ static int ahash_process_req(struct ahash_request *areq, 
unsigned int nbytes)
return nents;
}
sg_pcopy_to_buffer(areq->src, nents,
- req_ctx->bufnext,
+  req_ctx->buf[(req_ctx->buf_idx + 1) & 1],
  to_hash_later,
  nbytes - to_hash_later);
}
@@ -2038,9 +2042,13 @@ static int ahash_process_req(struct ahash_request *areq, 
unsigned int nbytes)
/* request SEC to INIT hash. */
if (req_ctx->first && !req_ctx->

Re: [PATCH 5/6] crypto: talitos - use kzalloc instead of kmalloc

2017-10-05 Thread Christophe LEROY



Le 21/09/2017 à 09:19, Christophe Leroy a écrit :

Use kzalloc() to zeroize the extended descriptor at allocation and
further zeorising


This patch significantly degrades performances.
I will submit a new serie soon.

Christophe



Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
  drivers/crypto/talitos.c | 23 +--
  drivers/crypto/talitos.h |  2 --
  2 files changed, 1 insertion(+), 24 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index cd8a37e60259..a5b608b54c74 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -75,7 +75,6 @@ static void to_talitos_ptr_len(struct talitos_ptr *ptr, 
unsigned int len,
   bool is_sec1)
  {
if (is_sec1) {
-   ptr->res = 0;
ptr->len1 = cpu_to_be16(len);
} else {
ptr->len = cpu_to_be16(len);
@@ -118,7 +117,6 @@ static void map_single_talitos_ptr(struct device *dev,
  
  	to_talitos_ptr_len(ptr, len, is_sec1);

to_talitos_ptr(ptr, dma_addr, is_sec1);
-   to_talitos_ptr_ext_set(ptr, 0, is_sec1);
  }
  
  /*

@@ -287,7 +285,6 @@ int talitos_submit(struct device *dev, int ch, struct 
talitos_desc *desc,
/* map descriptor and save caller data */
if (is_sec1) {
desc->hdr1 = desc->hdr;
-   desc->next_desc = 0;
request->dma_desc = dma_map_single(dev, >hdr1,
   TALITOS_DESC_SIZE,
   DMA_BIDIRECTIONAL);
@@ -1099,7 +1096,6 @@ static int sg_to_link_tbl_offset(struct scatterlist *sg, 
int sg_count,
to_talitos_ptr(link_tbl_ptr + count,
   sg_dma_address(sg) + offset, 0);
to_talitos_ptr_len(link_tbl_ptr + count, len, 0);
-   to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
count++;
cryptlen -= len;
offset = 0;
@@ -1125,7 +1121,6 @@ int talitos_sg_map(struct device *dev, struct scatterlist 
*src,
bool is_sec1 = has_ftr_sec1(priv);
  
  	to_talitos_ptr_len(ptr, len, is_sec1);

-   to_talitos_ptr_ext_set(ptr, 0, is_sec1);
  
  	if (sg_count == 1) {

to_talitos_ptr(ptr, sg_dma_address(src) + offset, is_sec1);
@@ -1197,11 +1192,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
to_talitos_ptr(>ptr[2], edesc->iv_dma, is_sec1);
to_talitos_ptr_len(>ptr[2], ivsize, is_sec1);
-   to_talitos_ptr_ext_set(>ptr[2], 0, is_sec1);
} else {
to_talitos_ptr(>ptr[3], edesc->iv_dma, is_sec1);
to_talitos_ptr_len(>ptr[3], ivsize, is_sec1);
-   to_talitos_ptr_ext_set(>ptr[3], 0, is_sec1);
}
  
  	/* cipher key */

@@ -1221,7 +1214,6 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
 * typically 12 for ipsec
 */
to_talitos_ptr_len(>ptr[4], cryptlen, is_sec1);
-   to_talitos_ptr_ext_set(>ptr[4], 0, is_sec1);
  
  	sg_link_tbl_len = cryptlen;
  
@@ -1275,8 +1267,6 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,

to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl + offset,
   is_sec1);
}
-   } else {
-   edesc->icv_ool = false;
}
  
  	/* ICV data */

@@ -1386,7 +1376,7 @@ static struct talitos_edesc *talitos_edesc_alloc(struct 
device *dev,
alloc_len += icv_stashing ? authsize : 0;
}
  
-	edesc = kmalloc(alloc_len, GFP_DMA | flags);

+   edesc = kzalloc(alloc_len, GFP_DMA | flags);
if (!edesc) {
dev_err(dev, "could not allocate edescriptor\n");
err = ERR_PTR(-ENOMEM);
@@ -1467,7 +1457,6 @@ static int aead_decrypt(struct aead_request *req)
  DESC_HDR_MODE1_MDEU_CICV;
  
  		/* reset integrity check result bits */

-   edesc->desc.hdr_lo = 0;
  
  		return ipsec_esp(edesc, req, ipsec_esp_decrypt_hwauth_done);

}
@@ -1554,12 +1543,10 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
bool is_sec1 = has_ftr_sec1(priv);
  
  	/* first DWORD empty */

-   desc->ptr[0] = zero_entry;
  
  	/* cipher iv */

to_talitos_ptr(>ptr[1], edesc->iv_dma, is_sec1);
to_talitos_ptr_len(>ptr[1], ivsize, is_sec1);
-   to_talitos_ptr_ext_set(>ptr[1], 0, is_sec1);
  
  	/* cipher key */

map_single_talitos_ptr(dev, >ptr[2], ctx->keylen,
@@ -1598,7 +1585,6 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
   DMA_FROM_DEVICE);
  
  	/* last DWORD empty */

-   desc->pt

Re: Question about ahash export and import

2017-09-27 Thread Christophe LEROY



Le 27/09/2017 à 11:08, Herbert Xu a écrit :

On Tue, Sep 26, 2017 at 01:09:05PM +0200, Kamil Konieczny wrote:


Can import() be called without _any_ init(), for example
after reboot of machine ? Is following scenario valid:


Of course it can.  import must restore the state of the request
to that at the time when export was called.

import does not need to be called after init.  init simply resets
the hash state for new update/final calls.


init(), update() 0 or more times, export(),
save exported data to pernament storage
reboot machine
load crypto driver, import() saved state ?


Yes this must be supported.

Basically after any update call is complete (you've called the
completion function), you should be able to call export and
completely extract the partial (as opposed to finalised) hash
state.


Can we consider that once an export has been done, no new update call 
will be performed prior to doing an init or an import ? Or should it be 
possible to continue with an update or a final/finup call after an export ?




Remember we need to support an arbitrarily large number of
concurrent hashing operations.  So you cannot keep a hash state
in hardware indefinitely just because the user has not called
finalize on it.

Cheers,



Christophe


Question about ahash export and import

2017-09-26 Thread Christophe LEROY

Hello,

Today, the talitos driver dma maps/unmaps context and keys at every 
single request.
I'm looking at doing the dma mapping at hash init and doing unmapping at 
final/finup/digest


However, I'm wondering how to manage hash exports and imports. I was 
initially thinking about doing a dma_sync_for_cpu() before any export 
and a dma_sync_for_device() after any export, but that supposes that the 
dma area is already mapped, which means that we have done the init and 
not yet done a final/finup/digest.


I'm a bit sceptic when reading the following text in include/crypto/hash.h :

@export: Export partial state of the transformation. This function dumps the
 *  entire state of the ongoing transformation into a provided block of
 *  data so it can be @import 'ed back later on. This is useful in case
 *  you want to save partial result of the transformation after
 *  processing certain amount of data and reload this partial result
 *  multiple times later on for multiple re-use


Does it mean that import may be called in lieu of hash init, or is hash 
init always called before doing an import ?


Thanks
Christophe


[PATCH] crypto: talitos - fix setkey to check key weakness

2017-09-25 Thread Christophe Leroy
Crypto manager test report the following failures:
[3.061081] alg: skcipher: setkey failed on test 5 for ecb-des-talitos: 
flags=100
[3.069342] alg: skcipher-ddst: setkey failed on test 5 for ecb-des-talitos: 
flags=100
[3.077754] alg: skcipher-ddst: setkey failed on test 5 for ecb-des-talitos: 
flags=100

This is due to setkey being expected to detect weak keys.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index e7e31f8fd3d1..09a2cd3a31d2 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1494,12 +1494,20 @@ static int ablkcipher_setkey(struct crypto_ablkcipher 
*cipher,
 const u8 *key, unsigned int keylen)
 {
struct talitos_ctx *ctx = crypto_ablkcipher_ctx(cipher);
+   u32 tmp[DES_EXPKEY_WORDS];
 
if (keylen > TALITOS_MAX_KEY_SIZE) {
crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
}
 
+   if (unlikely(crypto_ablkcipher_get_flags(cipher) &
+CRYPTO_TFM_REQ_WEAK_KEY) &&
+   !des_ekey(tmp, key)) {
+   crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_WEAK_KEY);
+   return -EINVAL;
+   }
+
memcpy(>key, key, keylen);
ctx->keylen = keylen;
 
-- 
2.13.3



[PATCH] crypto: talitos - fix AEAD for sha224 on non sha224 capable chips

2017-09-25 Thread Christophe Leroy
sha224 AEAD test fails with:

[2.803125] talitos ff02.crypto: DEUISR 0x_
[2.808743] talitos ff02.crypto: MDEUISR 0x8010_
[2.814678] talitos ff02.crypto: DESCBUF 0x20731f21_0018
[2.820616] talitos ff02.crypto: DESCBUF 0x0628d64c_0010
[2.826554] talitos ff02.crypto: DESCBUF 0x0631005c_0018
[2.832492] talitos ff02.crypto: DESCBUF 0x0628d664_0008
[2.838430] talitos ff02.crypto: DESCBUF 0x061b13a0_0080
[2.844369] talitos ff02.crypto: DESCBUF 0x0631006c_0080
[2.850307] talitos ff02.crypto: DESCBUF 0x0631006c_0018
[2.856245] talitos ff02.crypto: DESCBUF 0x063100ec_
[2.884972] talitos ff02.crypto: failed to reset channel 0
[2.890503] talitos ff02.crypto: done overflow, internal time out, or 
rngu error: ISR 0x2000_0002
[2.900652] alg: aead: encryption failed on test 1 for 
authenc-hmac-sha224-cbc-3des-talitos: ret=22

This is due to SHA224 not being supported by the HW. Allthough for
hash we are able to init the hash contet by SW, it is not
possible for AEAD. Therefore SHA224 AEAD has to be deactivated.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 09a2cd3a31d2..9bfda9d59ace 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -3045,6 +3045,11 @@ static struct talitos_crypto_alg 
*talitos_alg_alloc(struct device *dev,
t_alg->algt.alg.aead.setkey = aead_setkey;
t_alg->algt.alg.aead.encrypt = aead_encrypt;
t_alg->algt.alg.aead.decrypt = aead_decrypt;
+   if (!(priv->features & TALITOS_FTR_SHA224_HWINIT) &&
+   !strncmp(alg->cra_name, "authenc(hmac(sha224)", 20)) {
+   kfree(t_alg);
+   return ERR_PTR(-ENOTSUPP);
+   }
break;
case CRYPTO_ALG_TYPE_AHASH:
alg = _alg->algt.alg.hash.halg.base;
-- 
2.13.3



[PATCH 6/6] crypto: talitos - fix memory corruption on SEC2

2017-09-21 Thread Christophe Leroy
xc8
[2.930853] [c0d4bf60] [c007f064] cpu_startup_entry+0xe4/0x190
[2.936707] [c0d4bfb0] [c096c434] start_kernel+0x3f4/0x408
[2.942198] [c0d4bff0] [3438] 0x3438
[2.946137] FIX dma-kmalloc-256: Restoring 0xde858108-0xde85810b=0xcc
[2.946137]
[2.954158] FIX dma-kmalloc-256: Object at 0xde858008 not freed

This patch reworks the handling of the CICV out in order
to properly handle all cases.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 40 ++--
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index a5b608b54c74..e7e31f8fd3d1 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1239,14 +1239,15 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
dma_map_sg(dev, areq->dst, sg_count, DMA_FROM_DEVICE);
}
 
-   sg_count = talitos_sg_map(dev, areq->dst, cryptlen, edesc,
- >ptr[5], sg_count, areq->assoclen,
- tbl_off);
+   ret = talitos_sg_map(dev, areq->dst, cryptlen, edesc, >ptr[5],
+sg_count, areq->assoclen, tbl_off);
 
if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)
to_talitos_ptr_ext_or(>ptr[5], authsize, is_sec1);
 
-   if (sg_count > 1) {
+   /* ICV data */
+   if (ret > 1) {
+   tbl_off += ret;
edesc->icv_ool = true;
sync_needed = true;
 
@@ -1256,9 +1257,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
 sizeof(struct talitos_ptr) + authsize;
 
/* Add an entry to the link table for ICV data */
-   tbl_ptr += sg_count - 1;
-   to_talitos_ptr_ext_set(tbl_ptr, 0, is_sec1);
-   tbl_ptr++;
+   to_talitos_ptr_ext_set(tbl_ptr - 1, 0, is_sec1);
to_talitos_ptr_ext_set(tbl_ptr, DESC_PTR_LNKTBL_RETURN,
   is_sec1);
to_talitos_ptr_len(tbl_ptr, authsize, is_sec1);
@@ -1266,14 +1265,27 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
/* icv data follows link tables */
to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl + offset,
   is_sec1);
-   }
-   }
+   } else {
+   dma_addr_t addr = edesc->dma_link_tbl;
 
-   /* ICV data */
-   if (!(desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)) {
-   to_talitos_ptr_len(>ptr[6], authsize, is_sec1);
-   to_talitos_ptr(>ptr[6], edesc->dma_link_tbl +
-  areq->assoclen + cryptlen, is_sec1);
+   if (is_sec1)
+   addr += areq->assoclen + cryptlen;
+   else
+   addr += sizeof(struct talitos_ptr) * tbl_off;
+
+   to_talitos_ptr(>ptr[6], addr, is_sec1);
+   to_talitos_ptr_len(>ptr[6], authsize, is_sec1);
+   }
+   } else if (!(desc->hdr & DESC_HDR_TYPE_IPSEC_ESP)) {
+   ret = talitos_sg_map(dev, areq->dst, authsize, edesc,
+>ptr[6], sg_count, areq->assoclen +
+ cryptlen,
+tbl_off);
+   if (ret > 1) {
+   tbl_off += ret;
+   edesc->icv_ool = true;
+   sync_needed = true;
+   }
}
 
/* iv out */
-- 
2.13.3



[PATCH 5/6] crypto: talitos - use kzalloc instead of kmalloc

2017-09-21 Thread Christophe Leroy
Use kzalloc() to zeroize the extended descriptor at allocation and
further zeorising

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 23 +--
 drivers/crypto/talitos.h |  2 --
 2 files changed, 1 insertion(+), 24 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index cd8a37e60259..a5b608b54c74 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -75,7 +75,6 @@ static void to_talitos_ptr_len(struct talitos_ptr *ptr, 
unsigned int len,
   bool is_sec1)
 {
if (is_sec1) {
-   ptr->res = 0;
ptr->len1 = cpu_to_be16(len);
} else {
ptr->len = cpu_to_be16(len);
@@ -118,7 +117,6 @@ static void map_single_talitos_ptr(struct device *dev,
 
to_talitos_ptr_len(ptr, len, is_sec1);
to_talitos_ptr(ptr, dma_addr, is_sec1);
-   to_talitos_ptr_ext_set(ptr, 0, is_sec1);
 }
 
 /*
@@ -287,7 +285,6 @@ int talitos_submit(struct device *dev, int ch, struct 
talitos_desc *desc,
/* map descriptor and save caller data */
if (is_sec1) {
desc->hdr1 = desc->hdr;
-   desc->next_desc = 0;
request->dma_desc = dma_map_single(dev, >hdr1,
   TALITOS_DESC_SIZE,
   DMA_BIDIRECTIONAL);
@@ -1099,7 +1096,6 @@ static int sg_to_link_tbl_offset(struct scatterlist *sg, 
int sg_count,
to_talitos_ptr(link_tbl_ptr + count,
   sg_dma_address(sg) + offset, 0);
to_talitos_ptr_len(link_tbl_ptr + count, len, 0);
-   to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
count++;
cryptlen -= len;
offset = 0;
@@ -1125,7 +1121,6 @@ int talitos_sg_map(struct device *dev, struct scatterlist 
*src,
bool is_sec1 = has_ftr_sec1(priv);
 
to_talitos_ptr_len(ptr, len, is_sec1);
-   to_talitos_ptr_ext_set(ptr, 0, is_sec1);
 
if (sg_count == 1) {
to_talitos_ptr(ptr, sg_dma_address(src) + offset, is_sec1);
@@ -1197,11 +1192,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
if (desc->hdr & DESC_HDR_TYPE_IPSEC_ESP) {
to_talitos_ptr(>ptr[2], edesc->iv_dma, is_sec1);
to_talitos_ptr_len(>ptr[2], ivsize, is_sec1);
-   to_talitos_ptr_ext_set(>ptr[2], 0, is_sec1);
} else {
to_talitos_ptr(>ptr[3], edesc->iv_dma, is_sec1);
to_talitos_ptr_len(>ptr[3], ivsize, is_sec1);
-   to_talitos_ptr_ext_set(>ptr[3], 0, is_sec1);
}
 
/* cipher key */
@@ -1221,7 +1214,6 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
 * typically 12 for ipsec
 */
to_talitos_ptr_len(>ptr[4], cryptlen, is_sec1);
-   to_talitos_ptr_ext_set(>ptr[4], 0, is_sec1);
 
sg_link_tbl_len = cryptlen;
 
@@ -1275,8 +1267,6 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
to_talitos_ptr(tbl_ptr, edesc->dma_link_tbl + offset,
   is_sec1);
}
-   } else {
-   edesc->icv_ool = false;
}
 
/* ICV data */
@@ -1386,7 +1376,7 @@ static struct talitos_edesc *talitos_edesc_alloc(struct 
device *dev,
alloc_len += icv_stashing ? authsize : 0;
}
 
-   edesc = kmalloc(alloc_len, GFP_DMA | flags);
+   edesc = kzalloc(alloc_len, GFP_DMA | flags);
if (!edesc) {
dev_err(dev, "could not allocate edescriptor\n");
err = ERR_PTR(-ENOMEM);
@@ -1467,7 +1457,6 @@ static int aead_decrypt(struct aead_request *req)
  DESC_HDR_MODE1_MDEU_CICV;
 
/* reset integrity check result bits */
-   edesc->desc.hdr_lo = 0;
 
return ipsec_esp(edesc, req, ipsec_esp_decrypt_hwauth_done);
}
@@ -1554,12 +1543,10 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
bool is_sec1 = has_ftr_sec1(priv);
 
/* first DWORD empty */
-   desc->ptr[0] = zero_entry;
 
/* cipher iv */
to_talitos_ptr(>ptr[1], edesc->iv_dma, is_sec1);
to_talitos_ptr_len(>ptr[1], ivsize, is_sec1);
-   to_talitos_ptr_ext_set(>ptr[1], 0, is_sec1);
 
/* cipher key */
map_single_talitos_ptr(dev, >ptr[2], ctx->keylen,
@@ -1598,7 +1585,6 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
   DMA_FROM_DEVICE);
 
/* last DWORD empty */
-   desc->ptr[6] = zero_entry;
 
if (sync_needed)
dma_sync_single_for_device(dev, edesc->dma_l

[PATCH 3/6] crypto: talitos - fix sha224

2017-09-21 Thread Christophe Leroy
Kernel crypto tests report the following error at startup

[2.752626] alg: hash: Test 4 failed for sha224-talitos
[2.757907] : 30 e2 86 e2 e7 8a dd 0d d7 eb 9f d5 83 fe f1 b0
0010: 2d 5a 6c a5 f9 55 ea fd 0e 72 05 22

This patch fixes it

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 49f1561fa694..dff88838dce7 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1756,9 +1756,9 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
req_ctx->swinit = 0;
} else {
desc->ptr[1] = zero_entry;
-   /* Indicate next op is not the first. */
-   req_ctx->first = 0;
}
+   /* Indicate next op is not the first. */
+   req_ctx->first = 0;
 
/* HMAC key */
if (ctx->keylen)
-- 
2.13.3



[PATCH 2/6] crypto: talitos - fix hashing

2017-09-21 Thread Christophe Leroy
md5sum on some files gives wrong result

Exemple:

With the md5sum from libkcapi:
c15115c05bad51113f81bdaee735dd09  test

With the original md5sum:
bbdf41d80ba7e8b2b7be3a0772be76cb  test

This patch fixes this issue

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 5cc160078286..49f1561fa694 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1769,7 +1769,7 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
 
sg_count = edesc->src_nents ?: 1;
if (is_sec1 && sg_count > 1)
-   sg_copy_to_buffer(areq->src, sg_count, edesc->buf, length);
+   sg_copy_to_buffer(req_ctx->psrc, sg_count, edesc->buf, length);
else
sg_count = dma_map_sg(dev, req_ctx->psrc, sg_count,
  DMA_TO_DEVICE);
-- 
2.13.3



[PATCH 0/6] crypto: talitos - various fixes

2017-09-21 Thread Christophe Leroy
This serie provide various fixes on the talitos driver.

Christophe Leroy (6):
  crypto: talitos - Don't provide setkey for non hmac hashing algs.
  crypto: talitos - fix hashing
  crypto: talitos - fix sha224
  crypto: talitos - fix AEAD test failures
  crypto: talitos - use kzalloc instead of kmalloc
  crypto: talitos - fix memory corruption on SEC2

 drivers/crypto/talitos.c | 81 +---
 drivers/crypto/talitos.h |  2 --
 2 files changed, 36 insertions(+), 47 deletions(-)

-- 
2.13.3



[PATCH 1/6] crypto: talitos - Don't provide setkey for non hmac hashing algs.

2017-09-21 Thread Christophe Leroy
Today, md5sum fails with error -ENOKEY because a setkey
function is set for non hmac hashing algs, see strace output below:

mmap(NULL, 378880, PROT_READ, MAP_SHARED, 6, 0) = 0x77f5
accept(3, 0, NULL)  = 7
vmsplice(5, 
[{"bin/\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 378880}], 
1, SPLICE_F_MORE|SPLICE_F_GIFT) = 262144
splice(4, NULL, 7, NULL, 262144, SPLICE_F_MORE) = -1 ENOKEY (Required key not 
available)
write(2, "Generation of hash for file kcap"..., 50) = 50
munmap(0x77f5, 378880)  = 0

This patch ensures that setkey() function is set only
for hmac hashing.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 79791c690858..5cc160078286 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -3057,7 +3057,8 @@ static struct talitos_crypto_alg 
*talitos_alg_alloc(struct device *dev,
t_alg->algt.alg.hash.final = ahash_final;
t_alg->algt.alg.hash.finup = ahash_finup;
t_alg->algt.alg.hash.digest = ahash_digest;
-   t_alg->algt.alg.hash.setkey = ahash_setkey;
+   if (!strncmp(alg->cra_name, "hmac", 4))
+   t_alg->algt.alg.hash.setkey = ahash_setkey;
t_alg->algt.alg.hash.import = ahash_import;
t_alg->algt.alg.hash.export = ahash_export;
 
-- 
2.13.3



Re: [PATCH 0/6] crypto: talitos - various fixes

2017-09-20 Thread christophe leroy
What's going wrong ? I have resent it and it the same again, the serie 
is not dispatched on the linux-crypto list, but when I answer to a mail 
of the serie, the answer shows up.


What could be the issue ?

Christophe

Le 20/09/2017 à 10:35, Christophe LEROY a écrit :
Looks like the linux-crypto list and patchwork was out of order when I 
sent this. I will send again, sorry for the noise on the other lists.


Le 19/09/2017 à 14:58, Christophe Leroy a écrit :

This serie provide various fixes on the talitos driver.

Christophe Leroy (6):
   crypto: talitos - Don't provide setkey for non hmac hashing algs.
   crypto: talitos - fix hashing
   crypto: talitos - fix sha224
   crypto: talitos - fix AEAD test failures
   crypto: talitos - use kzalloc instead of kmalloc
   crypto: talitos - fix memory corruption on SEC2

  drivers/crypto/talitos.c | 81 
+---

  drivers/crypto/talitos.h |  2 --
  2 files changed, 36 insertions(+), 47 deletions(-)



---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel 
antivirus Avast.
https://www.avast.com/antivirus



Test

2017-09-20 Thread Christophe LEROY
Sorry for the noise, but I have twice tried to send a PATCH serie to 
this list with a copy to linuxppc-...@lists.ozlabs.org, it appears 
properly in the linuxppc list/patchwork but it still doesn't appear on 
linux-crypto.


Is there anything wrong with the list ?

Christophe


Re: [PATCH 0/6] crypto: talitos - various fixes

2017-09-20 Thread Christophe LEROY
Looks like the linux-crypto list and patchwork was out of order when I 
sent this. I will send again, sorry for the noise on the other lists.


Le 19/09/2017 à 14:58, Christophe Leroy a écrit :

This serie provide various fixes on the talitos driver.

Christophe Leroy (6):
   crypto: talitos - Don't provide setkey for non hmac hashing algs.
   crypto: talitos - fix hashing
   crypto: talitos - fix sha224
   crypto: talitos - fix AEAD test failures
   crypto: talitos - use kzalloc instead of kmalloc
   crypto: talitos - fix memory corruption on SEC2

  drivers/crypto/talitos.c | 81 +---
  drivers/crypto/talitos.h |  2 --
  2 files changed, 36 insertions(+), 47 deletions(-)



[PATCH] crypto: talitos - fix hashing

2017-09-13 Thread Christophe Leroy
md5sum on some files gives wrong result

Exemple:

With the md5sum from libkcapi:
c15115c05bad51113f81bdaee735dd09  test

With the original md5sum:
bbdf41d80ba7e8b2b7be3a0772be76cb  test

This patch fixes this issue

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index f6f811a1bb..d47b3eb1f0 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1769,7 +1769,7 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
 
sg_count = edesc->src_nents ?: 1;
if (is_sec1 && sg_count > 1)
-   sg_copy_to_buffer(areq->src, sg_count, edesc->buf, length);
+   sg_copy_to_buffer(req_ctx->psrc, sg_count, edesc->buf, length);
else
sg_count = dma_map_sg(dev, req_ctx->psrc, sg_count,
  DMA_TO_DEVICE);
-- 
2.13.3



[PATCH] crypto: talitos - fix sha224

2017-09-13 Thread Christophe Leroy
Kernel crypto tests report the following error at startup

[2.752626] alg: hash: Test 4 failed for sha224-talitos
[2.757907] : 30 e2 86 e2 e7 8a dd 0d d7 eb 9f d5 83 fe f1 b0
0010: 2d 5a 6c a5 f9 55 ea fd 0e 72 05 22

This patch fixes it

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index d47b3eb1f0..e2d323fa24 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1756,9 +1756,9 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
req_ctx->swinit = 0;
} else {
desc->ptr[1] = zero_entry;
-   /* Indicate next op is not the first. */
-   req_ctx->first = 0;
}
+   /* Indicate next op is not the first. */
+   req_ctx->first = 0;
 
/* HMAC key */
if (ctx->keylen)
-- 
2.13.3



Re: md5sum (from libkcapi) fails as splice() returns -ENOKEY

2017-09-12 Thread Christophe LEROY

Hi again

Le 12/09/2017 à 09:22, Stephan Mueller a écrit :

Am Dienstag, 12. September 2017, 09:20:41 CEST schrieb Stephan Mueller:


I am thinking now to add AC_PREREQ([2.60]) to configure.ac.


I meant 2.69, of course? :-)


Ok ... CentOS ships with 2.63 and no update seems available via 'yum 
update'.


Is 2.69 really necessary ? It seems to work just fine with 2.63 once the 
modification is done.


Christophe




Ciao
Stephan



Re: md5sum (from libkcapi) fails as splice() returns -ENOKEY

2017-09-12 Thread Christophe LEROY

Hi Stephan,

Le 12/09/2017 à 09:20, Stephan Mueller a écrit :

Am Dienstag, 12. September 2017, 09:01:08 CEST schrieb Christophe LEROY:

Hi Christophe,


Hi Stephan

Le 11/09/2017 à 21:17, Stephan Müller a écrit :

Am Montag, 11. September 2017, 19:07:31 CEST schrieb christophe leroy:

Hi christophe,


Hello Stephan,

I'm trying to use md5sum from the latest libkcapi 0.14 and I getting a
failure with return code -5.

What am I missing ? See strace below, splice() return -ENOKEY.


The ENOKEY error is due to an accept() at the wrong location. But I do not
see
that error:

I did the test once more without the Talitos Crypto driver compiled in
the kernel, and this time it works.
I believe it must then be an issue with that driver.
What could be the issue, what should I look for in the driver ?



I think I see the error in talitos.c -- yet I do not have that hardware so I
cannot create a patch and test.

In talitos_alg_alloc the function pointer setkey is set unconditional for
CRYPTO_ALG_TYPE_AHASH. This is correct for HMAC/CMAC, but not correct for
staight hashes. As both, md5 and hmac(md5) (and also for the SHA equivalents)
are marked as CRYPTO_ALG_TYPE_AHASH in driver_algs, they all will get a setkey
function.

This will trigger the following code in algif_hash:

static int hash_accept_parent(void *private, struct sock *sk)
{
 struct algif_hash_tfm *tfm = private;

 if (!tfm->has_key && crypto_ahash_has_setkey(tfm->hash))
 return -ENOKEY;

If the setkey would not be present for the straight hashes, ENOKEY would not
be returned.


Thanks.
I modified it and it now works (allthough it doesn't provide the correct 
MD5sum ... have to findout why)

I submitted a patch for it.

Christophe


...



# autoreconf --version
autoreconf (GNU Autoconf) 2.63


Thanks for the bug report. But I think the autoconf tools are not up to date.
It should be 2.69.

Could you please check whether you can update?

I am thinking now to add AC_PREREQ([2.60]) to configure.ac.



Ciao
Stephan



[PATCH] crypto: talitos - Don't provide setkey for non hmac hashing algs.

2017-09-12 Thread Christophe Leroy
Today, md5sum fails with error -ENOKEY because a setkey
function is set for non hmac hashing algs, see strace output below:

mmap(NULL, 378880, PROT_READ, MAP_SHARED, 6, 0) = 0x77f5
accept(3, 0, NULL)  = 7
vmsplice(5, 
[{"bin/\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 378880}], 
1, SPLICE_F_MORE|SPLICE_F_GIFT) = 262144
splice(4, NULL, 7, NULL, 262144, SPLICE_F_MORE) = -1 ENOKEY (Required key not 
available)
write(2, "Generation of hash for file kcap"..., 50) = 50
munmap(0x77f5, 378880)  = 0

This patch ensures that setkey() function is set only
for hmac hashing.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 79791c690858..5cc160078286 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -3057,7 +3057,8 @@ static struct talitos_crypto_alg 
*talitos_alg_alloc(struct device *dev,
t_alg->algt.alg.hash.final = ahash_final;
t_alg->algt.alg.hash.finup = ahash_finup;
t_alg->algt.alg.hash.digest = ahash_digest;
-   t_alg->algt.alg.hash.setkey = ahash_setkey;
+   if (!strncmp(alg->cra_name, "hmac", 4))
+   t_alg->algt.alg.hash.setkey = ahash_setkey;
t_alg->algt.alg.hash.import = ahash_import;
t_alg->algt.alg.hash.export = ahash_export;
 
-- 
2.13.3



Re: md5sum (from libkcapi) fails as splice() returns -ENOKEY

2017-09-12 Thread Christophe LEROY

Hi Stephan

Le 11/09/2017 à 21:17, Stephan Müller a écrit :

Am Montag, 11. September 2017, 19:07:31 CEST schrieb christophe leroy:

Hi christophe,


Hello Stephan,

I'm trying to use md5sum from the latest libkcapi 0.14 and I getting a
failure with return code -5.

What am I missing ? See strace below, splice() return -ENOKEY.


The ENOKEY error is due to an accept() at the wrong location. But I do not see
that error:


I did the test once more without the Talitos Crypto driver compiled in 
the kernel, and this time it works.

I believe it must then be an issue with that driver.
What could be the issue, what should I look for in the driver ?



tar xvfJ libkcapi-0.14.0.tar.xz
cd libkcapi-0.14.0
autoreconf -i


I get an error here, have to replace AC_CONFIG_MACRO_DIRS by 
AC_CONFIG_MACRO_DIR in configure.ac


# tar xfJ libkcapi-0.14.0.tar.xz

# cd libkcapi-0.14.0

# autoreconf -i
libtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: putting macros in `m4'.
libtoolize: copying file `m4/libtool.m4'
libtoolize: copying file `m4/ltoptions.m4'
libtoolize: copying file `m4/ltsugar.m4'
libtoolize: copying file `m4/ltversion.m4'
libtoolize: copying file `m4/lt~obsolete.m4'
libtoolize: Consider adding `AC_CONFIG_MACRO_DIR([m4])' to configure.ac and
libtoolize: rerunning libtoolize, to keep the correct libtool macros 
in-tree.

configure.ac:26: error: possibly undefined macro: AC_CONFIG_MACRO_DIRS
  If this token and others are legitimate, please use m4_pattern_allow.
  See the Autoconf documentation.
autoreconf: /usr/bin/autoconf failed with exit status: 1

# sed -i s/AC_CONFIG_MACRO_DIRS/AC_CONFIG_MACRO_DIR/g configure.ac

# autoreconf -i
configure.ac:22: installing `./config.guess'
configure.ac:22: installing `./config.sub'
configure.ac:21: installing `./install-sh'
configure.ac:21: installing `./missing'
lib/doc/Makefile.am: installing `./depcomp'

# autoreconf --version
autoreconf (GNU Autoconf) 2.63
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv2+: GNU GPL version 2 or later
<http://gnu.org/licenses/old-licenses/gpl-2.0.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by David J. MacKenzie and Akim Demaille.

Thanks
Christophe



./configure --enable-kcapi-hasher
make
cd bin/.libs/ # I make no make install for testing
ln kcapi-hasher md5sum # create md5sum app
export LD_LIBRARY_PATH=../../.libs/ # location of current library

$ ./md5sum md5sum
ddd1a82680b16fb6c241d81656b844df  md5sum

So, it works for me.

Can you please check whether you use the current library version? Note,
library version 0.10.1 fixed the aforementioned accept() call for kernel 4.4
and later.

$ ./md5sum -v
md5sum: libkcapi 0.14.0

Ciao
Stephan



md5sum (from libkcapi) fails as splice() returns -ENOKEY

2017-09-11 Thread christophe leroy

Hello Stephan,

I'm trying to use md5sum from the latest libkcapi 0.14 and I getting a 
failure with return code -5.


What am I missing ? See strace below, splice() return -ENOKEY.

Christophe

execve("./md5sum", ["./md5sum", "kcapi.tar"], [/* 11 vars */]) = 0
brk(0)  = 0x10024000
access("/etc/ld.so.preload", R_OK)  = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/ppc823/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such 
file or directory)
stat64("/usr/lib/tls/ppc823", 0x7ffa2328) = -1 ENOENT (No such file or 
directory)
open("/usr/lib/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or 
directory)
stat64("/usr/lib/tls", 0x7ffa2328)  = -1 ENOENT (No such file or directory)
open("/usr/lib/ppc823/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file 
or directory)
stat64("/usr/lib/ppc823", 0x7ffa2328)   = -1 ENOENT (No such file or directory)
open("/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or 
directory)
stat64("/usr/lib", {st_mode=S_IFDIR|0755, st_size=3568, ...}) = 0
open("/lib/tls/ppc823/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file 
or directory)
stat64("/lib/tls/ppc823", 0x7ffa2328)   = -1 ENOENT (No such file or directory)
open("/lib/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or 
directory)
stat64("/lib/tls", 0x7ffa2328)  = -1 ENOENT (No such file or directory)
open("/lib/ppc823/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or 
directory)
stat64("/lib/ppc823", 0x7ffa2328)   = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, 
"\177ELF\1\2\1\3\0\0\0\0\0\0\0\0\0\3\0\24\0\0\0\1\0\2\35\\\0\0\0004"..., 512) = 
512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1797540, ...}) = 0
mmap(0xfe58000, 1661856, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) 
= 0xfe58000
mprotect(0xffc8000, 114688, PROT_NONE)  = 0
mmap(0xffe4000, 32768, PROT_READ|PROT_WRITE|PROT_EXEC, 
MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17c000) = 0xffe4000
mmap(0xffec000, 7072, PROT_READ|PROT_WRITE|PROT_EXEC, 
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xffec000
close(3)= 0
mprotect(0xffe4000, 16384, PROT_READ)   = 0
mprotect(0x1001c000, 16384, PROT_READ)  = 0
mprotect(0x779f8000, 16384, PROT_READ)  = 0
brk(0)  = 0x10024000
brk(0x10048000) = 0x10048000
open("/proc/sys/crypto/fips_enabled", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
read(3, "0\n", 1024)= 2
close(3)= 0
socket(PF_ALG, SOCK_SEQPACKET, 0)   = 3
bind(3, {sa_family=AF_ALG, sa_data="hash\0\0\0\0\0\0\0\0\0\0"}, 88) = 0
pipe([4, 5])= 0
socket(PF_NETLINK, SOCK_RAW, 21)= 6
bind(6, {sa_family=AF_NETLINK, pid=0, groups=}, 12) = 0
getsockname(6, {sa_family=AF_NETLINK, pid=266, groups=}, [12]) = 0
sendmsg(6, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=}, 
msg_iov(1)=[{"\0\0\0\340\0\23\0\1\0;\232\247\0\0\0\0md5\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
 224}], msg_controllen=0, msg_flags=0}, 0) = 224
recvmsg(6, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=}, 
msg_iov(1)=[{"\0\0\0014\0\23\0\0\0;\232\247\0\0\1\nmd5\0\0\0\0\0\0\0\0\0\0\0\0\0"...,
 4096}], msg_controllen=0, msg_flags=0}, 0) = 308
close(6)= 0
open("kcapi.tar", O_RDONLY|O_CLOEXEC)   = 6
fstat64(6, {st_mode=S_IFREG|0644, st_size=378880, ...}) = 0
mmap(NULL, 378880, PROT_READ, MAP_SHARED, 6, 0) = 0x7795c000
accept(3, 0, NULL)  = 7
vmsplice(5, 
[{"bin/\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 378880}], 
1, SPLICE_F_MORE|SPLICE_F_GIFT) = 262144
splice(4, NULL, 7, NULL, 262144, SPLICE_F_MORE) = -1 ENOKEY (Required key not 
available)
write(2, "Generation of hash for file kcap"..., 50) = 50
munmap(0x7795c000, 378880)  = 0
close(6)= 0
close(3)= 0
close(7)= 0
close(4)= 0
close(5)= 0
exit_group(-5)  = ?
+++ exited with 251 +++


---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel 
antivirus Avast.
https://www.avast.com/antivirus



[PATCH v2 4/7] crypto: talitos - Implement AEAD for SEC1 using HMAC_SNOOP_NO_AFEU

2016-06-06 Thread Christophe Leroy
This patchs enhances the IPSEC_ESP related functions for them to
also supports the same operations with descriptor type
HMAC_SNOOP_NO_AFEU.

The differences between the two descriptor types are:
* pointeurs 2 and 3 are swaped (Confidentiality key and
Primary EU Context IN)
* HMAC_SNOOP_NO_AFEU has CICV out in pointer 6
* HMAC_SNOOP_NO_AFEU has no primary EU context out so we get it
from the end of data out

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 209 ---
 1 file changed, 124 insertions(+), 85 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index b0d3c24..4ff03c3 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -940,7 +940,13 @@ static void ipsec_esp_unmap(struct device *dev,
struct talitos_edesc *edesc,
struct aead_request *areq)
 {
-   unmap_single_talitos_ptr(dev, >desc.ptr[6], DMA_FROM_DEVICE);
+   struct crypto_aead *aead = crypto_aead_reqtfm(areq);
+   struct talitos_ctx *ctx = crypto_aead_ctx(aead);
+   unsigned int ivsize = crypto_aead_ivsize(aead);
+
+   if (edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP)
+   unmap_single_talitos_ptr(dev, >desc.ptr[6],
+DMA_FROM_DEVICE);
unmap_single_talitos_ptr(dev, >desc.ptr[3], DMA_TO_DEVICE);
unmap_single_talitos_ptr(dev, >desc.ptr[2], DMA_TO_DEVICE);
unmap_single_talitos_ptr(dev, >desc.ptr[0], DMA_TO_DEVICE);
@@ -951,6 +957,13 @@ static void ipsec_esp_unmap(struct device *dev,
if (edesc->dma_len)
dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
 DMA_BIDIRECTIONAL);
+
+   if (!(edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP)) {
+   unsigned int dst_nents = edesc->dst_nents ? : 1;
+
+   sg_pcopy_to_buffer(areq->dst, dst_nents, ctx->iv, ivsize,
+  areq->assoclen + areq->cryptlen - ivsize);
+   }
 }
 
 /*
@@ -960,6 +973,8 @@ static void ipsec_esp_encrypt_done(struct device *dev,
   struct talitos_desc *desc, void *context,
   int err)
 {
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
struct aead_request *areq = context;
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
unsigned int authsize = crypto_aead_authsize(authenc);
@@ -973,8 +988,11 @@ static void ipsec_esp_encrypt_done(struct device *dev,
 
/* copy the generated ICV to dst */
if (edesc->icv_ool) {
-   icvdata = >link_tbl[edesc->src_nents +
-  edesc->dst_nents + 2];
+   if (is_sec1)
+   icvdata = edesc->buf + areq->assoclen + areq->cryptlen;
+   else
+   icvdata = >link_tbl[edesc->src_nents +
+  edesc->dst_nents + 2];
sg = sg_last(areq->dst, edesc->dst_nents);
memcpy((char *)sg_virt(sg) + sg->length - authsize,
   icvdata, authsize);
@@ -995,6 +1013,8 @@ static void ipsec_esp_decrypt_swauth_done(struct device 
*dev,
struct talitos_edesc *edesc;
struct scatterlist *sg;
char *oicv, *icv;
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
 
edesc = container_of(desc, struct talitos_edesc, desc);
 
@@ -1006,7 +1026,12 @@ static void ipsec_esp_decrypt_swauth_done(struct device 
*dev,
icv = (char *)sg_virt(sg) + sg->length - authsize;
 
if (edesc->dma_len) {
-   oicv = (char *)>link_tbl[edesc->src_nents +
+   if (is_sec1)
+   oicv = (char *)>dma_link_tbl +
+  req->assoclen + req->cryptlen;
+   else
+   oicv = (char *)
+  >link_tbl[edesc->src_nents +
edesc->dst_nents + 2];
if (edesc->icv_ool)
icv = oicv + authsize;
@@ -1145,42 +1170,52 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
int tbl_off = 0;
int sg_count, ret;
int sg_link_tbl_len;
+   bool sync_needed = false;
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
 
/* hmac key */
map_single_talitos_ptr(dev, >ptr[0], ctx->authkeylen, >key,
   

[PATCH v2 0/7] crypto: talitos - implementation of AEAD for SEC1

2016-06-06 Thread Christophe Leroy
This set of patches provides the implementation of AEAD for
talitos SEC1.

Changes in v2:
* Fixed compilation issue introduced by later cosmetic changes
requested by checkpatch script
* split "making mapping helpers more generic" in two parts
to better see the changes done after the move.
* reworked the DMA sync associated with mapping in order to not
spend time syncing several times

Christophe Leroy (7):
  crypto: talitos - using helpers for all talitos_ptr operations
  crypto: talitos - move mapping helpers before IPSEC functions
  crypto: talitos - making mapping helpers more generic
  crypto: talitos - Implement AEAD for SEC1 using HMAC_SNOOP_NO_AFEU
  crypto: talitos - sg_to_link_tbl() not used anymore, remove it
  crypto: talitos - implement cra_priority
  crypto: talitos - templates for AEAD using HMAC_SNOOP_NO_AFEU

 drivers/crypto/talitos.c | 672 ++-
 1 file changed, 426 insertions(+), 246 deletions(-)

-- 
2.1.0

--
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 6/7] crypto: talitos - implement cra_priority

2016-06-06 Thread Christophe Leroy
SEC1 doesn't have IPSEC_ESP descriptor type but it is able to perform
IPSEC using HMAC_SNOOP_NO_AFEU, which is also existing on SEC2
In order to be able to define descriptors templates for SEC1 without
breaking SEC2+, we have to give lower priority to HMAC_SNOOP_NO_AFEU
so that SEC2+ selects IPSEC_ESP and not HMAC_SNOOP_NO_AFEU which is
less performant.

This is done by adding a priority field in the template. If the field
is 0, we use the default priority, otherwise we used the one in the
field.

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index ff8cf39..dfd3a93 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -2120,6 +2120,7 @@ static int ahash_setkey(struct crypto_ahash *tfm, const 
u8 *key,
 
 struct talitos_alg_template {
u32 type;
+   u32 priority;
union {
struct crypto_alg crypto;
struct ahash_alg hash;
@@ -2897,7 +2898,10 @@ static struct talitos_crypto_alg 
*talitos_alg_alloc(struct device *dev,
}
 
alg->cra_module = THIS_MODULE;
-   alg->cra_priority = TALITOS_CRA_PRIORITY;
+   if (t_alg->algt.priority)
+   alg->cra_priority = t_alg->algt.priority;
+   else
+   alg->cra_priority = TALITOS_CRA_PRIORITY;
alg->cra_alignmask = 0;
alg->cra_ctxsize = sizeof(struct talitos_ctx);
alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY;
-- 
2.1.0

--
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 3/7] crypto: talitos - making mapping helpers more generic

2016-06-06 Thread Christophe Leroy
In preparation of IPSEC for SEC1, first step is to make the mapping
helpers more generic so that they can also be used by AEAD functions.

First, the functions are moved before IPSEC functions in talitos.c

talitos_sg_unmap() and unmap_sg_talitos_ptr() are merged as they
are quite similar, the second one handling the SEC1 case an calling
the first one for SEC2

map_sg_in_talitos_ptr() and map_sg_out_talitos_ptr() are merged
into talitos_sg_map() and enhenced to support offseted zones
as used for AEAD. The actual mapping is now performed outside that
helper. The DMA sync is also done outside to not make it several
times.

talitos_edesc_alloc() size calculation are fixed to also take into
account AEAD specific parts also for SEC1

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 230 +++
 1 file changed, 93 insertions(+), 137 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index beb369e..b0d3c24 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -911,45 +911,28 @@ struct talitos_edesc {
 static void talitos_sg_unmap(struct device *dev,
 struct talitos_edesc *edesc,
 struct scatterlist *src,
-struct scatterlist *dst)
+struct scatterlist *dst,
+unsigned int len, unsigned int offset)
 {
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
unsigned int src_nents = edesc->src_nents ? : 1;
unsigned int dst_nents = edesc->dst_nents ? : 1;
 
+   if (is_sec1 && dst && dst_nents > 1) {
+   dma_sync_single_for_device(dev, edesc->dma_link_tbl + offset,
+  len, DMA_FROM_DEVICE);
+   sg_pcopy_from_buffer(dst, dst_nents, edesc->buf + offset, len,
+offset);
+   }
if (src != dst) {
-   dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
+   if (src_nents == 1 || !is_sec1)
+   dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
 
-   if (dst) {
+   if (dst && (dst_nents == 1 || !is_sec1))
dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
-   }
-   } else
+   } else if (src_nents == 1 || !is_sec1) {
dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
-}
-
-static void unmap_sg_talitos_ptr(struct device *dev, struct scatterlist *src,
-struct scatterlist *dst, unsigned int len,
-struct talitos_edesc *edesc)
-{
-   struct talitos_private *priv = dev_get_drvdata(dev);
-   bool is_sec1 = has_ftr_sec1(priv);
-
-   if (is_sec1) {
-   if (!edesc->src_nents) {
-   dma_unmap_sg(dev, src, 1,
-dst != src ? DMA_TO_DEVICE
-   : DMA_BIDIRECTIONAL);
-   }
-   if (dst && edesc->dst_nents) {
-   dma_sync_single_for_device(dev,
-  edesc->dma_link_tbl + len,
-  len, DMA_FROM_DEVICE);
-   sg_copy_from_buffer(dst, edesc->dst_nents ? : 1,
-   edesc->buf + len, len);
-   } else if (dst && dst != src) {
-   dma_unmap_sg(dev, dst, 1, DMA_FROM_DEVICE);
-   }
-   } else {
-   talitos_sg_unmap(dev, edesc, src, dst);
}
 }
 
@@ -962,7 +945,8 @@ static void ipsec_esp_unmap(struct device *dev,
unmap_single_talitos_ptr(dev, >desc.ptr[2], DMA_TO_DEVICE);
unmap_single_talitos_ptr(dev, >desc.ptr[0], DMA_TO_DEVICE);
 
-   talitos_sg_unmap(dev, edesc, areq->src, areq->dst);
+   talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen,
+areq->assoclen);
 
if (edesc->dma_len)
dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
@@ -1110,99 +1094,37 @@ static inline int sg_to_link_tbl(struct scatterlist 
*sg, int sg_count,
 link_tbl_ptr);
 }
 
-int map_sg_in_talitos_ptr(struct device *dev, struct scatterlist *src,
- unsigned int len, struct talitos_edesc *edesc,
- enum dma_data_direction dir, struct talitos_ptr *ptr)
+int talitos_sg_map(struct device *dev, struct scatterlist *src,
+  unsigned int len, struct talitos_edesc *edesc,
+  struct talitos_ptr *ptr,
+  int sg_count, unsigned int offset, int tbl_off)
 {
-   i

[PATCH v2 2/7] crypto: talitos - move mapping helpers before IPSEC functions

2016-06-06 Thread Christophe Leroy
In order to be able to use the mapping/unmapping helpers for IPSEC
it needs to be move upper in the file

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 244 +++
 1 file changed, 122 insertions(+), 122 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index a92aa37..beb369e 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -926,6 +926,33 @@ static void talitos_sg_unmap(struct device *dev,
dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
 }
 
+static void unmap_sg_talitos_ptr(struct device *dev, struct scatterlist *src,
+struct scatterlist *dst, unsigned int len,
+struct talitos_edesc *edesc)
+{
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
+
+   if (is_sec1) {
+   if (!edesc->src_nents) {
+   dma_unmap_sg(dev, src, 1,
+dst != src ? DMA_TO_DEVICE
+   : DMA_BIDIRECTIONAL);
+   }
+   if (dst && edesc->dst_nents) {
+   dma_sync_single_for_device(dev,
+  edesc->dma_link_tbl + len,
+  len, DMA_FROM_DEVICE);
+   sg_copy_from_buffer(dst, edesc->dst_nents ? : 1,
+   edesc->buf + len, len);
+   } else if (dst && dst != src) {
+   dma_unmap_sg(dev, dst, 1, DMA_FROM_DEVICE);
+   }
+   } else {
+   talitos_sg_unmap(dev, edesc, src, dst);
+   }
+}
+
 static void ipsec_esp_unmap(struct device *dev,
struct talitos_edesc *edesc,
struct aead_request *areq)
@@ -1083,6 +1110,101 @@ static inline int sg_to_link_tbl(struct scatterlist 
*sg, int sg_count,
 link_tbl_ptr);
 }
 
+int map_sg_in_talitos_ptr(struct device *dev, struct scatterlist *src,
+ unsigned int len, struct talitos_edesc *edesc,
+ enum dma_data_direction dir, struct talitos_ptr *ptr)
+{
+   int sg_count;
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
+
+   to_talitos_ptr_len(ptr, len, is_sec1);
+
+   if (is_sec1) {
+   sg_count = edesc->src_nents ? : 1;
+
+   if (sg_count == 1) {
+   dma_map_sg(dev, src, 1, dir);
+   to_talitos_ptr(ptr, sg_dma_address(src), is_sec1);
+   } else {
+   sg_copy_to_buffer(src, sg_count, edesc->buf, len);
+   to_talitos_ptr(ptr, edesc->dma_link_tbl, is_sec1);
+   dma_sync_single_for_device(dev, edesc->dma_link_tbl,
+  len, DMA_TO_DEVICE);
+   }
+   } else {
+   to_talitos_ptr_ext_set(ptr, 0, is_sec1);
+
+   sg_count = dma_map_sg(dev, src, edesc->src_nents ? : 1, dir);
+
+   if (sg_count == 1) {
+   to_talitos_ptr(ptr, sg_dma_address(src), is_sec1);
+   } else {
+   sg_count = sg_to_link_tbl(src, sg_count, len,
+ >link_tbl[0]);
+   if (sg_count > 1) {
+   to_talitos_ptr(ptr, edesc->dma_link_tbl, 0);
+   to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP,
+ 0);
+   dma_sync_single_for_device(dev,
+  edesc->dma_link_tbl,
+  edesc->dma_len,
+  DMA_BIDIRECTIONAL);
+   } else {
+   /* Only one segment now, so no link tbl needed*/
+   to_talitos_ptr(ptr, sg_dma_address(src),
+  is_sec1);
+   }
+   }
+   }
+   return sg_count;
+}
+
+void map_sg_out_talitos_ptr(struct device *dev, struct scatterlist *dst,
+   unsigned int len, struct talitos_edesc *edesc,
+   enum dma_data_direction dir,
+   struct talitos_ptr *ptr, int sg_count)
+{
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
+
+   if (dir != DMA_NONE)
+   sg_count = dma_map_sg(dev, dst, edesc->dst_nents ? : 1, dir);

[PATCH v2 7/7] crypto: talitos - templates for AEAD using HMAC_SNOOP_NO_AFEU

2016-06-06 Thread Christophe Leroy
This will allow IPSEC on SEC1

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 180 +++
 1 file changed, 180 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index dfd3a93..0418a2f 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -811,6 +811,11 @@ static void talitos_unregister_rng(struct device *dev)
  * crypto alg
  */
 #define TALITOS_CRA_PRIORITY   3000
+/*
+ * Defines a priority for doing AEAD with descriptors type
+ * HMAC_SNOOP_NO_AFEA (HSNA) instead of type IPSEC_ESP
+ */
+#define TALITOS_CRA_PRIORITY_AEAD_HSNA (TALITOS_CRA_PRIORITY - 1)
 #define TALITOS_MAX_KEY_SIZE   96
 #define TALITOS_MAX_IV_LENGTH  16 /* max of AES_BLOCK_SIZE, 
DES3_EDE_BLOCK_SIZE */
 
@@ -2152,6 +2157,27 @@ static struct talitos_alg_template driver_algs[] = {
 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
},
{   .type = CRYPTO_ALG_TYPE_AEAD,
+   .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
+   .alg.aead = {
+   .base = {
+   .cra_name = "authenc(hmac(sha1),cbc(aes))",
+   .cra_driver_name = "authenc-hmac-sha1-"
+  "cbc-aes-talitos",
+   .cra_blocksize = AES_BLOCK_SIZE,
+   .cra_flags = CRYPTO_ALG_ASYNC,
+   },
+   .ivsize = AES_BLOCK_SIZE,
+   .maxauthsize = SHA1_DIGEST_SIZE,
+   },
+   .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
+DESC_HDR_SEL0_AESU |
+DESC_HDR_MODE0_AESU_CBC |
+DESC_HDR_SEL1_MDEUA |
+DESC_HDR_MODE1_MDEU_INIT |
+DESC_HDR_MODE1_MDEU_PAD |
+DESC_HDR_MODE1_MDEU_SHA1_HMAC,
+   },
+   {   .type = CRYPTO_ALG_TYPE_AEAD,
.alg.aead = {
.base = {
.cra_name = "authenc(hmac(sha1),"
@@ -2173,6 +2199,29 @@ static struct talitos_alg_template driver_algs[] = {
 DESC_HDR_MODE1_MDEU_PAD |
 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
},
+   {   .type = CRYPTO_ALG_TYPE_AEAD,
+   .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
+   .alg.aead = {
+   .base = {
+   .cra_name = "authenc(hmac(sha1),"
+   "cbc(des3_ede))",
+   .cra_driver_name = "authenc-hmac-sha1-"
+  "cbc-3des-talitos",
+   .cra_blocksize = DES3_EDE_BLOCK_SIZE,
+   .cra_flags = CRYPTO_ALG_ASYNC,
+   },
+   .ivsize = DES3_EDE_BLOCK_SIZE,
+   .maxauthsize = SHA1_DIGEST_SIZE,
+   },
+   .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
+DESC_HDR_SEL0_DEU |
+DESC_HDR_MODE0_DEU_CBC |
+DESC_HDR_MODE0_DEU_3DES |
+DESC_HDR_SEL1_MDEUA |
+DESC_HDR_MODE1_MDEU_INIT |
+DESC_HDR_MODE1_MDEU_PAD |
+DESC_HDR_MODE1_MDEU_SHA1_HMAC,
+   },
{   .type = CRYPTO_ALG_TYPE_AEAD,
.alg.aead = {
.base = {
@@ -2193,6 +2242,27 @@ static struct talitos_alg_template driver_algs[] = {
 DESC_HDR_MODE1_MDEU_PAD |
 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
},
+   {   .type = CRYPTO_ALG_TYPE_AEAD,
+   .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
+   .alg.aead = {
+   .base = {
+   .cra_name = "authenc(hmac(sha224),cbc(aes))",
+   .cra_driver_name = "authenc-hmac-sha224-"
+  "cbc-aes-talitos",
+   .cra_blocksize = AES_BLOCK_SIZE,
+   .cra_flags = CRYPTO_ALG_ASYNC,
+   },
+   .ivsize = AES_BLOCK_SIZE,
+   .maxauthsize = SHA224_DIGEST_SIZE,
+   },
+   .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
+ 

[PATCH v2 5/7] crypto: talitos - sg_to_link_tbl() not used anymore, remove it

2016-06-06 Thread Christophe Leroy
Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 8 
 1 file changed, 8 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 4ff03c3..ff8cf39 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -,14 +,6 @@ next:
return count;
 }
 
-static inline int sg_to_link_tbl(struct scatterlist *sg, int sg_count,
-int cryptlen,
-struct talitos_ptr *link_tbl_ptr)
-{
-   return sg_to_link_tbl_offset(sg, sg_count, 0, cryptlen,
-link_tbl_ptr);
-}
-
 int talitos_sg_map(struct device *dev, struct scatterlist *src,
   unsigned int len, struct talitos_edesc *edesc,
   struct talitos_ptr *ptr,
-- 
2.1.0

--
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 1/7] crypto: talitos - using helpers for all talitos_ptr operations

2016-06-06 Thread Christophe Leroy
Use helper for all modifications to talitos_ptr in preparation to
the implementation of AEAD for SEC1

to_talitos_ptr_extent_clear() has been removed in favor of
to_talitos_ptr_ext_set() to set any value and
to_talitos_ptr_ext_or() to or the extent field with a value
name has been shorten to help keeping single lines of 80 chars

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 59 
 1 file changed, 34 insertions(+), 25 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index b7ee8d3..a92aa37 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -91,10 +91,17 @@ static unsigned short from_talitos_ptr_len(struct 
talitos_ptr *ptr,
return be16_to_cpu(ptr->len);
 }
 
-static void to_talitos_ptr_extent_clear(struct talitos_ptr *ptr, bool is_sec1)
+static void to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val,
+  bool is_sec1)
 {
if (!is_sec1)
-   ptr->j_extent = 0;
+   ptr->j_extent = val;
+}
+
+static void to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val, bool 
is_sec1)
+{
+   if (!is_sec1)
+   ptr->j_extent |= val;
 }
 
 /*
@@ -111,7 +118,7 @@ static void map_single_talitos_ptr(struct device *dev,
 
to_talitos_ptr_len(ptr, len, is_sec1);
to_talitos_ptr(ptr, dma_addr, is_sec1);
-   to_talitos_ptr_extent_clear(ptr, is_sec1);
+   to_talitos_ptr_ext_set(ptr, 0, is_sec1);
 }
 
 /*
@@ -1050,8 +1057,8 @@ static int sg_to_link_tbl_offset(struct scatterlist *sg, 
int sg_count,
 
to_talitos_ptr(link_tbl_ptr + count,
   sg_dma_address(sg) + offset, 0);
-   link_tbl_ptr[count].len = cpu_to_be16(len);
-   link_tbl_ptr[count].j_extent = 0;
+   to_talitos_ptr_len(link_tbl_ptr + count, len, 0);
+   to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
count++;
cryptlen -= len;
offset = 0;
@@ -1062,7 +1069,8 @@ next:
 
/* tag end of link table */
if (count > 0)
-   link_tbl_ptr[count - 1].j_extent = DESC_PTR_LNKTBL_RETURN;
+   to_talitos_ptr_ext_set(link_tbl_ptr + count - 1,
+  DESC_PTR_LNKTBL_RETURN, 0);
 
return count;
 }
@@ -1102,14 +1110,14 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
  (areq->src == areq->dst) ? DMA_BIDIRECTIONAL
   : DMA_TO_DEVICE);
/* hmac data */
-   desc->ptr[1].len = cpu_to_be16(areq->assoclen);
+   to_talitos_ptr_len(>ptr[1], areq->assoclen, 0);
if (sg_count > 1 &&
(ret = sg_to_link_tbl_offset(areq->src, sg_count, 0,
 areq->assoclen,
 >link_tbl[tbl_off])) > 1) {
to_talitos_ptr(>ptr[1], edesc->dma_link_tbl + tbl_off *
   sizeof(struct talitos_ptr), 0);
-   desc->ptr[1].j_extent = DESC_PTR_LNKTBL_JUMP;
+   to_talitos_ptr_ext_set(>ptr[1], DESC_PTR_LNKTBL_JUMP, 0);
 
dma_sync_single_for_device(dev, edesc->dma_link_tbl,
   edesc->dma_len, DMA_BIDIRECTIONAL);
@@ -1117,13 +1125,13 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
tbl_off += ret;
} else {
to_talitos_ptr(>ptr[1], sg_dma_address(areq->src), 0);
-   desc->ptr[1].j_extent = 0;
+   to_talitos_ptr_ext_set(>ptr[1], 0, 0);
}
 
/* cipher iv */
to_talitos_ptr(>ptr[2], edesc->iv_dma, 0);
-   desc->ptr[2].len = cpu_to_be16(ivsize);
-   desc->ptr[2].j_extent = 0;
+   to_talitos_ptr_len(>ptr[2], ivsize, 0);
+   to_talitos_ptr_ext_set(>ptr[2], 0, 0);
 
/* cipher key */
map_single_talitos_ptr(dev, >ptr[3], ctx->enckeylen,
@@ -1136,8 +1144,8 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
 * extent is bytes of HMAC postpended to ciphertext,
 * typically 12 for ipsec
 */
-   desc->ptr[4].len = cpu_to_be16(cryptlen);
-   desc->ptr[4].j_extent = authsize;
+   to_talitos_ptr_len(>ptr[4], cryptlen, 0);
+   to_talitos_ptr_ext_set(>ptr[4], authsize, 0);
 
sg_link_tbl_len = cryptlen;
if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV)
@@ -1150,7 +1158,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
areq->assoclen, sg_link_tbl_len,
  

Re: [PATCH 2/6] crypto: talitos - making mapping helpers more generic

2016-06-06 Thread Christophe Leroy



Le 31/05/2016 à 11:46, Herbert Xu a écrit :

On Fri, May 27, 2016 at 11:32:36AM +0200, Christophe Leroy wrote:

+   sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len,
+>link_tbl[tbl_off])
+   if (sg_count == 1) {
+   /* Only one segment now, so no link tbl needed*/
+   copy_talitos_ptr(ptr, >link_tbl[tbl_off], is_sec1);
+   return sg_count;
+   }

This patch doesn't build.
Oops, I was too quick on doing the cosmetic modifications requested by 
the checkpatch script.

Sorry for that, I will submit a new version this week

Christophe
--
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] crypto: talitos - making mapping helpers more generic

2016-05-27 Thread Christophe Leroy
In preparation of IPSEC for SEC1, first step is to make the mapping
helpers more generic so that they can also be used by AEAD functions.

First, the functions are moved before IPSEC functions in talitos.c

talitos_sg_unmap() and unmap_sg_talitos_ptr() are merged as they
are quite similar, the second one handling the SEC1 case an calling
the first one for SEC2

map_sg_in_talitos_ptr() and map_sg_out_talitos_ptr() are merged
into talitos_sg_map() and enhenced to support offseted zones
as used for AEAD. The actual mapping is now performed outside that
helper.

talitos_edesc_alloc() size calculation are fixed to also take into
account AEAD specific parts also for SEC1

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 243 ++-
 1 file changed, 94 insertions(+), 149 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index a92aa37..0f5a739 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -911,19 +911,29 @@ struct talitos_edesc {
 static void talitos_sg_unmap(struct device *dev,
 struct talitos_edesc *edesc,
 struct scatterlist *src,
-struct scatterlist *dst)
+struct scatterlist *dst,
+unsigned int len, unsigned int offset)
 {
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
unsigned int src_nents = edesc->src_nents ? : 1;
unsigned int dst_nents = edesc->dst_nents ? : 1;
 
+   if (is_sec1 && dst && dst_nents > 1) {
+   dma_sync_single_for_device(dev, edesc->dma_link_tbl + offset,
+  len, DMA_FROM_DEVICE);
+   sg_pcopy_from_buffer(dst, dst_nents, edesc->buf + offset, len,
+offset);
+   }
if (src != dst) {
-   dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
+   if (src_nents == 1 || !is_sec1)
+   dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
 
-   if (dst) {
+   if (dst && (dst_nents == 1 || !is_sec1))
dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
-   }
-   } else
+   } else if (src_nents == 1 || !is_sec1) {
dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
+   }
 }
 
 static void ipsec_esp_unmap(struct device *dev,
@@ -935,7 +945,8 @@ static void ipsec_esp_unmap(struct device *dev,
unmap_single_talitos_ptr(dev, >desc.ptr[2], DMA_TO_DEVICE);
unmap_single_talitos_ptr(dev, >desc.ptr[0], DMA_TO_DEVICE);
 
-   talitos_sg_unmap(dev, edesc, areq->src, areq->dst);
+   talitos_sg_unmap(dev, edesc, areq->src, areq->dst, areq->cryptlen,
+areq->assoclen);
 
if (edesc->dma_len)
dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
@@ -1083,6 +1094,44 @@ static inline int sg_to_link_tbl(struct scatterlist *sg, 
int sg_count,
 link_tbl_ptr);
 }
 
+int talitos_sg_map(struct device *dev, struct scatterlist *src,
+  unsigned int len, struct talitos_edesc *edesc,
+  struct talitos_ptr *ptr,
+  int sg_count, unsigned int offset, int tbl_off)
+{
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
+
+   to_talitos_ptr_len(ptr, len, is_sec1);
+   to_talitos_ptr_ext_set(ptr, 0, is_sec1);
+
+   if (sg_count == 1) {
+   to_talitos_ptr(ptr, sg_dma_address(src) + offset, is_sec1);
+   return sg_count;
+   }
+   if (is_sec1) {
+   to_talitos_ptr(ptr, edesc->dma_link_tbl + offset, is_sec1);
+   dma_sync_single_for_device(dev, edesc->dma_link_tbl,
+  edesc->dma_len, DMA_BIDIRECTIONAL);
+   return sg_count;
+   }
+   sg_count = sg_to_link_tbl_offset(src, sg_count, offset, len,
+>link_tbl[tbl_off])
+   if (sg_count == 1) {
+   /* Only one segment now, so no link tbl needed*/
+   copy_talitos_ptr(ptr, >link_tbl[tbl_off], is_sec1);
+   return sg_count;
+   }
+   to_talitos_ptr(ptr, edesc->dma_link_tbl +
+   tbl_off * sizeof(struct talitos_ptr), is_sec1);
+   to_talitos_ptr_ext_or(ptr, DESC_PTR_LNKTBL_JUMP, is_sec1);
+
+   dma_sync_single_for_device(dev, edesc->dma_link_tbl, edesc->dma_len,
+  DMA_BIDIRECTIONAL);
+
+   return sg_count;
+}
+
 /*
  * fill in and submit ipsec_esp descriptor
  */
@@ -1241,7 +1290,7 @@ static struct talitos_edesc *talitos_edesc_alloc

[PATCH 1/6] crypto: talitos - using helpers for all talitos_ptr operations

2016-05-27 Thread Christophe Leroy
Use helper for all modifications to talitos_ptr in preparation to
the implementation of AEAD for SEC1

to_talitos_ptr_extent_clear() has been removed in favor of
to_talitos_ptr_ext_set() to set any value and
to_talitos_ptr_ext_or() to or the extent field with a value
name has been shorten to help keeping single lines of 80 chars

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 59 
 1 file changed, 34 insertions(+), 25 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index b7ee8d3..a92aa37 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -91,10 +91,17 @@ static unsigned short from_talitos_ptr_len(struct 
talitos_ptr *ptr,
return be16_to_cpu(ptr->len);
 }
 
-static void to_talitos_ptr_extent_clear(struct talitos_ptr *ptr, bool is_sec1)
+static void to_talitos_ptr_ext_set(struct talitos_ptr *ptr, u8 val,
+  bool is_sec1)
 {
if (!is_sec1)
-   ptr->j_extent = 0;
+   ptr->j_extent = val;
+}
+
+static void to_talitos_ptr_ext_or(struct talitos_ptr *ptr, u8 val, bool 
is_sec1)
+{
+   if (!is_sec1)
+   ptr->j_extent |= val;
 }
 
 /*
@@ -111,7 +118,7 @@ static void map_single_talitos_ptr(struct device *dev,
 
to_talitos_ptr_len(ptr, len, is_sec1);
to_talitos_ptr(ptr, dma_addr, is_sec1);
-   to_talitos_ptr_extent_clear(ptr, is_sec1);
+   to_talitos_ptr_ext_set(ptr, 0, is_sec1);
 }
 
 /*
@@ -1050,8 +1057,8 @@ static int sg_to_link_tbl_offset(struct scatterlist *sg, 
int sg_count,
 
to_talitos_ptr(link_tbl_ptr + count,
   sg_dma_address(sg) + offset, 0);
-   link_tbl_ptr[count].len = cpu_to_be16(len);
-   link_tbl_ptr[count].j_extent = 0;
+   to_talitos_ptr_len(link_tbl_ptr + count, len, 0);
+   to_talitos_ptr_ext_set(link_tbl_ptr + count, 0, 0);
count++;
cryptlen -= len;
offset = 0;
@@ -1062,7 +1069,8 @@ next:
 
/* tag end of link table */
if (count > 0)
-   link_tbl_ptr[count - 1].j_extent = DESC_PTR_LNKTBL_RETURN;
+   to_talitos_ptr_ext_set(link_tbl_ptr + count - 1,
+  DESC_PTR_LNKTBL_RETURN, 0);
 
return count;
 }
@@ -1102,14 +1110,14 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
  (areq->src == areq->dst) ? DMA_BIDIRECTIONAL
   : DMA_TO_DEVICE);
/* hmac data */
-   desc->ptr[1].len = cpu_to_be16(areq->assoclen);
+   to_talitos_ptr_len(>ptr[1], areq->assoclen, 0);
if (sg_count > 1 &&
(ret = sg_to_link_tbl_offset(areq->src, sg_count, 0,
 areq->assoclen,
 >link_tbl[tbl_off])) > 1) {
to_talitos_ptr(>ptr[1], edesc->dma_link_tbl + tbl_off *
   sizeof(struct talitos_ptr), 0);
-   desc->ptr[1].j_extent = DESC_PTR_LNKTBL_JUMP;
+   to_talitos_ptr_ext_set(>ptr[1], DESC_PTR_LNKTBL_JUMP, 0);
 
dma_sync_single_for_device(dev, edesc->dma_link_tbl,
   edesc->dma_len, DMA_BIDIRECTIONAL);
@@ -1117,13 +1125,13 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
tbl_off += ret;
} else {
to_talitos_ptr(>ptr[1], sg_dma_address(areq->src), 0);
-   desc->ptr[1].j_extent = 0;
+   to_talitos_ptr_ext_set(>ptr[1], 0, 0);
}
 
/* cipher iv */
to_talitos_ptr(>ptr[2], edesc->iv_dma, 0);
-   desc->ptr[2].len = cpu_to_be16(ivsize);
-   desc->ptr[2].j_extent = 0;
+   to_talitos_ptr_len(>ptr[2], ivsize, 0);
+   to_talitos_ptr_ext_set(>ptr[2], 0, 0);
 
/* cipher key */
map_single_talitos_ptr(dev, >ptr[3], ctx->enckeylen,
@@ -1136,8 +1144,8 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
 * extent is bytes of HMAC postpended to ciphertext,
 * typically 12 for ipsec
 */
-   desc->ptr[4].len = cpu_to_be16(cryptlen);
-   desc->ptr[4].j_extent = authsize;
+   to_talitos_ptr_len(>ptr[4], cryptlen, 0);
+   to_talitos_ptr_ext_set(>ptr[4], authsize, 0);
 
sg_link_tbl_len = cryptlen;
if (edesc->desc.hdr & DESC_HDR_MODE1_MDEU_CICV)
@@ -1150,7 +1158,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
areq->assoclen, sg_link_tbl_len,
  

[PATCH 0/6] crypto: talitos - implementation of AEAD for SEC1

2016-05-27 Thread Christophe Leroy
This set of patches provides the implementation of AEAD for
talitos SEC1.

Christophe Leroy (6):
  crypto: talitos - using helpers for all talitos_ptr operations
  crypto: talitos - making mapping helpers more generic
  crypto: talitos - Implement AEAD for SEC1 using HMAC_SNOOP_NO_AFEU
  crypto: talitos - sg_to_link_tbl() not used anymore, remove it
  crypto: talitos - implement cra_priority
  crypto: talitos - templates for AEAD using HMAC_SNOOP_NO_AFEU

 drivers/crypto/talitos.c | 657 +--
 1 file changed, 410 insertions(+), 247 deletions(-)

-- 
2.1.0

--
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/6] crypto: talitos - Implement AEAD for SEC1 using HMAC_SNOOP_NO_AFEU

2016-05-27 Thread Christophe Leroy
This patchs enhances the IPSEC_ESP related functions for them to
also supports the same operations with descriptor type
HMAC_SNOOP_NO_AFEU.

The differences between the two descriptor types are:
* pointeurs 2 and 3 are swaped (Confidentiality key and
Primary EU Context IN)
* HMAC_SNOOP_NO_AFEU has CICV out in pointer 6
* HMAC_SNOOP_NO_AFEU has no primary EU context out so we get it
from the end of data out

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 205 +++
 1 file changed, 119 insertions(+), 86 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 0f5a739..c17e6c9 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -940,7 +940,13 @@ static void ipsec_esp_unmap(struct device *dev,
struct talitos_edesc *edesc,
struct aead_request *areq)
 {
-   unmap_single_talitos_ptr(dev, >desc.ptr[6], DMA_FROM_DEVICE);
+   struct crypto_aead *aead = crypto_aead_reqtfm(areq);
+   struct talitos_ctx *ctx = crypto_aead_ctx(aead);
+   unsigned int ivsize = crypto_aead_ivsize(aead);
+
+   if (edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP)
+   unmap_single_talitos_ptr(dev, >desc.ptr[6],
+DMA_FROM_DEVICE);
unmap_single_talitos_ptr(dev, >desc.ptr[3], DMA_TO_DEVICE);
unmap_single_talitos_ptr(dev, >desc.ptr[2], DMA_TO_DEVICE);
unmap_single_talitos_ptr(dev, >desc.ptr[0], DMA_TO_DEVICE);
@@ -951,6 +957,13 @@ static void ipsec_esp_unmap(struct device *dev,
if (edesc->dma_len)
dma_unmap_single(dev, edesc->dma_link_tbl, edesc->dma_len,
 DMA_BIDIRECTIONAL);
+
+   if (!(edesc->desc.hdr & DESC_HDR_TYPE_IPSEC_ESP)) {
+   unsigned int dst_nents = edesc->dst_nents ? : 1;
+
+   sg_pcopy_to_buffer(areq->dst, dst_nents, ctx->iv, ivsize,
+  areq->assoclen + areq->cryptlen - ivsize);
+   }
 }
 
 /*
@@ -960,6 +973,8 @@ static void ipsec_esp_encrypt_done(struct device *dev,
   struct talitos_desc *desc, void *context,
   int err)
 {
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
struct aead_request *areq = context;
struct crypto_aead *authenc = crypto_aead_reqtfm(areq);
unsigned int authsize = crypto_aead_authsize(authenc);
@@ -973,8 +988,11 @@ static void ipsec_esp_encrypt_done(struct device *dev,
 
/* copy the generated ICV to dst */
if (edesc->icv_ool) {
-   icvdata = >link_tbl[edesc->src_nents +
-  edesc->dst_nents + 2];
+   if (is_sec1)
+   icvdata = edesc->buf + areq->assoclen + areq->cryptlen;
+   else
+   icvdata = >link_tbl[edesc->src_nents +
+  edesc->dst_nents + 2];
sg = sg_last(areq->dst, edesc->dst_nents);
memcpy((char *)sg_virt(sg) + sg->length - authsize,
   icvdata, authsize);
@@ -995,6 +1013,8 @@ static void ipsec_esp_decrypt_swauth_done(struct device 
*dev,
struct talitos_edesc *edesc;
struct scatterlist *sg;
char *oicv, *icv;
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
 
edesc = container_of(desc, struct talitos_edesc, desc);
 
@@ -1006,7 +1026,12 @@ static void ipsec_esp_decrypt_swauth_done(struct device 
*dev,
icv = (char *)sg_virt(sg) + sg->length - authsize;
 
if (edesc->dma_len) {
-   oicv = (char *)>link_tbl[edesc->src_nents +
+   if (is_sec1)
+   oicv = (char *)>dma_link_tbl +
+  req->assoclen + req->cryptlen;
+   else
+   oicv = (char *)
+  >link_tbl[edesc->src_nents +
edesc->dst_nents + 2];
if (edesc->icv_ool)
icv = oicv + authsize;
@@ -1150,42 +1175,49 @@ static int ipsec_esp(struct talitos_edesc *edesc, 
struct aead_request *areq,
int tbl_off = 0;
int sg_count, ret;
int sg_link_tbl_len;
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
 
/* hmac key */
map_single_talitos_ptr(dev, >ptr[0], ctx->authkeylen, >key,
   DMA_TO_DEVICE);
 
-  

[PATCH 6/6] crypto: talitos - templates for AEAD using HMAC_SNOOP_NO_AFEU

2016-05-27 Thread Christophe Leroy
This will allow IPSEC on SEC1

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 180 +++
 1 file changed, 180 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index b554f56..d3951e3 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -811,6 +811,11 @@ static void talitos_unregister_rng(struct device *dev)
  * crypto alg
  */
 #define TALITOS_CRA_PRIORITY   3000
+/*
+ * Defines a priority for doing AEAD with descriptors type
+ * HMAC_SNOOP_NO_AFEA (HSNA) instead of type IPSEC_ESP
+ */
+#define TALITOS_CRA_PRIORITY_AEAD_HSNA (TALITOS_CRA_PRIORITY - 1)
 #define TALITOS_MAX_KEY_SIZE   96
 #define TALITOS_MAX_IV_LENGTH  16 /* max of AES_BLOCK_SIZE, 
DES3_EDE_BLOCK_SIZE */
 
@@ -2135,6 +2140,27 @@ static struct talitos_alg_template driver_algs[] = {
 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
},
{   .type = CRYPTO_ALG_TYPE_AEAD,
+   .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
+   .alg.aead = {
+   .base = {
+   .cra_name = "authenc(hmac(sha1),cbc(aes))",
+   .cra_driver_name = "authenc-hmac-sha1-"
+  "cbc-aes-talitos",
+   .cra_blocksize = AES_BLOCK_SIZE,
+   .cra_flags = CRYPTO_ALG_ASYNC,
+   },
+   .ivsize = AES_BLOCK_SIZE,
+   .maxauthsize = SHA1_DIGEST_SIZE,
+   },
+   .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
+DESC_HDR_SEL0_AESU |
+DESC_HDR_MODE0_AESU_CBC |
+DESC_HDR_SEL1_MDEUA |
+DESC_HDR_MODE1_MDEU_INIT |
+DESC_HDR_MODE1_MDEU_PAD |
+DESC_HDR_MODE1_MDEU_SHA1_HMAC,
+   },
+   {   .type = CRYPTO_ALG_TYPE_AEAD,
.alg.aead = {
.base = {
.cra_name = "authenc(hmac(sha1),"
@@ -2156,6 +2182,29 @@ static struct talitos_alg_template driver_algs[] = {
 DESC_HDR_MODE1_MDEU_PAD |
 DESC_HDR_MODE1_MDEU_SHA1_HMAC,
},
+   {   .type = CRYPTO_ALG_TYPE_AEAD,
+   .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
+   .alg.aead = {
+   .base = {
+   .cra_name = "authenc(hmac(sha1),"
+   "cbc(des3_ede))",
+   .cra_driver_name = "authenc-hmac-sha1-"
+  "cbc-3des-talitos",
+   .cra_blocksize = DES3_EDE_BLOCK_SIZE,
+   .cra_flags = CRYPTO_ALG_ASYNC,
+   },
+   .ivsize = DES3_EDE_BLOCK_SIZE,
+   .maxauthsize = SHA1_DIGEST_SIZE,
+   },
+   .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
+DESC_HDR_SEL0_DEU |
+DESC_HDR_MODE0_DEU_CBC |
+DESC_HDR_MODE0_DEU_3DES |
+DESC_HDR_SEL1_MDEUA |
+DESC_HDR_MODE1_MDEU_INIT |
+DESC_HDR_MODE1_MDEU_PAD |
+DESC_HDR_MODE1_MDEU_SHA1_HMAC,
+   },
{   .type = CRYPTO_ALG_TYPE_AEAD,
.alg.aead = {
.base = {
@@ -2176,6 +2225,27 @@ static struct talitos_alg_template driver_algs[] = {
 DESC_HDR_MODE1_MDEU_PAD |
 DESC_HDR_MODE1_MDEU_SHA224_HMAC,
},
+   {   .type = CRYPTO_ALG_TYPE_AEAD,
+   .priority = TALITOS_CRA_PRIORITY_AEAD_HSNA,
+   .alg.aead = {
+   .base = {
+   .cra_name = "authenc(hmac(sha224),cbc(aes))",
+   .cra_driver_name = "authenc-hmac-sha224-"
+  "cbc-aes-talitos",
+   .cra_blocksize = AES_BLOCK_SIZE,
+   .cra_flags = CRYPTO_ALG_ASYNC,
+   },
+   .ivsize = AES_BLOCK_SIZE,
+   .maxauthsize = SHA224_DIGEST_SIZE,
+   },
+   .desc_hdr_template = DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU |
+ 

AEAD in TALITOS SEC1 versus TALITOS SEC2

2016-04-20 Thread Christophe Leroy
Today, in Talitos driver crypto alg registration is based on predefined 
templates with a predefined descriptor type and verification against the 
descriptors supported by the HW. This works well for ALG that require a 
unique descriptor. But for IPsec this is slightly different:
* IPsec can be performed with both DESC_HDR_TYPE_IPSEC_ESP and 
DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU

* DESC_HDR_TYPE_IPSEC_ESP is supported only by SEC2
* DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU is supported by both SEC1 and SEC2
* DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU is less performant than 
DESC_HDR_TYPE_IPSEC_ESP
So it is natural to use DESC_HDR_TYPE_IPSEC_ESP when it is supported and 
use DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU otherwise ?


What's the best way to implement the selection of the proper descriptor 
type ?
* We can duplicate the templates but it means that when both types are 
supported the driver with try to register each AEAD alg twice
* We can "on the fly" change the DESC_HDR_TYPE_IPSEC_ESP type into 
DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU type ?
* We can alter the templates at startup when we know we are on a SEC1, 
changing all templates based on DESC_HDR_TYPE_IPSEC_ESP into templates 
based on DESC_HDR_TYPE_HMAC_SNOOP_NO_AFEU


What would be the best approach from your point of view ?

Christophe
--
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: talitos - add new crypto modes

2015-12-01 Thread Christophe Leroy
This patch adds the following algorithms to the talitos driver:
* ecb(aes)
* ctr(aes)
* ecb(des)
* cbc(des)
* ecb(des3_ede)

Signed-off-by: Christophe Leroy <christophe.le...@c-s.fr>
---
 drivers/crypto/talitos.c | 83 
 drivers/crypto/talitos.h |  1 +
 2 files changed, 84 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index ab33898..a0d4a08 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -2324,6 +2324,22 @@ static struct talitos_alg_template driver_algs[] = {
/* ABLKCIPHER algorithms. */
{   .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
.alg.crypto = {
+   .cra_name = "ecb(aes)",
+   .cra_driver_name = "ecb-aes-talitos",
+   .cra_blocksize = AES_BLOCK_SIZE,
+   .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+CRYPTO_ALG_ASYNC,
+   .cra_ablkcipher = {
+   .min_keysize = AES_MIN_KEY_SIZE,
+   .max_keysize = AES_MAX_KEY_SIZE,
+   .ivsize = AES_BLOCK_SIZE,
+   }
+   },
+   .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+DESC_HDR_SEL0_AESU,
+   },
+   {   .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
+   .alg.crypto = {
.cra_name = "cbc(aes)",
.cra_driver_name = "cbc-aes-talitos",
.cra_blocksize = AES_BLOCK_SIZE,
@@ -2341,6 +2357,73 @@ static struct talitos_alg_template driver_algs[] = {
},
{   .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
.alg.crypto = {
+   .cra_name = "ctr(aes)",
+   .cra_driver_name = "ctr-aes-talitos",
+   .cra_blocksize = AES_BLOCK_SIZE,
+   .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+CRYPTO_ALG_ASYNC,
+   .cra_ablkcipher = {
+   .min_keysize = AES_MIN_KEY_SIZE,
+   .max_keysize = AES_MAX_KEY_SIZE,
+   .ivsize = AES_BLOCK_SIZE,
+   }
+   },
+   .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+DESC_HDR_SEL0_AESU |
+DESC_HDR_MODE0_AESU_CTR,
+   },
+   {   .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
+   .alg.crypto = {
+   .cra_name = "ecb(des)",
+   .cra_driver_name = "ecb-des-talitos",
+   .cra_blocksize = DES_BLOCK_SIZE,
+   .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+CRYPTO_ALG_ASYNC,
+   .cra_ablkcipher = {
+   .min_keysize = DES_KEY_SIZE,
+   .max_keysize = DES_KEY_SIZE,
+   .ivsize = DES_BLOCK_SIZE,
+   }
+   },
+   .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+DESC_HDR_SEL0_DEU,
+   },
+   {   .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
+   .alg.crypto = {
+   .cra_name = "cbc(des)",
+   .cra_driver_name = "cbc-des-talitos",
+   .cra_blocksize = DES_BLOCK_SIZE,
+   .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+CRYPTO_ALG_ASYNC,
+   .cra_ablkcipher = {
+   .min_keysize = DES_KEY_SIZE,
+   .max_keysize = DES_KEY_SIZE,
+   .ivsize = DES_BLOCK_SIZE,
+   }
+   },
+   .desc_hdr_template = DESC_HDR_TYPE_COMMON_NONSNOOP_NO_AFEU |
+DESC_HDR_SEL0_DEU |
+DESC_HDR_MODE0_DEU_CBC,
+   },
+   {   .type = CRYPTO_ALG_TYPE_ABLKCIPHER,
+   .alg.crypto = {
+   .cra_name = "ecb(des3_ede)",
+   .cra_driver_name = "ecb-3des-talitos",
+   .cra_blocksize = DES3_EDE_BLOCK_SIZE,
+   .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER |
+CRYPTO_ALG_ASYNC,
+   .cra_ablkcipher = {
+   .min_keysize = DES3_EDE_KEY_SIZE,
+   .max_keysize = DES3_EDE_KEY_SIZE,
+   .ivsize = DES3_EDE_BLOCK

Re: [PATCH 1/4] crypto: talitos: dma_map_sg can handle chained SG

2015-09-23 Thread Christophe Leroy


Le 23/09/2015 13:55, LABBE Corentin a écrit :

The talitos driver use two dma_map_sg path
according to SG are chained or not.
Since dma_map_sg can handle both case, clean the code with all
references to sg chained.

Thus removing talitos_map_sg, talitos_unmap_sg_chain
and sg_count functions.


Shouldn't the replacement of sg_count()  by sg_nents_for_len() be part 
of second patch ?


Christophe
--
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 v3] splice: sendfile() at once fails for big files

2015-05-06 Thread Christophe Leroy
Using sendfile with below small program to get MD5 sums of some files,
it appear that big files (over 64kbytes with 4k pages system) get a
wrong MD5 sum while small files get the correct sum.
This program uses sendfile() to send a file to an AF_ALG socket
for hashing.


/* md5sum2.c */
#include stdio.h
#include stdlib.h
#include unistd.h
#include string.h
#include fcntl.h
#include sys/socket.h
#include sys/stat.h
#include sys/types.h
#include linux/if_alg.h

int main(int argc, char **argv)
{
int sk = socket(AF_ALG, SOCK_SEQPACKET, 0);
struct stat st;
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = hash,
.salg_name = md5,
};
int n;

bind(sk, (struct sockaddr*)sa, sizeof(sa));

for (n = 1; n  argc; n++) {
int size;
int offset = 0;
char buf[4096];
int fd;
int sko;
int i;

fd = open(argv[n], O_RDONLY);
sko = accept(sk, NULL, 0);
fstat(fd, st);
size = st.st_size;
sendfile(sko, fd, offset, size);
size = read(sko, buf, sizeof(buf));
for (i = 0; i  size; i++)
printf(%2.2x, buf[i]);
printf(  %s\n, argv[n]);
close(fd);
close(sko);
}
exit(0);
}

Test below is done using official linux patch files. First result is
with a software based md5sum. Second result is with the program above.

root@vgoip:~# ls -l patch-3.6.*
-rw-r--r--1 root root 64011 Aug 24 12:01 patch-3.6.2.gz
-rw-r--r--1 root root 94131 Aug 24 12:01 patch-3.6.3.gz

root@vgoip:~# md5sum patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
c5e8f687878457db77cb7158c38a7e43  patch-3.6.3.gz

root@vgoip:~# ./md5sum2 patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
5fd77b24e68bb24dcc72d6e57c64790e  patch-3.6.3.gz


After investivation, it appears that sendfile() sends the files by blocks
of 64kbytes (16 times PAGE_SIZE). The problem is that at the end of each
block, the SPLICE_F_MORE flag is missing, therefore the hashing operation
is reset as if it was the end of the file.

This patch adds SPLICE_F_MORE to the flags when more data is pending.

With the patch applied, we get the correct sums:

root@vgoip:~# md5sum patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
c5e8f687878457db77cb7158c38a7e43  patch-3.6.3.gz

root@vgoip:~# ./md5sum2 patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
c5e8f687878457db77cb7158c38a7e43  patch-3.6.3.gz

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 v2: no change, only new commit text
 v3: comment added iaw Jens Axboe suggestion
 
 fs/splice.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/fs/splice.c b/fs/splice.c
index 476024b..bfe62ae 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1161,7 +1161,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct 
splice_desc *sd,
long ret, bytes;
umode_t i_mode;
size_t len;
-   int i, flags;
+   int i, flags, more;
 
/*
 * We require the input being a regular file, as we don't want to
@@ -1204,6 +1204,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct 
splice_desc *sd,
 * Don't block on output, we have to drain the direct pipe.
 */
sd-flags = ~SPLICE_F_NONBLOCK;
+   more = sd-flags  SPLICE_F_MORE;
 
while (len) {
size_t read_len;
@@ -1217,6 +1218,15 @@ ssize_t splice_direct_to_actor(struct file *in, struct 
splice_desc *sd,
sd-total_len = read_len;
 
/*
+* If more data is pending, set SPLICE_F_MORE
+* If this is the last data and SPLICE_F_MORE was not set
+* initially, clears it.
+*/
+   if (read_len  len)
+   sd-flags |= SPLICE_F_MORE;
+   else if (!more)
+   sd-flags = ~SPLICE_F_MORE;
+   /*
 * NOTE: nonblocking mode only applies to the input. We
 * must not do the output in nonblocking mode as then we
 * could get stuck data in the internal pipe:
-- 
2.1.0

--
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] splice: sendfile() at once fails for big files

2015-04-23 Thread Christophe Leroy
Using sendfile with below small program to get MD5 sums of some files,
it appear that big files (over 64kbytes with 4k pages system) get a
wrong MD5 sum while small files get the correct sum.
This program uses sendfile() to send a file to an AF_ALG socket
for hashing.


/* md5sum2.c */
#include stdio.h
#include stdlib.h
#include unistd.h
#include string.h
#include fcntl.h
#include sys/socket.h
#include sys/stat.h
#include sys/types.h
#include linux/if_alg.h

int main(int argc, char **argv)
{
int sk = socket(AF_ALG, SOCK_SEQPACKET, 0);
struct stat st;
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = hash,
.salg_name = md5,
};
int n;

bind(sk, (struct sockaddr*)sa, sizeof(sa));

for (n = 1; n  argc; n++) {
int size;
int offset = 0;
char buf[4096];
int fd;
int sko;
int i;

fd = open(argv[n], O_RDONLY);
sko = accept(sk, NULL, 0);
fstat(fd, st);
size = st.st_size;
sendfile(sko, fd, offset, size);
size = read(sko, buf, sizeof(buf));
for (i = 0; i  size; i++)
printf(%2.2x, buf[i]);
printf(  %s\n, argv[n]);
close(fd);
close(sko);
}
exit(0);
}

Test below is done using official linux patch files. First result is
with a software based md5sum. Second result is with the program above.

root@vgoip:~# ls -l patch-3.6.*
-rw-r--r--1 root root 64011 Aug 24 12:01 patch-3.6.2.gz
-rw-r--r--1 root root 94131 Aug 24 12:01 patch-3.6.3.gz

root@vgoip:~# md5sum patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
c5e8f687878457db77cb7158c38a7e43  patch-3.6.3.gz

root@vgoip:~# ./md5sum2 patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
5fd77b24e68bb24dcc72d6e57c64790e  patch-3.6.3.gz


After investivation, it appears that sendfile() sends the files by blocks
of 64kbytes (16 times PAGE_SIZE). The problem is that at the end of each
block, the SPLICE_F_MORE flag is missing, therefore the hashing operation
is reset as if it was the end of the file.

This patch adds SPLICE_F_MORE to the flags when more data is pending.

With the patch applied, we get the correct sums:

root@vgoip:~# md5sum patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
c5e8f687878457db77cb7158c38a7e43  patch-3.6.3.gz

root@vgoip:~# ./md5sum2 patch-3.6.*
b3ffb9848196846f31b2ff133d2d6443  patch-3.6.2.gz
c5e8f687878457db77cb7158c38a7e43  patch-3.6.3.gz

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 v2: no change, only new commit text
 
 fs/splice.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/fs/splice.c b/fs/splice.c
index 476024b..fe61723 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1161,7 +1161,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct 
splice_desc *sd,
long ret, bytes;
umode_t i_mode;
size_t len;
-   int i, flags;
+   int i, flags, more;
 
/*
 * We require the input being a regular file, as we don't want to
@@ -1204,6 +1204,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct 
splice_desc *sd,
 * Don't block on output, we have to drain the direct pipe.
 */
sd-flags = ~SPLICE_F_NONBLOCK;
+   more = sd-flags  SPLICE_F_MORE;
 
while (len) {
size_t read_len;
@@ -1216,6 +1217,10 @@ ssize_t splice_direct_to_actor(struct file *in, struct 
splice_desc *sd,
read_len = ret;
sd-total_len = read_len;
 
+   if (read_len  len)
+   sd-flags |= SPLICE_F_MORE;
+   else if (!more)
+   sd-flags = ~SPLICE_F_MORE;
/*
 * NOTE: nonblocking mode only applies to the input. We
 * must not do the output in nonblocking mode as then we
-- 
2.1.0

--
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 v3 13/17] crypto: talitos - adapt interrupts and reset functions to SEC1

2015-04-17 Thread Christophe Leroy
This patch adapts the interrupts handling and reset function for
SEC1. On SEC1, registers are almost similar to SEC2+, but bits
are sometimes located at different places. So we need to define
TALITOS1 and TALITOS2 versions of some fields, and manage according
to whether it is SEC1 or SEC2.

On SEC1, only one interrupt vector is dedicated to the SEC, so only
interrupt_4ch is needed.

On SEC1, interrupts are enabled by clearing related bits in IMR,
while on SEC2, interrupts are enabled by seting the bits in IMR.

SEC1 also performs parity verification in the DES Unit. We have
to disable this feature because the test vectors provided in
the kernel have parity errors.

In reset functions, only SEC2 supports continuation after error.
For SEC1, we have to reset in all cases.

For errors handling, SEC2+ names have been kept, but displayed
text have been amended to reflect exact meaning on SEC1.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 227 +++
 drivers/crypto/talitos.h |  39 +---
 2 files changed, 199 insertions(+), 67 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 6d77699..1265405 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -124,12 +124,23 @@ static int reset_channel(struct device *dev, int ch)
 {
struct talitos_private *priv = dev_get_drvdata(dev);
unsigned int timeout = TALITOS_TIMEOUT;
+   bool is_sec1 = has_ftr_sec1(priv);
 
-   setbits32(priv-chan[ch].reg + TALITOS_CCCR, TALITOS_CCCR_RESET);
+   if (is_sec1) {
+   setbits32(priv-chan[ch].reg + TALITOS_CCCR_LO,
+ TALITOS1_CCCR_LO_RESET);
 
-   while ((in_be32(priv-chan[ch].reg + TALITOS_CCCR)  TALITOS_CCCR_RESET)
-   --timeout)
-   cpu_relax();
+   while ((in_be32(priv-chan[ch].reg + TALITOS_CCCR_LO) 
+   TALITOS1_CCCR_LO_RESET)  --timeout)
+   cpu_relax();
+   } else {
+   setbits32(priv-chan[ch].reg + TALITOS_CCCR,
+ TALITOS2_CCCR_RESET);
+
+   while ((in_be32(priv-chan[ch].reg + TALITOS_CCCR) 
+   TALITOS2_CCCR_RESET)  --timeout)
+   cpu_relax();
+   }
 
if (timeout == 0) {
dev_err(dev, failed to reset channel %d\n, ch);
@@ -152,11 +163,12 @@ static int reset_device(struct device *dev)
 {
struct talitos_private *priv = dev_get_drvdata(dev);
unsigned int timeout = TALITOS_TIMEOUT;
-   u32 mcr = TALITOS_MCR_SWR;
+   bool is_sec1 = has_ftr_sec1(priv);
+   u32 mcr = is_sec1 ? TALITOS1_MCR_SWR : TALITOS2_MCR_SWR;
 
setbits32(priv-reg + TALITOS_MCR, mcr);
 
-   while ((in_be32(priv-reg + TALITOS_MCR)  TALITOS_MCR_SWR)
+   while ((in_be32(priv-reg + TALITOS_MCR)  mcr)
--timeout)
cpu_relax();
 
@@ -180,6 +192,7 @@ static int init_device(struct device *dev)
 {
struct talitos_private *priv = dev_get_drvdata(dev);
int ch, err;
+   bool is_sec1 = has_ftr_sec1(priv);
 
/*
 * Master reset
@@ -203,8 +216,15 @@ static int init_device(struct device *dev)
}
 
/* enable channel done and error interrupts */
-   setbits32(priv-reg + TALITOS_IMR, TALITOS_IMR_INIT);
-   setbits32(priv-reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT);
+   if (is_sec1) {
+   clrbits32(priv-reg + TALITOS_IMR, TALITOS1_IMR_INIT);
+   clrbits32(priv-reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT);
+   /* disable parity error check in DEU (erroneous? test vect.) */
+   setbits32(priv-reg_deu + TALITOS_EUICR, TALITOS1_DEUICR_KPE);
+   } else {
+   setbits32(priv-reg + TALITOS_IMR, TALITOS2_IMR_INIT);
+   setbits32(priv-reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT);
+   }
 
/* disable integrity check error interrupts (use writeback instead) */
if (priv-features  TALITOS_FTR_HW_AUTH_CHECK)
@@ -349,8 +369,37 @@ static void flush_channel(struct device *dev, int ch, int 
error, int reset_ch)
 /*
  * process completed requests for channels that have done status
  */
-#define DEF_TALITOS_DONE(name, ch_done_mask)   \
-static void talitos_done_##name(unsigned long data)\
+#define DEF_TALITOS1_DONE(name, ch_done_mask)  \
+static void talitos1_done_##name(unsigned long data)   \
+{  \
+   struct device *dev = (struct device *)data; \
+   struct talitos_private *priv = dev_get_drvdata(dev);\
+   unsigned long flags;\
+   \
+   if (ch_done_mask  0x1000

[PATCH v3 00/17] crypto: talitos - Add support for SEC1

2015-04-17 Thread Christophe Leroy
The purpose of this set of patchs is to add to talitos crypto driver
the support for the SEC1 version of the security engine, which is
found in mpc885 and mpc8272 processors.

v3 is a complete rework of the patchset. Since a kernel can be built
with support for both MPC82xx and MPC83xx at the same time, talitos
driver shall support both SEC1 and SEC2+ at the same time.

Based on cryptodev-2.6 tree

Christophe Leroy (17):
  crypto: talitos - Use zero entry to init descriptors ptrs to zero
  crypto: talitos - Refactor the sg in/out chain allocation
  crypto: talitos - talitos_ptr renamed ptr for more lisibility
  crypto: talitos - Add a helper function to clear j_extent field
  crypto: talitos - remove param 'extent' in map_single_talitos_ptr()
  crypto: talitos - helper function for ptr len
  crypto: talitos - enhanced talitos_desc struct for SEC1
  crypto: talitos - add sub-choice in talitos CONFIG for SEC1
  crypto: talitos - Add a feature to tag SEC1
  crypto: talitos - fill in talitos descriptor iaw SEC1 or SEC2+
  crypto: talitos - adaptation of talitos_submit() for SEC1
  crypto: talitos - base address for Execution Units
  crypto: talitos - adapt interrupts and reset functions to SEC1
  crypto: talitos - implement scatter/gather copy for SEC1
  crypto: talitos - SEC1 bugs on 0 data hash
  crypto: talitos - Add fsl,sec1.0 compatible
  crypto: talitos - Update DT bindings with SEC1

 .../devicetree/bindings/crypto/fsl-sec2.txt|   6 +-
 drivers/crypto/Kconfig |  18 +
 drivers/crypto/talitos.c   | 727 +++--
 drivers/crypto/talitos.h   | 153 +++--
 4 files changed, 644 insertions(+), 260 deletions(-)

-- 
2.1.0

--
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 v3 10/17] crypto: talitos - fill in talitos descriptor iaw SEC1 or SEC2+

2015-04-17 Thread Christophe Leroy
talitos descriptor is slightly different for SEC1 and SEC2+, so
lets the helper function that fills the descriptor take into account
the type of SEC.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 105 ++-
 1 file changed, 67 insertions(+), 38 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index db95023..678b528 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -55,25 +55,38 @@
 
 #include talitos.h
 
-static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr)
+static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
+  bool is_sec1)
 {
ptr-ptr = cpu_to_be32(lower_32_bits(dma_addr));
-   ptr-eptr = upper_32_bits(dma_addr);
+   if (!is_sec1)
+   ptr-eptr = upper_32_bits(dma_addr);
 }
 
-static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned short len)
+static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned short len,
+  bool is_sec1)
 {
-   ptr-len = cpu_to_be16(len);
+   if (is_sec1) {
+   ptr-res = 0;
+   ptr-len1 = cpu_to_be16(len);
+   } else {
+   ptr-len = cpu_to_be16(len);
+   }
 }
 
-static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr)
+static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr,
+  bool is_sec1)
 {
-   return be16_to_cpu(ptr-len);
+   if (is_sec1)
+   return be16_to_cpu(ptr-len1);
+   else
+   return be16_to_cpu(ptr-len);
 }
 
-static void to_talitos_ptr_extent_clear(struct talitos_ptr *ptr)
+static void to_talitos_ptr_extent_clear(struct talitos_ptr *ptr, bool is_sec1)
 {
-   ptr-j_extent = 0;
+   if (!is_sec1)
+   ptr-j_extent = 0;
 }
 
 /*
@@ -85,10 +98,12 @@ static void map_single_talitos_ptr(struct device *dev,
   enum dma_data_direction dir)
 {
dma_addr_t dma_addr = dma_map_single(dev, data, len, dir);
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
 
-   to_talitos_ptr_len(ptr, len);
-   to_talitos_ptr(ptr, dma_addr);
-   to_talitos_ptr_extent_clear(ptr);
+   to_talitos_ptr_len(ptr, len, is_sec1);
+   to_talitos_ptr(ptr, dma_addr, is_sec1);
+   to_talitos_ptr_extent_clear(ptr, is_sec1);
 }
 
 /*
@@ -98,8 +113,11 @@ static void unmap_single_talitos_ptr(struct device *dev,
 struct talitos_ptr *ptr,
 enum dma_data_direction dir)
 {
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
+
dma_unmap_single(dev, be32_to_cpu(ptr-ptr),
-from_talitos_ptr_len(ptr), dir);
+from_talitos_ptr_len(ptr, is_sec1), dir);
 }
 
 static int reset_channel(struct device *dev, int ch)
@@ -922,7 +940,7 @@ static int sg_to_link_tbl(struct scatterlist *sg, int 
sg_count,
int n_sg = sg_count;
 
while (n_sg--) {
-   to_talitos_ptr(link_tbl_ptr, sg_dma_address(sg));
+   to_talitos_ptr(link_tbl_ptr, sg_dma_address(sg), 0);
link_tbl_ptr-len = cpu_to_be16(sg_dma_len(sg));
link_tbl_ptr-j_extent = 0;
link_tbl_ptr++;
@@ -976,7 +994,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
struct talitos_ptr *tbl_ptr = edesc-link_tbl[tbl_off];
 
to_talitos_ptr(desc-ptr[1], edesc-dma_link_tbl + tbl_off *
-  sizeof(struct talitos_ptr));
+  sizeof(struct talitos_ptr), 0);
desc-ptr[1].j_extent = DESC_PTR_LNKTBL_JUMP;
 
/* assoc_nents - 1 entries for assoc, 1 for IV */
@@ -987,7 +1005,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
tbl_ptr += sg_count - 1;
tbl_ptr-j_extent = 0;
tbl_ptr++;
-   to_talitos_ptr(tbl_ptr, edesc-iv_dma);
+   to_talitos_ptr(tbl_ptr, edesc-iv_dma, 0);
tbl_ptr-len = cpu_to_be16(ivsize);
tbl_ptr-j_extent = DESC_PTR_LNKTBL_RETURN;
 
@@ -996,14 +1014,14 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
} else {
if (areq-assoclen)
to_talitos_ptr(desc-ptr[1],
-  sg_dma_address(areq-assoc));
+  sg_dma_address(areq-assoc), 0);
else
-   to_talitos_ptr(desc-ptr[1], edesc-iv_dma);
+   to_talitos_ptr(desc-ptr[1], edesc-iv_dma, 0);
desc-ptr[1].j_extent = 0;
}
 
/* cipher iv

[PATCH v3 02/17] crypto: talitos - Refactor the sg in/out chain allocation

2015-04-17 Thread Christophe Leroy
This patch refactors the handling of the input and output data that is quite
similar in several functions

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 159 ---
 1 file changed, 81 insertions(+), 78 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 7bf1b2b..5a7e345 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1327,16 +1327,23 @@ static int ablkcipher_setkey(struct crypto_ablkcipher 
*cipher,
return 0;
 }
 
+static void unmap_sg_talitos_ptr(struct device *dev, struct scatterlist *src,
+struct scatterlist *dst, unsigned int len,
+struct talitos_edesc *edesc)
+{
+   talitos_sg_unmap(dev, edesc, src, dst);
+}
+
 static void common_nonsnoop_unmap(struct device *dev,
  struct talitos_edesc *edesc,
  struct ablkcipher_request *areq)
 {
unmap_single_talitos_ptr(dev, edesc-desc.ptr[5], DMA_FROM_DEVICE);
+
+   unmap_sg_talitos_ptr(dev, areq-src, areq-dst, areq-nbytes, edesc);
unmap_single_talitos_ptr(dev, edesc-desc.ptr[2], DMA_TO_DEVICE);
unmap_single_talitos_ptr(dev, edesc-desc.ptr[1], DMA_TO_DEVICE);
 
-   talitos_sg_unmap(dev, edesc, areq-src, areq-dst);
-
if (edesc-dma_len)
dma_unmap_single(dev, edesc-dma_link_tbl, edesc-dma_len,
 DMA_BIDIRECTIONAL);
@@ -1358,6 +1365,65 @@ static void ablkcipher_done(struct device *dev,
areq-base.complete(areq-base, err);
 }
 
+int map_sg_in_talitos_ptr(struct device *dev, struct scatterlist *src,
+ unsigned int len, struct talitos_edesc *edesc,
+ enum dma_data_direction dir, struct talitos_ptr *ptr)
+{
+   int sg_count;
+
+   ptr-len = cpu_to_be16(len);
+   ptr-j_extent = 0;
+
+   sg_count = talitos_map_sg(dev, src, edesc-src_nents ? : 1, dir,
+ edesc-src_chained);
+
+   if (sg_count == 1) {
+   to_talitos_ptr(ptr, sg_dma_address(src));
+   } else {
+   sg_count = sg_to_link_tbl(src, sg_count, len,
+ edesc-link_tbl[0]);
+   if (sg_count  1) {
+   to_talitos_ptr(ptr, edesc-dma_link_tbl);
+   ptr-j_extent |= DESC_PTR_LNKTBL_JUMP;
+   dma_sync_single_for_device(dev, edesc-dma_link_tbl,
+  edesc-dma_len,
+  DMA_BIDIRECTIONAL);
+   } else {
+   /* Only one segment now, so no link tbl needed */
+   to_talitos_ptr(ptr, sg_dma_address(src));
+   }
+   }
+   return sg_count;
+}
+
+void map_sg_out_talitos_ptr(struct device *dev, struct scatterlist *dst,
+   unsigned int len, struct talitos_edesc *edesc,
+   enum dma_data_direction dir,
+   struct talitos_ptr *ptr, int sg_count)
+{
+   ptr-len = cpu_to_be16(len);
+   ptr-j_extent = 0;
+
+   if (dir != DMA_NONE)
+   sg_count = talitos_map_sg(dev, dst, edesc-dst_nents ? : 1,
+ dir, edesc-dst_chained);
+
+   if (sg_count == 1) {
+   to_talitos_ptr(ptr, sg_dma_address(dst));
+   } else {
+   struct talitos_ptr *link_tbl_ptr =
+   edesc-link_tbl[edesc-src_nents + 1];
+
+   to_talitos_ptr(ptr, edesc-dma_link_tbl +
+ (edesc-src_nents + 1) *
+ sizeof(struct talitos_ptr));
+   ptr-j_extent |= DESC_PTR_LNKTBL_JUMP;
+   sg_count = sg_to_link_tbl(dst, sg_count, len, link_tbl_ptr);
+   dma_sync_single_for_device(dev, edesc-dma_link_tbl,
+  edesc-dma_len, DMA_BIDIRECTIONAL);
+   }
+}
+
 static int common_nonsnoop(struct talitos_edesc *edesc,
   struct ablkcipher_request *areq,
   void (*callback) (struct device *dev,
@@ -1387,56 +1453,16 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
/*
 * cipher in
 */
-   desc-ptr[3].len = cpu_to_be16(cryptlen);
-   desc-ptr[3].j_extent = 0;
-
-   sg_count = talitos_map_sg(dev, areq-src, edesc-src_nents ? : 1,
- (areq-src == areq-dst) ? DMA_BIDIRECTIONAL
-  : DMA_TO_DEVICE,
- edesc-src_chained);
-
-   if (sg_count == 1) {
-   to_talitos_ptr(desc-ptr[3], sg_dma_address(areq-src));
-   } else {
-   sg_count = sg_to_link_tbl(areq-src

[PATCH v3 07/17] crypto: talitos - enhanced talitos_desc struct for SEC1

2015-04-17 Thread Christophe Leroy
This patch enhances the talitos_desc struct with fields for SEC1.
SEC1 has only one header field, and has a 'next_desc' field in
addition.
This mixed descriptor will continue to fit SEC2, and for SEC1
we will recopy hdr value into hdr1 value in talitos_submit()

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.h | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h
index 61a1405..f078da1 100644
--- a/drivers/crypto/talitos.h
+++ b/drivers/crypto/talitos.h
@@ -37,9 +37,17 @@
 
 /* descriptor pointer entry */
 struct talitos_ptr {
-   __be16 len; /* length */
-   u8 j_extent;/* jump to sg link table and/or extent */
-   u8 eptr;/* extended address */
+   union {
+   struct {/* SEC2 format */
+   __be16 len; /* length */
+   u8 j_extent;/* jump to sg link table and/or extent*/
+   u8 eptr;/* extended address */
+   };
+   struct {/* SEC1 format */
+   __be16 res;
+   __be16 len1;/* length */
+   };
+   };
__be32 ptr; /* address */
 };
 
@@ -53,8 +61,12 @@ static const struct talitos_ptr zero_entry = {
 /* descriptor */
 struct talitos_desc {
__be32 hdr; /* header high bits */
-   __be32 hdr_lo;  /* header low bits */
+   union {
+   __be32 hdr_lo;  /* header low bits */
+   __be32 hdr1;/* header for SEC1 */
+   };
struct talitos_ptr ptr[7];  /* ptr/len pair array */
+   __be32 next_desc;   /* next descriptor (SEC1) */
 };
 
 /**
-- 
2.1.0

--
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 v3 03/17] crypto: talitos - talitos_ptr renamed ptr for more lisibility

2015-04-17 Thread Christophe Leroy
Linux CodyingStyle recommends to use short variables for local
variables. ptr is just good enough for those 3 lines functions.
It helps keep single lines shorter than 80 characters.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 20 ++--
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 5a7e345..fca0aed 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -55,37 +55,37 @@
 
 #include talitos.h
 
-static void to_talitos_ptr(struct talitos_ptr *talitos_ptr, dma_addr_t 
dma_addr)
+static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr)
 {
-   talitos_ptr-ptr = cpu_to_be32(lower_32_bits(dma_addr));
-   talitos_ptr-eptr = upper_32_bits(dma_addr);
+   ptr-ptr = cpu_to_be32(lower_32_bits(dma_addr));
+   ptr-eptr = upper_32_bits(dma_addr);
 }
 
 /*
  * map virtual single (contiguous) pointer to h/w descriptor pointer
  */
 static void map_single_talitos_ptr(struct device *dev,
-  struct talitos_ptr *talitos_ptr,
+  struct talitos_ptr *ptr,
   unsigned short len, void *data,
   unsigned char extent,
   enum dma_data_direction dir)
 {
dma_addr_t dma_addr = dma_map_single(dev, data, len, dir);
 
-   talitos_ptr-len = cpu_to_be16(len);
-   to_talitos_ptr(talitos_ptr, dma_addr);
-   talitos_ptr-j_extent = extent;
+   ptr-len = cpu_to_be16(len);
+   to_talitos_ptr(ptr, dma_addr);
+   ptr-j_extent = extent;
 }
 
 /*
  * unmap bus single (contiguous) h/w descriptor pointer
  */
 static void unmap_single_talitos_ptr(struct device *dev,
-struct talitos_ptr *talitos_ptr,
+struct talitos_ptr *ptr,
 enum dma_data_direction dir)
 {
-   dma_unmap_single(dev, be32_to_cpu(talitos_ptr-ptr),
-be16_to_cpu(talitos_ptr-len), dir);
+   dma_unmap_single(dev, be32_to_cpu(ptr-ptr),
+be16_to_cpu(ptr-len), dir);
 }
 
 static int reset_channel(struct device *dev, int ch)
-- 
2.1.0

--
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 v3 05/17] crypto: talitos - remove param 'extent' in map_single_talitos_ptr()

2015-04-17 Thread Christophe Leroy
map_single_talitos_ptr() is always called with extent == 0, so lets remove this 
unused parameter

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index c93f79b..81e5636 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -72,14 +72,13 @@ static void to_talitos_ptr_extent_clear(struct talitos_ptr 
*ptr)
 static void map_single_talitos_ptr(struct device *dev,
   struct talitos_ptr *ptr,
   unsigned short len, void *data,
-  unsigned char extent,
   enum dma_data_direction dir)
 {
dma_addr_t dma_addr = dma_map_single(dev, data, len, dir);
 
ptr-len = cpu_to_be16(len);
to_talitos_ptr(ptr, dma_addr);
-   ptr-j_extent = extent;
+   to_talitos_ptr_extent_clear(ptr);
 }
 
 /*
@@ -958,7 +957,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
 
/* hmac key */
map_single_talitos_ptr(dev, desc-ptr[0], ctx-authkeylen, ctx-key,
-  0, DMA_TO_DEVICE);
+  DMA_TO_DEVICE);
 
/* hmac data */
desc-ptr[1].len = cpu_to_be16(areq-assoclen + ivsize);
@@ -1002,7 +1001,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
 
/* cipher key */
map_single_talitos_ptr(dev, desc-ptr[3], ctx-enckeylen,
-  (char *)ctx-key + ctx-authkeylen, 0,
+  (char *)ctx-key + ctx-authkeylen,
   DMA_TO_DEVICE);
 
/*
@@ -1080,7 +1079,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
}
 
/* iv out */
-   map_single_talitos_ptr(dev, desc-ptr[6], ivsize, ctx-iv, 0,
+   map_single_talitos_ptr(dev, desc-ptr[6], ivsize, ctx-iv,
   DMA_FROM_DEVICE);
 
ret = talitos_submit(dev, ctx-ch, desc, callback, areq);
@@ -1453,7 +1452,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
 
/* cipher key */
map_single_talitos_ptr(dev, desc-ptr[2], ctx-keylen,
-  (char *)ctx-key, 0, DMA_TO_DEVICE);
+  (char *)ctx-key, DMA_TO_DEVICE);
 
/*
 * cipher in
@@ -1470,7 +1469,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
   desc-ptr[4], sg_count);
 
/* iv out */
-   map_single_talitos_ptr(dev, desc-ptr[5], ivsize, ctx-iv, 0,
+   map_single_talitos_ptr(dev, desc-ptr[5], ivsize, ctx-iv,
   DMA_FROM_DEVICE);
 
/* last DWORD empty */
@@ -1595,7 +1594,7 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
if (!req_ctx-first || req_ctx-swinit) {
map_single_talitos_ptr(dev, desc-ptr[1],
   req_ctx-hw_context_size,
-  (char *)req_ctx-hw_context, 0,
+  (char *)req_ctx-hw_context,
   DMA_TO_DEVICE);
req_ctx-swinit = 0;
} else {
@@ -1607,7 +1606,7 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
/* HMAC key */
if (ctx-keylen)
map_single_talitos_ptr(dev, desc-ptr[2], ctx-keylen,
-  (char *)ctx-key, 0, DMA_TO_DEVICE);
+  (char *)ctx-key, DMA_TO_DEVICE);
else
desc-ptr[2] = zero_entry;
 
@@ -1624,11 +1623,11 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
if (req_ctx-last)
map_single_talitos_ptr(dev, desc-ptr[5],
   crypto_ahash_digestsize(tfm),
-  areq-result, 0, DMA_FROM_DEVICE);
+  areq-result, DMA_FROM_DEVICE);
else
map_single_talitos_ptr(dev, desc-ptr[5],
   req_ctx-hw_context_size,
-  req_ctx-hw_context, 0, DMA_FROM_DEVICE);
+  req_ctx-hw_context, DMA_FROM_DEVICE);
 
/* last DWORD empty */
desc-ptr[6] = zero_entry;
-- 
2.1.0

--
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 v3 06/17] crypto: talitos - helper function for ptr len

2015-04-17 Thread Christophe Leroy
This patch adds a helper function for reads and writes of the len
param of the talitos descriptor. This will help implement
SEC1 later.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 24 +---
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 81e5636..bca6ded 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -61,6 +61,16 @@ static void to_talitos_ptr(struct talitos_ptr *ptr, 
dma_addr_t dma_addr)
ptr-eptr = upper_32_bits(dma_addr);
 }
 
+static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned short len)
+{
+   ptr-len = cpu_to_be16(len);
+}
+
+static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr)
+{
+   return be16_to_cpu(ptr-len);
+}
+
 static void to_talitos_ptr_extent_clear(struct talitos_ptr *ptr)
 {
ptr-j_extent = 0;
@@ -76,7 +86,7 @@ static void map_single_talitos_ptr(struct device *dev,
 {
dma_addr_t dma_addr = dma_map_single(dev, data, len, dir);
 
-   ptr-len = cpu_to_be16(len);
+   to_talitos_ptr_len(ptr, len);
to_talitos_ptr(ptr, dma_addr);
to_talitos_ptr_extent_clear(ptr);
 }
@@ -89,7 +99,7 @@ static void unmap_single_talitos_ptr(struct device *dev,
 enum dma_data_direction dir)
 {
dma_unmap_single(dev, be32_to_cpu(ptr-ptr),
-be16_to_cpu(ptr-len), dir);
+from_talitos_ptr_len(ptr), dir);
 }
 
 static int reset_channel(struct device *dev, int ch)
@@ -1375,7 +1385,7 @@ int map_sg_in_talitos_ptr(struct device *dev, struct 
scatterlist *src,
 {
int sg_count;
 
-   ptr-len = cpu_to_be16(len);
+   to_talitos_ptr_len(ptr, len);
to_talitos_ptr_extent_clear(ptr);
 
sg_count = talitos_map_sg(dev, src, edesc-src_nents ? : 1, dir,
@@ -1405,7 +1415,7 @@ void map_sg_out_talitos_ptr(struct device *dev, struct 
scatterlist *dst,
enum dma_data_direction dir,
struct talitos_ptr *ptr, int sg_count)
 {
-   ptr-len = cpu_to_be16(len);
+   to_talitos_ptr_len(ptr, len);
to_talitos_ptr_extent_clear(ptr);
 
if (dir != DMA_NONE)
@@ -1447,7 +1457,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
 
/* cipher iv */
to_talitos_ptr(desc-ptr[1], edesc-iv_dma);
-   desc-ptr[1].len = cpu_to_be16(ivsize);
+   to_talitos_ptr_len(desc-ptr[1], ivsize);
to_talitos_ptr_extent_clear(desc-ptr[1]);
 
/* cipher key */
@@ -1539,11 +1549,11 @@ static void common_nonsnoop_hash_unmap(struct device 
*dev,
unmap_sg_talitos_ptr(dev, req_ctx-psrc, NULL, 0, edesc);
 
/* When using hashctx-in, must unmap it. */
-   if (edesc-desc.ptr[1].len)
+   if (from_talitos_ptr_len(edesc-desc.ptr[1]))
unmap_single_talitos_ptr(dev, edesc-desc.ptr[1],
 DMA_TO_DEVICE);
 
-   if (edesc-desc.ptr[2].len)
+   if (from_talitos_ptr_len(edesc-desc.ptr[2]))
unmap_single_talitos_ptr(dev, edesc-desc.ptr[2],
 DMA_TO_DEVICE);
 
-- 
2.1.0

--
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 v3 04/17] crypto: talitos - Add a helper function to clear j_extent field

2015-04-17 Thread Christophe Leroy
j_extent field is specific to SEC2 so we add a helper function to clear it
so that SEC1 can redefine that function as nop

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index fca0aed..c93f79b 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -61,6 +61,11 @@ static void to_talitos_ptr(struct talitos_ptr *ptr, 
dma_addr_t dma_addr)
ptr-eptr = upper_32_bits(dma_addr);
 }
 
+static void to_talitos_ptr_extent_clear(struct talitos_ptr *ptr)
+{
+   ptr-j_extent = 0;
+}
+
 /*
  * map virtual single (contiguous) pointer to h/w descriptor pointer
  */
@@ -1372,7 +1377,7 @@ int map_sg_in_talitos_ptr(struct device *dev, struct 
scatterlist *src,
int sg_count;
 
ptr-len = cpu_to_be16(len);
-   ptr-j_extent = 0;
+   to_talitos_ptr_extent_clear(ptr);
 
sg_count = talitos_map_sg(dev, src, edesc-src_nents ? : 1, dir,
  edesc-src_chained);
@@ -1402,7 +1407,7 @@ void map_sg_out_talitos_ptr(struct device *dev, struct 
scatterlist *dst,
struct talitos_ptr *ptr, int sg_count)
 {
ptr-len = cpu_to_be16(len);
-   ptr-j_extent = 0;
+   to_talitos_ptr_extent_clear(ptr);
 
if (dir != DMA_NONE)
sg_count = talitos_map_sg(dev, dst, edesc-dst_nents ? : 1,
@@ -1444,7 +1449,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
/* cipher iv */
to_talitos_ptr(desc-ptr[1], edesc-iv_dma);
desc-ptr[1].len = cpu_to_be16(ivsize);
-   desc-ptr[1].j_extent = 0;
+   to_talitos_ptr_extent_clear(desc-ptr[1]);
 
/* cipher key */
map_single_talitos_ptr(dev, desc-ptr[2], ctx-keylen,
-- 
2.1.0

--
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 v3 04/17] crypto: talitos - Add a helper function to clear j_extent field

2015-04-17 Thread Christophe Leroy
j_extent field is specific to SEC2 so we add a helper function to clear it
so that SEC1 can redefine that function as nop

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index fca0aed..c93f79b 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -61,6 +61,11 @@ static void to_talitos_ptr(struct talitos_ptr *ptr, 
dma_addr_t dma_addr)
ptr-eptr = upper_32_bits(dma_addr);
 }
 
+static void to_talitos_ptr_extent_clear(struct talitos_ptr *ptr)
+{
+   ptr-j_extent = 0;
+}
+
 /*
  * map virtual single (contiguous) pointer to h/w descriptor pointer
  */
@@ -1372,7 +1377,7 @@ int map_sg_in_talitos_ptr(struct device *dev, struct 
scatterlist *src,
int sg_count;
 
ptr-len = cpu_to_be16(len);
-   ptr-j_extent = 0;
+   to_talitos_ptr_extent_clear(ptr);
 
sg_count = talitos_map_sg(dev, src, edesc-src_nents ? : 1, dir,
  edesc-src_chained);
@@ -1402,7 +1407,7 @@ void map_sg_out_talitos_ptr(struct device *dev, struct 
scatterlist *dst,
struct talitos_ptr *ptr, int sg_count)
 {
ptr-len = cpu_to_be16(len);
-   ptr-j_extent = 0;
+   to_talitos_ptr_extent_clear(ptr);
 
if (dir != DMA_NONE)
sg_count = talitos_map_sg(dev, dst, edesc-dst_nents ? : 1,
@@ -1444,7 +1449,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
/* cipher iv */
to_talitos_ptr(desc-ptr[1], edesc-iv_dma);
desc-ptr[1].len = cpu_to_be16(ivsize);
-   desc-ptr[1].j_extent = 0;
+   to_talitos_ptr_extent_clear(desc-ptr[1]);
 
/* cipher key */
map_single_talitos_ptr(dev, desc-ptr[2], ctx-keylen,
-- 
2.1.0

--
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 v3 12/17] crypto: talitos - base address for Execution Units

2015-04-17 Thread Christophe Leroy
SEC 1.0, 1.2 and 2.x+ have different EU base addresses, so we need to
define pointers for each EU in the driver private data structure.
The proper address is set by the probe function depending on the
SEC type, in order to provide access to the proper address.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 83 
 drivers/crypto/talitos.h | 72 +
 2 files changed, 100 insertions(+), 55 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index e6ea651..6d77699 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -208,7 +208,7 @@ static int init_device(struct device *dev)
 
/* disable integrity check error interrupts (use writeback instead) */
if (priv-features  TALITOS_FTR_HW_AUTH_CHECK)
-   setbits32(priv-reg + TALITOS_MDEUICR_LO,
+   setbits32(priv-reg_mdeu + TALITOS_EUICR_LO,
  TALITOS_MDEUICR_LO_ICE);
 
return 0;
@@ -424,44 +424,44 @@ static void report_eu_error(struct device *dev, int ch, 
u32 desc_hdr)
switch (desc_hdr  DESC_HDR_SEL0_MASK) {
case DESC_HDR_SEL0_AFEU:
dev_err(dev, AFEUISR 0x%08x_%08x\n,
-   in_be32(priv-reg + TALITOS_AFEUISR),
-   in_be32(priv-reg + TALITOS_AFEUISR_LO));
+   in_be32(priv-reg_afeu + TALITOS_EUISR),
+   in_be32(priv-reg_afeu + TALITOS_EUISR_LO));
break;
case DESC_HDR_SEL0_DEU:
dev_err(dev, DEUISR 0x%08x_%08x\n,
-   in_be32(priv-reg + TALITOS_DEUISR),
-   in_be32(priv-reg + TALITOS_DEUISR_LO));
+   in_be32(priv-reg_deu + TALITOS_EUISR),
+   in_be32(priv-reg_deu + TALITOS_EUISR_LO));
break;
case DESC_HDR_SEL0_MDEUA:
case DESC_HDR_SEL0_MDEUB:
dev_err(dev, MDEUISR 0x%08x_%08x\n,
-   in_be32(priv-reg + TALITOS_MDEUISR),
-   in_be32(priv-reg + TALITOS_MDEUISR_LO));
+   in_be32(priv-reg_mdeu + TALITOS_EUISR),
+   in_be32(priv-reg_mdeu + TALITOS_EUISR_LO));
break;
case DESC_HDR_SEL0_RNG:
dev_err(dev, RNGUISR 0x%08x_%08x\n,
-   in_be32(priv-reg + TALITOS_RNGUISR),
-   in_be32(priv-reg + TALITOS_RNGUISR_LO));
+   in_be32(priv-reg_rngu + TALITOS_ISR),
+   in_be32(priv-reg_rngu + TALITOS_ISR_LO));
break;
case DESC_HDR_SEL0_PKEU:
dev_err(dev, PKEUISR 0x%08x_%08x\n,
-   in_be32(priv-reg + TALITOS_PKEUISR),
-   in_be32(priv-reg + TALITOS_PKEUISR_LO));
+   in_be32(priv-reg_pkeu + TALITOS_EUISR),
+   in_be32(priv-reg_pkeu + TALITOS_EUISR_LO));
break;
case DESC_HDR_SEL0_AESU:
dev_err(dev, AESUISR 0x%08x_%08x\n,
-   in_be32(priv-reg + TALITOS_AESUISR),
-   in_be32(priv-reg + TALITOS_AESUISR_LO));
+   in_be32(priv-reg_aesu + TALITOS_EUISR),
+   in_be32(priv-reg_aesu + TALITOS_EUISR_LO));
break;
case DESC_HDR_SEL0_CRCU:
dev_err(dev, CRCUISR 0x%08x_%08x\n,
-   in_be32(priv-reg + TALITOS_CRCUISR),
-   in_be32(priv-reg + TALITOS_CRCUISR_LO));
+   in_be32(priv-reg_crcu + TALITOS_EUISR),
+   in_be32(priv-reg_crcu + TALITOS_EUISR_LO));
break;
case DESC_HDR_SEL0_KEU:
dev_err(dev, KEUISR 0x%08x_%08x\n,
-   in_be32(priv-reg + TALITOS_KEUISR),
-   in_be32(priv-reg + TALITOS_KEUISR_LO));
+   in_be32(priv-reg_pkeu + TALITOS_EUISR),
+   in_be32(priv-reg_pkeu + TALITOS_EUISR_LO));
break;
}
 
@@ -469,13 +469,13 @@ static void report_eu_error(struct device *dev, int ch, 
u32 desc_hdr)
case DESC_HDR_SEL1_MDEUA:
case DESC_HDR_SEL1_MDEUB:
dev_err(dev, MDEUISR 0x%08x_%08x\n,
-   in_be32(priv-reg + TALITOS_MDEUISR),
-   in_be32(priv-reg + TALITOS_MDEUISR_LO));
+   in_be32(priv-reg_mdeu + TALITOS_EUISR),
+   in_be32(priv-reg_mdeu + TALITOS_EUISR_LO));
break;
case DESC_HDR_SEL1_CRCU:
dev_err(dev, CRCUISR 0x%08x_%08x\n,
-   in_be32(priv-reg + TALITOS_CRCUISR),
-   in_be32(priv-reg + TALITOS_CRCUISR_LO));
+   in_be32(priv-reg_crcu + TALITOS_EUISR),
+   in_be32(priv-reg_crcu

[PATCH v3 01/17] crypto: talitos - Use zero entry to init descriptors ptrs to zero

2015-04-17 Thread Christophe Leroy
Do use zero_entry value to init the descriptors ptrs to zero instead of
writing 0 in each field

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 857414a..7bf1b2b 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1373,9 +1373,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
int sg_count, ret;
 
/* first DWORD empty */
-   desc-ptr[0].len = 0;
-   to_talitos_ptr(desc-ptr[0], 0);
-   desc-ptr[0].j_extent = 0;
+   desc-ptr[0] = zero_entry;
 
/* cipher iv */
to_talitos_ptr(desc-ptr[1], edesc-iv_dma);
@@ -1445,9 +1443,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
   DMA_FROM_DEVICE);
 
/* last DWORD empty */
-   desc-ptr[6].len = 0;
-   to_talitos_ptr(desc-ptr[6], 0);
-   desc-ptr[6].j_extent = 0;
+   desc-ptr[6] = zero_entry;
 
ret = talitos_submit(dev, ctx-ch, desc, callback, areq);
if (ret != -EINPROGRESS) {
-- 
2.1.0

--
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 v3 05/17] crypto: talitos - remove param 'extent' in map_single_talitos_ptr()

2015-04-17 Thread Christophe Leroy
map_single_talitos_ptr() is always called with extent == 0, so lets remove this 
unused parameter

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index c93f79b..81e5636 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -72,14 +72,13 @@ static void to_talitos_ptr_extent_clear(struct talitos_ptr 
*ptr)
 static void map_single_talitos_ptr(struct device *dev,
   struct talitos_ptr *ptr,
   unsigned short len, void *data,
-  unsigned char extent,
   enum dma_data_direction dir)
 {
dma_addr_t dma_addr = dma_map_single(dev, data, len, dir);
 
ptr-len = cpu_to_be16(len);
to_talitos_ptr(ptr, dma_addr);
-   ptr-j_extent = extent;
+   to_talitos_ptr_extent_clear(ptr);
 }
 
 /*
@@ -958,7 +957,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
 
/* hmac key */
map_single_talitos_ptr(dev, desc-ptr[0], ctx-authkeylen, ctx-key,
-  0, DMA_TO_DEVICE);
+  DMA_TO_DEVICE);
 
/* hmac data */
desc-ptr[1].len = cpu_to_be16(areq-assoclen + ivsize);
@@ -1002,7 +1001,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
 
/* cipher key */
map_single_talitos_ptr(dev, desc-ptr[3], ctx-enckeylen,
-  (char *)ctx-key + ctx-authkeylen, 0,
+  (char *)ctx-key + ctx-authkeylen,
   DMA_TO_DEVICE);
 
/*
@@ -1080,7 +1079,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
}
 
/* iv out */
-   map_single_talitos_ptr(dev, desc-ptr[6], ivsize, ctx-iv, 0,
+   map_single_talitos_ptr(dev, desc-ptr[6], ivsize, ctx-iv,
   DMA_FROM_DEVICE);
 
ret = talitos_submit(dev, ctx-ch, desc, callback, areq);
@@ -1453,7 +1452,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
 
/* cipher key */
map_single_talitos_ptr(dev, desc-ptr[2], ctx-keylen,
-  (char *)ctx-key, 0, DMA_TO_DEVICE);
+  (char *)ctx-key, DMA_TO_DEVICE);
 
/*
 * cipher in
@@ -1470,7 +1469,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
   desc-ptr[4], sg_count);
 
/* iv out */
-   map_single_talitos_ptr(dev, desc-ptr[5], ivsize, ctx-iv, 0,
+   map_single_talitos_ptr(dev, desc-ptr[5], ivsize, ctx-iv,
   DMA_FROM_DEVICE);
 
/* last DWORD empty */
@@ -1595,7 +1594,7 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
if (!req_ctx-first || req_ctx-swinit) {
map_single_talitos_ptr(dev, desc-ptr[1],
   req_ctx-hw_context_size,
-  (char *)req_ctx-hw_context, 0,
+  (char *)req_ctx-hw_context,
   DMA_TO_DEVICE);
req_ctx-swinit = 0;
} else {
@@ -1607,7 +1606,7 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
/* HMAC key */
if (ctx-keylen)
map_single_talitos_ptr(dev, desc-ptr[2], ctx-keylen,
-  (char *)ctx-key, 0, DMA_TO_DEVICE);
+  (char *)ctx-key, DMA_TO_DEVICE);
else
desc-ptr[2] = zero_entry;
 
@@ -1624,11 +1623,11 @@ static int common_nonsnoop_hash(struct talitos_edesc 
*edesc,
if (req_ctx-last)
map_single_talitos_ptr(dev, desc-ptr[5],
   crypto_ahash_digestsize(tfm),
-  areq-result, 0, DMA_FROM_DEVICE);
+  areq-result, DMA_FROM_DEVICE);
else
map_single_talitos_ptr(dev, desc-ptr[5],
   req_ctx-hw_context_size,
-  req_ctx-hw_context, 0, DMA_FROM_DEVICE);
+  req_ctx-hw_context, DMA_FROM_DEVICE);
 
/* last DWORD empty */
desc-ptr[6] = zero_entry;
-- 
2.1.0

--
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 v3 06/17] crypto: talitos - helper function for ptr len

2015-04-17 Thread Christophe Leroy
This patch adds a helper function for reads and writes of the len
param of the talitos descriptor. This will help implement
SEC1 later.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 24 +---
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 81e5636..bca6ded 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -61,6 +61,16 @@ static void to_talitos_ptr(struct talitos_ptr *ptr, 
dma_addr_t dma_addr)
ptr-eptr = upper_32_bits(dma_addr);
 }
 
+static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned short len)
+{
+   ptr-len = cpu_to_be16(len);
+}
+
+static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr)
+{
+   return be16_to_cpu(ptr-len);
+}
+
 static void to_talitos_ptr_extent_clear(struct talitos_ptr *ptr)
 {
ptr-j_extent = 0;
@@ -76,7 +86,7 @@ static void map_single_talitos_ptr(struct device *dev,
 {
dma_addr_t dma_addr = dma_map_single(dev, data, len, dir);
 
-   ptr-len = cpu_to_be16(len);
+   to_talitos_ptr_len(ptr, len);
to_talitos_ptr(ptr, dma_addr);
to_talitos_ptr_extent_clear(ptr);
 }
@@ -89,7 +99,7 @@ static void unmap_single_talitos_ptr(struct device *dev,
 enum dma_data_direction dir)
 {
dma_unmap_single(dev, be32_to_cpu(ptr-ptr),
-be16_to_cpu(ptr-len), dir);
+from_talitos_ptr_len(ptr), dir);
 }
 
 static int reset_channel(struct device *dev, int ch)
@@ -1375,7 +1385,7 @@ int map_sg_in_talitos_ptr(struct device *dev, struct 
scatterlist *src,
 {
int sg_count;
 
-   ptr-len = cpu_to_be16(len);
+   to_talitos_ptr_len(ptr, len);
to_talitos_ptr_extent_clear(ptr);
 
sg_count = talitos_map_sg(dev, src, edesc-src_nents ? : 1, dir,
@@ -1405,7 +1415,7 @@ void map_sg_out_talitos_ptr(struct device *dev, struct 
scatterlist *dst,
enum dma_data_direction dir,
struct talitos_ptr *ptr, int sg_count)
 {
-   ptr-len = cpu_to_be16(len);
+   to_talitos_ptr_len(ptr, len);
to_talitos_ptr_extent_clear(ptr);
 
if (dir != DMA_NONE)
@@ -1447,7 +1457,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
 
/* cipher iv */
to_talitos_ptr(desc-ptr[1], edesc-iv_dma);
-   desc-ptr[1].len = cpu_to_be16(ivsize);
+   to_talitos_ptr_len(desc-ptr[1], ivsize);
to_talitos_ptr_extent_clear(desc-ptr[1]);
 
/* cipher key */
@@ -1539,11 +1549,11 @@ static void common_nonsnoop_hash_unmap(struct device 
*dev,
unmap_sg_talitos_ptr(dev, req_ctx-psrc, NULL, 0, edesc);
 
/* When using hashctx-in, must unmap it. */
-   if (edesc-desc.ptr[1].len)
+   if (from_talitos_ptr_len(edesc-desc.ptr[1]))
unmap_single_talitos_ptr(dev, edesc-desc.ptr[1],
 DMA_TO_DEVICE);
 
-   if (edesc-desc.ptr[2].len)
+   if (from_talitos_ptr_len(edesc-desc.ptr[2]))
unmap_single_talitos_ptr(dev, edesc-desc.ptr[2],
 DMA_TO_DEVICE);
 
-- 
2.1.0

--
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 v3 01/17] crypto: talitos - Use zero entry to init descriptors ptrs to zero

2015-04-17 Thread Christophe Leroy
Do use zero_entry value to init the descriptors ptrs to zero instead of
writing 0 in each field

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 857414a..7bf1b2b 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -1373,9 +1373,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
int sg_count, ret;
 
/* first DWORD empty */
-   desc-ptr[0].len = 0;
-   to_talitos_ptr(desc-ptr[0], 0);
-   desc-ptr[0].j_extent = 0;
+   desc-ptr[0] = zero_entry;
 
/* cipher iv */
to_talitos_ptr(desc-ptr[1], edesc-iv_dma);
@@ -1445,9 +1443,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
   DMA_FROM_DEVICE);
 
/* last DWORD empty */
-   desc-ptr[6].len = 0;
-   to_talitos_ptr(desc-ptr[6], 0);
-   desc-ptr[6].j_extent = 0;
+   desc-ptr[6] = zero_entry;
 
ret = talitos_submit(dev, ctx-ch, desc, callback, areq);
if (ret != -EINPROGRESS) {
-- 
2.1.0

--
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 v3 09/17] crypto: talitos - Add a feature to tag SEC1

2015-04-17 Thread Christophe Leroy
We add a new feature in the features field, to mark compatible
fsl,sec1.0
We also define a helper function called has_ftr_sec1() to help
functions quickly determine if they are running on SEC1 or SEC2+.
When only SEC1 or SEC2 is compiled in, has_ftr_sec1() return
trivial corresponding value. If both are compiled in, feature
field is checked.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c |  3 +++
 drivers/crypto/talitos.h | 17 +
 2 files changed, 20 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index bca6ded..db95023 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -2709,6 +2709,9 @@ static int talitos_probe(struct platform_device *ofdev)
  TALITOS_FTR_SHA224_HWINIT |
  TALITOS_FTR_HMAC_OK;
 
+   if (of_device_is_compatible(np, fsl,sec1.0))
+   priv-features |= TALITOS_FTR_SEC1;
+
priv-chan = kzalloc(sizeof(struct talitos_channel) *
 priv-num_channels, GFP_KERNEL);
if (!priv-chan) {
diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h
index f078da1..b0bdb4e 100644
--- a/drivers/crypto/talitos.h
+++ b/drivers/crypto/talitos.h
@@ -156,6 +156,23 @@ extern int talitos_submit(struct device *dev, int ch, 
struct talitos_desc *desc,
 #define TALITOS_FTR_HW_AUTH_CHECK 0x0002
 #define TALITOS_FTR_SHA224_HWINIT 0x0004
 #define TALITOS_FTR_HMAC_OK 0x0008
+#define TALITOS_FTR_SEC1 0x0010
+
+/*
+ * If both CONFIG_CRYPTO_DEV_TALITOS1 and CONFIG_CRYPTO_DEV_TALITOS2 are
+ * defined, we check the features which are set according to the device tree.
+ * Otherwise, we answer true or false directly
+ */
+static inline bool has_ftr_sec1(struct talitos_private *priv)
+{
+#if defined(CONFIG_CRYPTO_DEV_TALITOS1)  defined(CONFIG_CRYPTO_DEV_TALITOS2)
+   return priv-features  TALITOS_FTR_SEC1 ? true : false;
+#elif defined(CONFIG_CRYPTO_DEV_TALITOS1)
+   return true;
+#else
+   return false;
+#endif
+}
 
 /*
  * TALITOS_xxx_LO addresses point to the low data bits (32-63) of the register
-- 
2.1.0

--
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 v3 08/17] crypto: talitos - add sub-choice in talitos CONFIG for SEC1

2015-04-17 Thread Christophe Leroy
This patch adds a CONFIG option to select SEC1, SEC2+ or both.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/Kconfig | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 800bf41..8a76a01 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -222,6 +222,24 @@ config CRYPTO_DEV_TALITOS
  To compile this driver as a module, choose M here: the module
  will be called talitos.
 
+config CRYPTO_DEV_TALITOS1
+   bool SEC1 (SEC 1.0 and SEC Lite 1.2)
+   depends on CRYPTO_DEV_TALITOS
+   depends on PPC_8xx || PPC_82xx
+   default y
+   help
+ Say 'Y' here to use the Freescale Security Engine (SEC) version 1.0
+ found on MPC82xx or the Freescale Security Engine (SEC Lite)
+ version 1.2 found on MPC8xx
+
+config CRYPTO_DEV_TALITOS2
+   bool SEC2+ (SEC version 2.0 or upper)
+   depends on CRYPTO_DEV_TALITOS
+   default y if !PPC_8xx
+   help
+ Say 'Y' here to use the Freescale Security Engine (SEC)
+ version 2 and following as found on MPC83xx, MPC85xx, etc ...
+
 config CRYPTO_DEV_IXP4XX
tristate Driver for IXP4xx crypto hardware acceleration
depends on ARCH_IXP4XX  IXP4XX_QMGR  IXP4XX_NPE
-- 
2.1.0

--
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 v3 17/17] crypto: talitos - Update DT bindings with SEC1

2015-04-17 Thread Christophe Leroy
This patch updates the documentation by including SEC1 into SEC2/3 doc

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 Documentation/devicetree/bindings/crypto/fsl-sec2.txt | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec2.txt 
b/Documentation/devicetree/bindings/crypto/fsl-sec2.txt
index 38988ef..f0d926b 100644
--- a/Documentation/devicetree/bindings/crypto/fsl-sec2.txt
+++ b/Documentation/devicetree/bindings/crypto/fsl-sec2.txt
@@ -1,9 +1,11 @@
-Freescale SoC SEC Security Engines versions 2.x-3.x
+Freescale SoC SEC Security Engines versions 1.x-2.x-3.x
 
 Required properties:
 
 - compatible : Should contain entries for this and backward compatible
-  SEC versions, high to low, e.g., fsl,sec2.1, fsl,sec2.0
+  SEC versions, high to low, e.g., fsl,sec2.1, fsl,sec2.0 (SEC2/3)
+ e.g., fsl,sec1.2, fsl,sec1.0 (SEC1)
+warning: SEC1 and SEC2 are mutually exclusive
 - reg : Offset and length of the register set for the device
 - interrupts : the SEC's interrupt number
 - fsl,num-channels : An integer representing the number of channels
-- 
2.1.0

--
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 v3 16/17] crypto: talitos - Add fsl,sec1.0 compatible

2015-04-17 Thread Christophe Leroy
We add a specific compatible for SEC1, to handle the differences
between SEC1 and SEC2+

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index f1406d7b..c04074d 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -3086,9 +3086,16 @@ err_out:
 }
 
 static const struct of_device_id talitos_match[] = {
+#ifdef CONFIG_CRYPTO_DEV_TALITOS1
+   {
+   .compatible = fsl,sec1.0,
+   },
+#endif
+#ifdef CONFIG_CRYPTO_DEV_TALITOS2
{
.compatible = fsl,sec2.0,
},
+#endif
{},
 };
 MODULE_DEVICE_TABLE(of, talitos_match);
-- 
2.1.0

--
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 v3 17/17] crypto: talitos - Update DT bindings with SEC1

2015-04-17 Thread Christophe Leroy
This patch updates the documentation by including SEC1 into SEC2/3 doc

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 Documentation/devicetree/bindings/crypto/fsl-sec2.txt | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec2.txt 
b/Documentation/devicetree/bindings/crypto/fsl-sec2.txt
index 38988ef..f0d926b 100644
--- a/Documentation/devicetree/bindings/crypto/fsl-sec2.txt
+++ b/Documentation/devicetree/bindings/crypto/fsl-sec2.txt
@@ -1,9 +1,11 @@
-Freescale SoC SEC Security Engines versions 2.x-3.x
+Freescale SoC SEC Security Engines versions 1.x-2.x-3.x
 
 Required properties:
 
 - compatible : Should contain entries for this and backward compatible
-  SEC versions, high to low, e.g., fsl,sec2.1, fsl,sec2.0
+  SEC versions, high to low, e.g., fsl,sec2.1, fsl,sec2.0 (SEC2/3)
+ e.g., fsl,sec1.2, fsl,sec1.0 (SEC1)
+warning: SEC1 and SEC2 are mutually exclusive
 - reg : Offset and length of the register set for the device
 - interrupts : the SEC's interrupt number
 - fsl,num-channels : An integer representing the number of channels
-- 
2.1.0

--
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 v3 11/17] crypto: talitos - adaptation of talitos_submit() for SEC1

2015-04-17 Thread Christophe Leroy
SEC1 descriptor is a bit different to SEC2+ descriptor.
talitos_submit() will have to copy hdr field into hdr1 field and
send the descriptor starting at hdr1 up to next_desc.
For SEC2, it remains unchanged and next_desc is just ignored.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 23 +++
 drivers/crypto/talitos.h |  2 ++
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 678b528..e6ea651 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -236,6 +236,7 @@ int talitos_submit(struct device *dev, int ch, struct 
talitos_desc *desc,
struct talitos_request *request;
unsigned long flags;
int head;
+   bool is_sec1 = has_ftr_sec1(priv);
 
spin_lock_irqsave(priv-chan[ch].head_lock, flags);
 
@@ -249,8 +250,17 @@ int talitos_submit(struct device *dev, int ch, struct 
talitos_desc *desc,
request = priv-chan[ch].fifo[head];
 
/* map descriptor and save caller data */
-   request-dma_desc = dma_map_single(dev, desc, sizeof(*desc),
-  DMA_BIDIRECTIONAL);
+   if (is_sec1) {
+   desc-hdr1 = desc-hdr;
+   desc-next_desc = 0;
+   request-dma_desc = dma_map_single(dev, desc-hdr1,
+  TALITOS_DESC_SIZE,
+  DMA_BIDIRECTIONAL);
+   } else {
+   request-dma_desc = dma_map_single(dev, desc,
+  TALITOS_DESC_SIZE,
+  DMA_BIDIRECTIONAL);
+   }
request-callback = callback;
request-context = context;
 
@@ -282,16 +292,21 @@ static void flush_channel(struct device *dev, int ch, int 
error, int reset_ch)
struct talitos_request *request, saved_req;
unsigned long flags;
int tail, status;
+   bool is_sec1 = has_ftr_sec1(priv);
 
spin_lock_irqsave(priv-chan[ch].tail_lock, flags);
 
tail = priv-chan[ch].tail;
while (priv-chan[ch].fifo[tail].desc) {
+   __be32 hdr;
+
request = priv-chan[ch].fifo[tail];
 
/* descriptors with their done bits set don't get the error */
rmb();
-   if ((request-desc-hdr  DESC_HDR_DONE) == DESC_HDR_DONE)
+   hdr = is_sec1 ? request-desc-hdr1 : request-desc-hdr;
+
+   if ((hdr  DESC_HDR_DONE) == DESC_HDR_DONE)
status = 0;
else
if (!error)
@@ -300,7 +315,7 @@ static void flush_channel(struct device *dev, int ch, int 
error, int reset_ch)
status = error;
 
dma_unmap_single(dev, request-dma_desc,
-sizeof(struct talitos_desc),
+TALITOS_DESC_SIZE,
 DMA_BIDIRECTIONAL);
 
/* copy entries so we can call callback outside lock */
diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h
index b0bdb4e..f827c04 100644
--- a/drivers/crypto/talitos.h
+++ b/drivers/crypto/talitos.h
@@ -69,6 +69,8 @@ struct talitos_desc {
__be32 next_desc;   /* next descriptor (SEC1) */
 };
 
+#define TALITOS_DESC_SIZE  (sizeof(struct talitos_desc) - sizeof(__be32))
+
 /**
  * talitos_request - descriptor submission request
  * @desc: descriptor pointer (kernel virtual)
-- 
2.1.0

--
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 v3 10/17] crypto: talitos - fill in talitos descriptor iaw SEC1 or SEC2+

2015-04-17 Thread Christophe Leroy
talitos descriptor is slightly different for SEC1 and SEC2+, so
lets the helper function that fills the descriptor take into account
the type of SEC.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 105 ++-
 1 file changed, 67 insertions(+), 38 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index db95023..678b528 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -55,25 +55,38 @@
 
 #include talitos.h
 
-static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr)
+static void to_talitos_ptr(struct talitos_ptr *ptr, dma_addr_t dma_addr,
+  bool is_sec1)
 {
ptr-ptr = cpu_to_be32(lower_32_bits(dma_addr));
-   ptr-eptr = upper_32_bits(dma_addr);
+   if (!is_sec1)
+   ptr-eptr = upper_32_bits(dma_addr);
 }
 
-static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned short len)
+static void to_talitos_ptr_len(struct talitos_ptr *ptr, unsigned short len,
+  bool is_sec1)
 {
-   ptr-len = cpu_to_be16(len);
+   if (is_sec1) {
+   ptr-res = 0;
+   ptr-len1 = cpu_to_be16(len);
+   } else {
+   ptr-len = cpu_to_be16(len);
+   }
 }
 
-static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr)
+static unsigned short from_talitos_ptr_len(struct talitos_ptr *ptr,
+  bool is_sec1)
 {
-   return be16_to_cpu(ptr-len);
+   if (is_sec1)
+   return be16_to_cpu(ptr-len1);
+   else
+   return be16_to_cpu(ptr-len);
 }
 
-static void to_talitos_ptr_extent_clear(struct talitos_ptr *ptr)
+static void to_talitos_ptr_extent_clear(struct talitos_ptr *ptr, bool is_sec1)
 {
-   ptr-j_extent = 0;
+   if (!is_sec1)
+   ptr-j_extent = 0;
 }
 
 /*
@@ -85,10 +98,12 @@ static void map_single_talitos_ptr(struct device *dev,
   enum dma_data_direction dir)
 {
dma_addr_t dma_addr = dma_map_single(dev, data, len, dir);
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
 
-   to_talitos_ptr_len(ptr, len);
-   to_talitos_ptr(ptr, dma_addr);
-   to_talitos_ptr_extent_clear(ptr);
+   to_talitos_ptr_len(ptr, len, is_sec1);
+   to_talitos_ptr(ptr, dma_addr, is_sec1);
+   to_talitos_ptr_extent_clear(ptr, is_sec1);
 }
 
 /*
@@ -98,8 +113,11 @@ static void unmap_single_talitos_ptr(struct device *dev,
 struct talitos_ptr *ptr,
 enum dma_data_direction dir)
 {
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
+
dma_unmap_single(dev, be32_to_cpu(ptr-ptr),
-from_talitos_ptr_len(ptr), dir);
+from_talitos_ptr_len(ptr, is_sec1), dir);
 }
 
 static int reset_channel(struct device *dev, int ch)
@@ -922,7 +940,7 @@ static int sg_to_link_tbl(struct scatterlist *sg, int 
sg_count,
int n_sg = sg_count;
 
while (n_sg--) {
-   to_talitos_ptr(link_tbl_ptr, sg_dma_address(sg));
+   to_talitos_ptr(link_tbl_ptr, sg_dma_address(sg), 0);
link_tbl_ptr-len = cpu_to_be16(sg_dma_len(sg));
link_tbl_ptr-j_extent = 0;
link_tbl_ptr++;
@@ -976,7 +994,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
struct talitos_ptr *tbl_ptr = edesc-link_tbl[tbl_off];
 
to_talitos_ptr(desc-ptr[1], edesc-dma_link_tbl + tbl_off *
-  sizeof(struct talitos_ptr));
+  sizeof(struct talitos_ptr), 0);
desc-ptr[1].j_extent = DESC_PTR_LNKTBL_JUMP;
 
/* assoc_nents - 1 entries for assoc, 1 for IV */
@@ -987,7 +1005,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
tbl_ptr += sg_count - 1;
tbl_ptr-j_extent = 0;
tbl_ptr++;
-   to_talitos_ptr(tbl_ptr, edesc-iv_dma);
+   to_talitos_ptr(tbl_ptr, edesc-iv_dma, 0);
tbl_ptr-len = cpu_to_be16(ivsize);
tbl_ptr-j_extent = DESC_PTR_LNKTBL_RETURN;
 
@@ -996,14 +1014,14 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct 
aead_request *areq,
} else {
if (areq-assoclen)
to_talitos_ptr(desc-ptr[1],
-  sg_dma_address(areq-assoc));
+  sg_dma_address(areq-assoc), 0);
else
-   to_talitos_ptr(desc-ptr[1], edesc-iv_dma);
+   to_talitos_ptr(desc-ptr[1], edesc-iv_dma, 0);
desc-ptr[1].j_extent = 0;
}
 
/* cipher iv

[PATCH v3 14/17] crypto: talitos - implement scatter/gather copy for SEC1

2015-04-17 Thread Christophe Leroy
SEC1 doesn't support scatter/gather, SEC1 doesn't handle link tables.
Therefore, for SEC1 we have to do it by SW. For that, we reserve
space at the end of the extended descriptor, in lieu of the space
reserved for the link tables on SEC2, and we perform sg_copy() when
preparing the descriptors

We also adapt the max buffer size which is only 32k on SEC1 while it
is 64k on SEC2+

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 138 ++-
 drivers/crypto/talitos.h |   3 +-
 2 files changed, 103 insertions(+), 38 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 1265405..dddf4b3 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -866,9 +866,10 @@ badkey:
  * @dst_chained: whether dst is chained or not
  * @iv_dma: dma address of iv for checking continuity and link table
  * @dma_len: length of dma mapped link_tbl space
- * @dma_link_tbl: bus physical address of link_tbl
+ * @dma_link_tbl: bus physical address of link_tbl/buf
  * @desc: h/w descriptor
- * @link_tbl: input and output h/w link tables (if {src,dst}_nents  1)
+ * @link_tbl: input and output h/w link tables (if {src,dst}_nents  1) (SEC2)
+ * @buf: input and output buffeur (if {src,dst}_nents  1) (SEC1)
  *
  * if decrypting (with authcheck), or either one of src_nents or dst_nents
  * is greater than 1, an integrity check value is concatenated to the end
@@ -885,7 +886,10 @@ struct talitos_edesc {
int dma_len;
dma_addr_t dma_link_tbl;
struct talitos_desc desc;
-   struct talitos_ptr link_tbl[0];
+   union {
+   struct talitos_ptr link_tbl[0];
+   u8 buf[0];
+   };
 };
 
 static int talitos_map_sg(struct device *dev, struct scatterlist *sg,
@@ -1282,8 +1286,11 @@ static struct talitos_edesc *talitos_edesc_alloc(struct 
device *dev,
dma_addr_t iv_dma = 0;
gfp_t flags = cryptoflags  CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
  GFP_ATOMIC;
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
+   int max_len = is_sec1 ? TALITOS1_MAX_DATA_LEN : TALITOS2_MAX_DATA_LEN;
 
-   if (cryptlen + authsize  TALITOS_MAX_DATA_LEN) {
+   if (cryptlen + authsize  max_len) {
dev_err(dev, length exceeds h/w max limit\n);
return ERR_PTR(-EINVAL);
}
@@ -1327,8 +1334,12 @@ static struct talitos_edesc *talitos_edesc_alloc(struct 
device *dev,
 */
alloc_len = sizeof(struct talitos_edesc);
if (assoc_nents || src_nents || dst_nents) {
-   dma_len = (src_nents + dst_nents + 2 + assoc_nents) *
- sizeof(struct talitos_ptr) + authsize;
+   if (is_sec1)
+   dma_len = src_nents ? cryptlen : 0 +
+ dst_nents ? cryptlen : 0;
+   else
+   dma_len = (src_nents + dst_nents + 2 + assoc_nents) *
+ sizeof(struct talitos_ptr) + authsize;
alloc_len += dma_len;
} else {
dma_len = 0;
@@ -1485,7 +1496,27 @@ static void unmap_sg_talitos_ptr(struct device *dev, 
struct scatterlist *src,
 struct scatterlist *dst, unsigned int len,
 struct talitos_edesc *edesc)
 {
-   talitos_sg_unmap(dev, edesc, src, dst);
+   struct talitos_private *priv = dev_get_drvdata(dev);
+   bool is_sec1 = has_ftr_sec1(priv);
+
+   if (is_sec1) {
+   if (!edesc-src_nents) {
+   dma_unmap_sg(dev, src, 1,
+dst != src ? DMA_TO_DEVICE
+   : DMA_BIDIRECTIONAL);
+   }
+   if (dst  edesc-dst_nents) {
+   dma_sync_single_for_device(dev,
+  edesc-dma_link_tbl + len,
+  len, DMA_FROM_DEVICE);
+   sg_copy_from_buffer(dst, edesc-dst_nents ? : 1,
+   edesc-buf + len, len);
+   } else if (dst  dst != src) {
+   dma_unmap_sg(dev, dst, 1, DMA_FROM_DEVICE);
+   }
+   } else {
+   talitos_sg_unmap(dev, edesc, src, dst);
+   }
 }
 
 static void common_nonsnoop_unmap(struct device *dev,
@@ -1528,25 +1559,42 @@ int map_sg_in_talitos_ptr(struct device *dev, struct 
scatterlist *src,
bool is_sec1 = has_ftr_sec1(priv);
 
to_talitos_ptr_len(ptr, len, is_sec1);
-   to_talitos_ptr_extent_clear(ptr, is_sec1);
 
-   sg_count = talitos_map_sg(dev, src, edesc-src_nents ? : 1, dir,
- edesc-src_chained);
+   if (is_sec1) {
+   sg_count = edesc-src_nents ? : 1;
 
-   if (sg_count == 1

[PATCH v3 09/17] crypto: talitos - Add a feature to tag SEC1

2015-04-17 Thread Christophe Leroy
We add a new feature in the features field, to mark compatible
fsl,sec1.0
We also define a helper function called has_ftr_sec1() to help
functions quickly determine if they are running on SEC1 or SEC2+.
When only SEC1 or SEC2 is compiled in, has_ftr_sec1() return
trivial corresponding value. If both are compiled in, feature
field is checked.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c |  3 +++
 drivers/crypto/talitos.h | 17 +
 2 files changed, 20 insertions(+)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index bca6ded..db95023 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -2709,6 +2709,9 @@ static int talitos_probe(struct platform_device *ofdev)
  TALITOS_FTR_SHA224_HWINIT |
  TALITOS_FTR_HMAC_OK;
 
+   if (of_device_is_compatible(np, fsl,sec1.0))
+   priv-features |= TALITOS_FTR_SEC1;
+
priv-chan = kzalloc(sizeof(struct talitos_channel) *
 priv-num_channels, GFP_KERNEL);
if (!priv-chan) {
diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h
index f078da1..b0bdb4e 100644
--- a/drivers/crypto/talitos.h
+++ b/drivers/crypto/talitos.h
@@ -156,6 +156,23 @@ extern int talitos_submit(struct device *dev, int ch, 
struct talitos_desc *desc,
 #define TALITOS_FTR_HW_AUTH_CHECK 0x0002
 #define TALITOS_FTR_SHA224_HWINIT 0x0004
 #define TALITOS_FTR_HMAC_OK 0x0008
+#define TALITOS_FTR_SEC1 0x0010
+
+/*
+ * If both CONFIG_CRYPTO_DEV_TALITOS1 and CONFIG_CRYPTO_DEV_TALITOS2 are
+ * defined, we check the features which are set according to the device tree.
+ * Otherwise, we answer true or false directly
+ */
+static inline bool has_ftr_sec1(struct talitos_private *priv)
+{
+#if defined(CONFIG_CRYPTO_DEV_TALITOS1)  defined(CONFIG_CRYPTO_DEV_TALITOS2)
+   return priv-features  TALITOS_FTR_SEC1 ? true : false;
+#elif defined(CONFIG_CRYPTO_DEV_TALITOS1)
+   return true;
+#else
+   return false;
+#endif
+}
 
 /*
  * TALITOS_xxx_LO addresses point to the low data bits (32-63) of the register
-- 
2.1.0

--
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 v3 13/17] crypto: talitos - adapt interrupts and reset functions to SEC1

2015-04-17 Thread Christophe Leroy
This patch adapts the interrupts handling and reset function for
SEC1. On SEC1, registers are almost similar to SEC2+, but bits
are sometimes located at different places. So we need to define
TALITOS1 and TALITOS2 versions of some fields, and manage according
to whether it is SEC1 or SEC2.

On SEC1, only one interrupt vector is dedicated to the SEC, so only
interrupt_4ch is needed.

On SEC1, interrupts are enabled by clearing related bits in IMR,
while on SEC2, interrupts are enabled by seting the bits in IMR.

SEC1 also performs parity verification in the DES Unit. We have
to disable this feature because the test vectors provided in
the kernel have parity errors.

In reset functions, only SEC2 supports continuation after error.
For SEC1, we have to reset in all cases.

For errors handling, SEC2+ names have been kept, but displayed
text have been amended to reflect exact meaning on SEC1.

Signed-off-by: Christophe Leroy christophe.le...@c-s.fr
---
 drivers/crypto/talitos.c | 227 +++
 drivers/crypto/talitos.h |  39 +---
 2 files changed, 199 insertions(+), 67 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 6d77699..1265405 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -124,12 +124,23 @@ static int reset_channel(struct device *dev, int ch)
 {
struct talitos_private *priv = dev_get_drvdata(dev);
unsigned int timeout = TALITOS_TIMEOUT;
+   bool is_sec1 = has_ftr_sec1(priv);
 
-   setbits32(priv-chan[ch].reg + TALITOS_CCCR, TALITOS_CCCR_RESET);
+   if (is_sec1) {
+   setbits32(priv-chan[ch].reg + TALITOS_CCCR_LO,
+ TALITOS1_CCCR_LO_RESET);
 
-   while ((in_be32(priv-chan[ch].reg + TALITOS_CCCR)  TALITOS_CCCR_RESET)
-   --timeout)
-   cpu_relax();
+   while ((in_be32(priv-chan[ch].reg + TALITOS_CCCR_LO) 
+   TALITOS1_CCCR_LO_RESET)  --timeout)
+   cpu_relax();
+   } else {
+   setbits32(priv-chan[ch].reg + TALITOS_CCCR,
+ TALITOS2_CCCR_RESET);
+
+   while ((in_be32(priv-chan[ch].reg + TALITOS_CCCR) 
+   TALITOS2_CCCR_RESET)  --timeout)
+   cpu_relax();
+   }
 
if (timeout == 0) {
dev_err(dev, failed to reset channel %d\n, ch);
@@ -152,11 +163,12 @@ static int reset_device(struct device *dev)
 {
struct talitos_private *priv = dev_get_drvdata(dev);
unsigned int timeout = TALITOS_TIMEOUT;
-   u32 mcr = TALITOS_MCR_SWR;
+   bool is_sec1 = has_ftr_sec1(priv);
+   u32 mcr = is_sec1 ? TALITOS1_MCR_SWR : TALITOS2_MCR_SWR;
 
setbits32(priv-reg + TALITOS_MCR, mcr);
 
-   while ((in_be32(priv-reg + TALITOS_MCR)  TALITOS_MCR_SWR)
+   while ((in_be32(priv-reg + TALITOS_MCR)  mcr)
--timeout)
cpu_relax();
 
@@ -180,6 +192,7 @@ static int init_device(struct device *dev)
 {
struct talitos_private *priv = dev_get_drvdata(dev);
int ch, err;
+   bool is_sec1 = has_ftr_sec1(priv);
 
/*
 * Master reset
@@ -203,8 +216,15 @@ static int init_device(struct device *dev)
}
 
/* enable channel done and error interrupts */
-   setbits32(priv-reg + TALITOS_IMR, TALITOS_IMR_INIT);
-   setbits32(priv-reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT);
+   if (is_sec1) {
+   clrbits32(priv-reg + TALITOS_IMR, TALITOS1_IMR_INIT);
+   clrbits32(priv-reg + TALITOS_IMR_LO, TALITOS1_IMR_LO_INIT);
+   /* disable parity error check in DEU (erroneous? test vect.) */
+   setbits32(priv-reg_deu + TALITOS_EUICR, TALITOS1_DEUICR_KPE);
+   } else {
+   setbits32(priv-reg + TALITOS_IMR, TALITOS2_IMR_INIT);
+   setbits32(priv-reg + TALITOS_IMR_LO, TALITOS2_IMR_LO_INIT);
+   }
 
/* disable integrity check error interrupts (use writeback instead) */
if (priv-features  TALITOS_FTR_HW_AUTH_CHECK)
@@ -349,8 +369,37 @@ static void flush_channel(struct device *dev, int ch, int 
error, int reset_ch)
 /*
  * process completed requests for channels that have done status
  */
-#define DEF_TALITOS_DONE(name, ch_done_mask)   \
-static void talitos_done_##name(unsigned long data)\
+#define DEF_TALITOS1_DONE(name, ch_done_mask)  \
+static void talitos1_done_##name(unsigned long data)   \
+{  \
+   struct device *dev = (struct device *)data; \
+   struct talitos_private *priv = dev_get_drvdata(dev);\
+   unsigned long flags;\
+   \
+   if (ch_done_mask  0x1000

  1   2   >