Re: [PATCH v6 0/6] crypto: Add Qcom PRNG support

2018-07-23 Thread Vinod
On 16-07-18, 11:20, Vinod Koul wrote:
> This series removes the hwrng qcom driver and replaces it with crypto qcom
> driver and then adds support for Execution Environment (EE) found in v2
> version of the hardware and ACPI support for these

Stephan, Herbert

Any chance this could make it for 4.19. It has been here for a while and
I haven't heard any objections.

> 
> Changes in v6:
>  - Fix a typo in kconfig. Remove of_device.h and add of.h header
>  - Add review and tested tags
> 
> Changes in v5:
>  - Update ACPI check and use generic driver data API
> 
> Changes in v4:
>  - Use memcpy for data copy
>  - Fix trailing bytes copy
>  - Fix ACPI ID table name
> 
> Timur Tabi (1):
>   crypto: qcom: Add ACPI support
> 
> Vinod Koul (5):
>   hwrng: remove msm hw_random driver
>   dt-bindings: crypto: Move prng binding to crypto
>   crypto: Add Qcom prng driver
>   dt-bindings: crypto: Add new compatible qcom,prng-ee
>   crypto: qcom: Add support for prng-ee
> 
>  .../bindings/{rng => crypto}/qcom,prng.txt |   4 +-
>  drivers/char/hw_random/Kconfig |  13 --
>  drivers/char/hw_random/Makefile|   1 -
>  drivers/char/hw_random/msm-rng.c   | 183 
>  drivers/crypto/Kconfig |  11 +
>  drivers/crypto/Makefile|   1 +
>  drivers/crypto/qcom-rng.c  | 229 
> +
>  7 files changed, 244 insertions(+), 198 deletions(-)
>  rename Documentation/devicetree/bindings/{rng => crypto}/qcom,prng.txt (73%)
>  delete mode 100644 drivers/char/hw_random/msm-rng.c
>  create mode 100644 drivers/crypto/qcom-rng.c
> 
> -- 
> 2.14.4

-- 
~Vinod


[PATCH 3/3] crypto: ablkcipher - fix crash flushing dcache in error path

2018-07-23 Thread Eric Biggers
From: Eric Biggers 

Like the skcipher_walk and blkcipher_walk cases:

scatterwalk_done() is only meant to be called after a nonzero number of
bytes have been processed, since scatterwalk_pagedone() will flush the
dcache of the *previous* page.  But in the error case of
ablkcipher_walk_done(), e.g. if the input wasn't an integer number of
blocks, scatterwalk_done() was actually called after advancing 0 bytes.
This caused a crash ("BUG: unable to handle kernel paging request")
during '!PageSlab(page)' on architectures like arm and arm64 that define
ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE, provided that the input was
page-aligned as in that case walk->offset == 0.

Fix it by reorganizing ablkcipher_walk_done() to skip the
scatterwalk_advance() and scatterwalk_done() if an error has occurred.

Reported-by: Liu Chao 
Fixes: bf06099db18a ("crypto: skcipher - Add ablkcipher_walk interfaces")
Cc:  # v2.6.35+
Signed-off-by: Eric Biggers 
---
 crypto/ablkcipher.c | 57 +
 1 file changed, 26 insertions(+), 31 deletions(-)

diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
index 1edb5000d783..8882e90e868e 100644
--- a/crypto/ablkcipher.c
+++ b/crypto/ablkcipher.c
@@ -71,11 +71,9 @@ static inline u8 *ablkcipher_get_spot(u8 *start, unsigned 
int len)
return max(start, end_page);
 }
 
-static inline unsigned int ablkcipher_done_slow(struct ablkcipher_walk *walk,
-   unsigned int bsize)
+static inline void ablkcipher_done_slow(struct ablkcipher_walk *walk,
+   unsigned int n)
 {
-   unsigned int n = bsize;
-
for (;;) {
unsigned int len_this_page = scatterwalk_pagelen(>out);
 
@@ -87,17 +85,13 @@ static inline unsigned int ablkcipher_done_slow(struct 
ablkcipher_walk *walk,
n -= len_this_page;
scatterwalk_start(>out, sg_next(walk->out.sg));
}
-
-   return bsize;
 }
 
-static inline unsigned int ablkcipher_done_fast(struct ablkcipher_walk *walk,
-   unsigned int n)
+static inline void ablkcipher_done_fast(struct ablkcipher_walk *walk,
+   unsigned int n)
 {
scatterwalk_advance(>in, n);
scatterwalk_advance(>out, n);
-
-   return n;
 }
 
 static int ablkcipher_walk_next(struct ablkcipher_request *req,
@@ -107,39 +101,40 @@ int ablkcipher_walk_done(struct ablkcipher_request *req,
 struct ablkcipher_walk *walk, int err)
 {
struct crypto_tfm *tfm = req->base.tfm;
-   unsigned int nbytes = 0;
+   unsigned int n; /* bytes processed */
+   bool more;
 
-   if (likely(err >= 0)) {
-   unsigned int n = walk->nbytes - err;
+   if (unlikely(err < 0))
+   goto finish;
 
-   if (likely(!(walk->flags & ABLKCIPHER_WALK_SLOW)))
-   n = ablkcipher_done_fast(walk, n);
-   else if (WARN_ON(err)) {
-   err = -EINVAL;
-   goto err;
-   } else
-   n = ablkcipher_done_slow(walk, n);
+   n = walk->nbytes - err;
+   walk->total -= n;
+   more = (walk->total != 0);
 
-   nbytes = walk->total - n;
-   err = 0;
+   if (likely(!(walk->flags & ABLKCIPHER_WALK_SLOW))) {
+   ablkcipher_done_fast(walk, n);
+   } else {
+   if (WARN_ON(err)) {
+   /* unexpected case; didn't process all bytes */
+   err = -EINVAL;
+   goto finish;
+   }
+   ablkcipher_done_slow(walk, n);
}
 
-   scatterwalk_done(>in, 0, nbytes);
-   scatterwalk_done(>out, 1, nbytes);
-
-err:
-   walk->total = nbytes;
-   walk->nbytes = nbytes;
+   scatterwalk_done(>in, 0, more);
+   scatterwalk_done(>out, 1, more);
 
-   if (nbytes) {
+   if (more) {
crypto_yield(req->base.flags);
return ablkcipher_walk_next(req, walk);
}
-
+   err = 0;
+finish:
+   walk->nbytes = 0;
if (walk->iv != req->info)
memcpy(req->info, walk->iv, tfm->crt_ablkcipher.ivsize);
kfree(walk->iv_buffer);
-
return err;
 }
 EXPORT_SYMBOL_GPL(ablkcipher_walk_done);
-- 
2.18.0.233.g985f88cf7e-goog



[PATCH 2/3] crypto: blkcipher - fix crash flushing dcache in error path

2018-07-23 Thread Eric Biggers
From: Eric Biggers 

Like the skcipher_walk case:

scatterwalk_done() is only meant to be called after a nonzero number of
bytes have been processed, since scatterwalk_pagedone() will flush the
dcache of the *previous* page.  But in the error case of
blkcipher_walk_done(), e.g. if the input wasn't an integer number of
blocks, scatterwalk_done() was actually called after advancing 0 bytes.
This caused a crash ("BUG: unable to handle kernel paging request")
during '!PageSlab(page)' on architectures like arm and arm64 that define
ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE, provided that the input was
page-aligned as in that case walk->offset == 0.

Fix it by reorganizing blkcipher_walk_done() to skip the
scatterwalk_advance() and scatterwalk_done() if an error has occurred.

This bug was found by syzkaller fuzzing.

Reproducer, assuming ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE:

#include 
#include 
#include 

int main()
{
struct sockaddr_alg addr = {
.salg_type = "skcipher",
.salg_name = "ecb(aes-generic)",
};
char buffer[4096] __attribute__((aligned(4096))) = { 0 };
int fd;

fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
bind(fd, (void *), sizeof(addr));
setsockopt(fd, SOL_ALG, ALG_SET_KEY, buffer, 16);
fd = accept(fd, NULL, NULL);
write(fd, buffer, 15);
read(fd, buffer, 15);
}

Reported-by: Liu Chao 
Fixes: 5cde0af2a982 ("[CRYPTO] cipher: Added block cipher type")
Cc:  # v2.6.19+
Signed-off-by: Eric Biggers 
---
 crypto/blkcipher.c | 54 ++
 1 file changed, 26 insertions(+), 28 deletions(-)

diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index dd4dcab3766a..f93abf13b5d4 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -70,19 +70,18 @@ static inline u8 *blkcipher_get_spot(u8 *start, unsigned 
int len)
return max(start, end_page);
 }
 
-static inline unsigned int blkcipher_done_slow(struct blkcipher_walk *walk,
-  unsigned int bsize)
+static inline void blkcipher_done_slow(struct blkcipher_walk *walk,
+  unsigned int bsize)
 {
u8 *addr;
 
addr = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1);
addr = blkcipher_get_spot(addr, bsize);
scatterwalk_copychunks(addr, >out, bsize, 1);
-   return bsize;
 }
 
-static inline unsigned int blkcipher_done_fast(struct blkcipher_walk *walk,
-  unsigned int n)
+static inline void blkcipher_done_fast(struct blkcipher_walk *walk,
+  unsigned int n)
 {
if (walk->flags & BLKCIPHER_WALK_COPY) {
blkcipher_map_dst(walk);
@@ -96,49 +95,48 @@ static inline unsigned int blkcipher_done_fast(struct 
blkcipher_walk *walk,
 
scatterwalk_advance(>in, n);
scatterwalk_advance(>out, n);
-
-   return n;
 }
 
 int blkcipher_walk_done(struct blkcipher_desc *desc,
struct blkcipher_walk *walk, int err)
 {
-   unsigned int nbytes = 0;
+   unsigned int n; /* bytes processed */
+   bool more;
 
-   if (likely(err >= 0)) {
-   unsigned int n = walk->nbytes - err;
+   if (unlikely(err < 0))
+   goto finish;
 
-   if (likely(!(walk->flags & BLKCIPHER_WALK_SLOW)))
-   n = blkcipher_done_fast(walk, n);
-   else if (WARN_ON(err)) {
-   err = -EINVAL;
-   goto err;
-   } else
-   n = blkcipher_done_slow(walk, n);
+   n = walk->nbytes - err;
+   walk->total -= n;
+   more = (walk->total != 0);
 
-   nbytes = walk->total - n;
-   err = 0;
+   if (likely(!(walk->flags & BLKCIPHER_WALK_SLOW))) {
+   blkcipher_done_fast(walk, n);
+   } else {
+   if (WARN_ON(err)) {
+   /* unexpected case; didn't process all bytes */
+   err = -EINVAL;
+   goto finish;
+   }
+   blkcipher_done_slow(walk, n);
}
 
-   scatterwalk_done(>in, 0, nbytes);
-   scatterwalk_done(>out, 1, nbytes);
+   scatterwalk_done(>in, 0, more);
+   scatterwalk_done(>out, 1, more);
 
-err:
-   walk->total = nbytes;
-   walk->nbytes = nbytes;
-
-   if (nbytes) {
+   if (more) {
crypto_yield(desc->flags);
return blkcipher_walk_next(desc, walk);
}
-
+   err = 0;
+finish:
+   walk->nbytes = 0;
if (walk->iv != desc->info)
memcpy(desc->info, walk->iv, walk->ivsize);
if (walk->buffer != walk->page)
kfree(walk->buffer);
if (walk->page)

[PATCH 1/3] crypto: skcipher - fix crash flushing dcache in error path

2018-07-23 Thread Eric Biggers
From: Eric Biggers 

scatterwalk_done() is only meant to be called after a nonzero number of
bytes have been processed, since scatterwalk_pagedone() will flush the
dcache of the *previous* page.  But in the error case of
skcipher_walk_done(), e.g. if the input wasn't an integer number of
blocks, scatterwalk_done() was actually called after advancing 0 bytes.
This caused a crash ("BUG: unable to handle kernel paging request")
during '!PageSlab(page)' on architectures like arm and arm64 that define
ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE, provided that the input was
page-aligned as in that case walk->offset == 0.

Fix it by reorganizing skcipher_walk_done() to skip the
scatterwalk_advance() and scatterwalk_done() if an error has occurred.

This bug was found by syzkaller fuzzing.

Reproducer, assuming ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE:

#include 
#include 
#include 

int main()
{
struct sockaddr_alg addr = {
.salg_type = "skcipher",
.salg_name = "cbc(aes-generic)",
};
char buffer[4096] __attribute__((aligned(4096))) = { 0 };
int fd;

fd = socket(AF_ALG, SOCK_SEQPACKET, 0);
bind(fd, (void *), sizeof(addr));
setsockopt(fd, SOL_ALG, ALG_SET_KEY, buffer, 16);
fd = accept(fd, NULL, NULL);
write(fd, buffer, 15);
read(fd, buffer, 15);
}

Reported-by: Liu Chao 
Fixes: b286d8b1a690 ("crypto: skcipher - Add skcipher walk interface")
Cc:  # v4.10+
Signed-off-by: Eric Biggers 
---
 crypto/skcipher.c | 53 ---
 1 file changed, 27 insertions(+), 26 deletions(-)

diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index 7d6a49fe3047..5f7017b36d75 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -95,7 +95,7 @@ static inline u8 *skcipher_get_spot(u8 *start, unsigned int 
len)
return max(start, end_page);
 }
 
-static int skcipher_done_slow(struct skcipher_walk *walk, unsigned int bsize)
+static void skcipher_done_slow(struct skcipher_walk *walk, unsigned int bsize)
 {
u8 *addr;
 
@@ -103,23 +103,24 @@ static int skcipher_done_slow(struct skcipher_walk *walk, 
unsigned int bsize)
addr = skcipher_get_spot(addr, bsize);
scatterwalk_copychunks(addr, >out, bsize,
   (walk->flags & SKCIPHER_WALK_PHYS) ? 2 : 1);
-   return 0;
 }
 
 int skcipher_walk_done(struct skcipher_walk *walk, int err)
 {
-   unsigned int n = walk->nbytes - err;
-   unsigned int nbytes;
-
-   nbytes = walk->total - n;
-
-   if (unlikely(err < 0)) {
-   nbytes = 0;
-   n = 0;
-   } else if (likely(!(walk->flags & (SKCIPHER_WALK_PHYS |
-  SKCIPHER_WALK_SLOW |
-  SKCIPHER_WALK_COPY |
-  SKCIPHER_WALK_DIFF {
+   unsigned int n; /* bytes processed */
+   bool more;
+
+   if (unlikely(err < 0))
+   goto finish;
+
+   n = walk->nbytes - err;
+   walk->total -= n;
+   more = (walk->total != 0);
+
+   if (likely(!(walk->flags & (SKCIPHER_WALK_PHYS |
+   SKCIPHER_WALK_SLOW |
+   SKCIPHER_WALK_COPY |
+   SKCIPHER_WALK_DIFF {
 unmap_src:
skcipher_unmap_src(walk);
} else if (walk->flags & SKCIPHER_WALK_DIFF) {
@@ -131,28 +132,28 @@ int skcipher_walk_done(struct skcipher_walk *walk, int 
err)
skcipher_unmap_dst(walk);
} else if (unlikely(walk->flags & SKCIPHER_WALK_SLOW)) {
if (WARN_ON(err)) {
+   /* unexpected case; didn't process all bytes */
err = -EINVAL;
-   nbytes = 0;
-   } else
-   n = skcipher_done_slow(walk, n);
+   goto finish;
+   }
+   skcipher_done_slow(walk, n);
+   goto already_advanced;
}
 
-   if (err > 0)
-   err = 0;
-
-   walk->total = nbytes;
-   walk->nbytes = nbytes;
-
scatterwalk_advance(>in, n);
scatterwalk_advance(>out, n);
-   scatterwalk_done(>in, 0, nbytes);
-   scatterwalk_done(>out, 1, nbytes);
+already_advanced:
+   scatterwalk_done(>in, 0, more);
+   scatterwalk_done(>out, 1, more);
 
-   if (nbytes) {
+   if (more) {
crypto_yield(walk->flags & SKCIPHER_WALK_SLEEP ?
 CRYPTO_TFM_REQ_MAY_SLEEP : 0);
return skcipher_walk_next(walk);
}
+   err = 0;
+finish:
+   walk->nbytes = 0;
 
/* Short-circuit for the common/fast path. */
if (!((unsigned long)walk->buffer | (unsigned long)walk->page))
-- 

[PATCH 0/3] crypto: fix crash in scatterwalk_pagedone()

2018-07-23 Thread Eric Biggers
From: Eric Biggers 

This series fixes the bug reported by Liu Chao (found using syzkaller)
where a crash occurs in scatterwalk_pagedone() on architectures such as
arm and arm64 that implement flush_dcache_page(), due to an invalid page
pointer when walk->offset == 0.  This series attempts to address the
underlying problem which is that scatterwalk_pagedone() shouldn't have
been called at all in that case.

Eric Biggers (3):
  crypto: skcipher - fix crash flushing dcache in error path
  crypto: blkcipher - fix crash flushing dcache in error path
  crypto: ablkcipher - fix crash flushing dcache in error path

 crypto/ablkcipher.c | 57 +
 crypto/blkcipher.c  | 54 +-
 crypto/skcipher.c   | 53 -
 3 files changed, 79 insertions(+), 85 deletions(-)

-- 
2.18.0.233.g985f88cf7e-goog



[PATCH] crypto: skcipher - remove unnecessary setting of walk->nbytes

2018-07-23 Thread Eric Biggers
From: Eric Biggers 

Setting 'walk->nbytes = walk->total' in skcipher_walk_first() doesn't
make sense because actually walk->nbytes needs to be set to the length
of the first step in the walk, which may be less than walk->total.  This
is done by skcipher_walk_next() which is called immediately afterwards.
Also walk->nbytes was already set to 0 in skcipher_walk_skcipher(),
which is a better default value in case it's forgotten to be set later.

Therefore, remove the unnecessary assignment to walk->nbytes.

Signed-off-by: Eric Biggers 
---
 crypto/skcipher.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index 7d6a49fe3047..9f7d229827b5 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -436,7 +436,6 @@ static int skcipher_walk_first(struct skcipher_walk *walk)
}
 
walk->page = NULL;
-   walk->nbytes = walk->total;
 
return skcipher_walk_next(walk);
 }
-- 
2.18.0.233.g985f88cf7e-goog



[PATCH] crypto: scatterwalk - remove scatterwalk_samebuf()

2018-07-23 Thread Eric Biggers
From: Eric Biggers 

scatterwalk_samebuf() is never used.  Remove it.

Signed-off-by: Eric Biggers 
---
 include/crypto/scatterwalk.h | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/include/crypto/scatterwalk.h b/include/crypto/scatterwalk.h
index eac72840a7d2..a66c127a20ed 100644
--- a/include/crypto/scatterwalk.h
+++ b/include/crypto/scatterwalk.h
@@ -30,13 +30,6 @@ static inline void scatterwalk_crypto_chain(struct 
scatterlist *head,
sg_mark_end(head);
 }
 
-static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
-   struct scatter_walk *walk_out)
-{
-   return !(((sg_page(walk_in->sg) - sg_page(walk_out->sg)) << PAGE_SHIFT) 
+
-(int)(walk_in->offset - walk_out->offset));
-}
-
 static inline unsigned int scatterwalk_pagelen(struct scatter_walk *walk)
 {
unsigned int len = walk->sg->offset + walk->sg->length - walk->offset;
-- 
2.18.0.233.g985f88cf7e-goog



[PATCH] crypto: scatterwalk - remove 'chain' argument from scatterwalk_crypto_chain()

2018-07-23 Thread Eric Biggers
From: Eric Biggers 

All callers pass chain=0 to scatterwalk_crypto_chain().

Remove this unneeded parameter.

Signed-off-by: Eric Biggers 
---
 crypto/lrw.c  | 4 ++--
 crypto/scatterwalk.c  | 2 +-
 crypto/xts.c  | 4 ++--
 include/crypto/scatterwalk.h  | 8 +---
 net/tls/tls_device_fallback.c | 2 +-
 5 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/crypto/lrw.c b/crypto/lrw.c
index 954a7064a179..393a782679c7 100644
--- a/crypto/lrw.c
+++ b/crypto/lrw.c
@@ -188,7 +188,7 @@ static int post_crypt(struct skcipher_request *req)
if (rctx->dst != sg) {
rctx->dst[0] = *sg;
sg_unmark_end(rctx->dst);
-   scatterwalk_crypto_chain(rctx->dst, sg_next(sg), 0, 2);
+   scatterwalk_crypto_chain(rctx->dst, sg_next(sg), 2);
}
rctx->dst[0].length -= offset - sg->offset;
rctx->dst[0].offset = offset;
@@ -265,7 +265,7 @@ static int pre_crypt(struct skcipher_request *req)
if (rctx->src != sg) {
rctx->src[0] = *sg;
sg_unmark_end(rctx->src);
-   scatterwalk_crypto_chain(rctx->src, sg_next(sg), 0, 2);
+   scatterwalk_crypto_chain(rctx->src, sg_next(sg), 2);
}
rctx->src[0].length -= offset - sg->offset;
rctx->src[0].offset = offset;
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index c16c94f88733..d0b92c1cd6e9 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -91,7 +91,7 @@ struct scatterlist *scatterwalk_ffwd(struct scatterlist 
dst[2],
 
sg_init_table(dst, 2);
sg_set_page(dst, sg_page(src), src->length - len, src->offset + len);
-   scatterwalk_crypto_chain(dst, sg_next(src), 0, 2);
+   scatterwalk_crypto_chain(dst, sg_next(src), 2);
 
return dst;
 }
diff --git a/crypto/xts.c b/crypto/xts.c
index 12284183bd20..ccf55fbb8bc2 100644
--- a/crypto/xts.c
+++ b/crypto/xts.c
@@ -138,7 +138,7 @@ static int post_crypt(struct skcipher_request *req)
if (rctx->dst != sg) {
rctx->dst[0] = *sg;
sg_unmark_end(rctx->dst);
-   scatterwalk_crypto_chain(rctx->dst, sg_next(sg), 0, 2);
+   scatterwalk_crypto_chain(rctx->dst, sg_next(sg), 2);
}
rctx->dst[0].length -= offset - sg->offset;
rctx->dst[0].offset = offset;
@@ -204,7 +204,7 @@ static int pre_crypt(struct skcipher_request *req)
if (rctx->src != sg) {
rctx->src[0] = *sg;
sg_unmark_end(rctx->src);
-   scatterwalk_crypto_chain(rctx->src, sg_next(sg), 0, 2);
+   scatterwalk_crypto_chain(rctx->src, sg_next(sg), 2);
}
rctx->src[0].length -= offset - sg->offset;
rctx->src[0].offset = offset;
diff --git a/include/crypto/scatterwalk.h b/include/crypto/scatterwalk.h
index 880e6be9e95e..eac72840a7d2 100644
--- a/include/crypto/scatterwalk.h
+++ b/include/crypto/scatterwalk.h
@@ -22,14 +22,8 @@
 #include 
 
 static inline void scatterwalk_crypto_chain(struct scatterlist *head,
-   struct scatterlist *sg,
-   int chain, int num)
+   struct scatterlist *sg, int num)
 {
-   if (chain) {
-   head->length += sg->length;
-   sg = sg_next(sg);
-   }
-
if (sg)
sg_chain(head, num, sg);
else
diff --git a/net/tls/tls_device_fallback.c b/net/tls/tls_device_fallback.c
index 748914abdb60..4e1ec12bc0fb 100644
--- a/net/tls/tls_device_fallback.c
+++ b/net/tls/tls_device_fallback.c
@@ -42,7 +42,7 @@ static void chain_to_walk(struct scatterlist *sg, struct 
scatter_walk *walk)
sg_set_page(sg, sg_page(src),
src->length - diff, walk->offset);
 
-   scatterwalk_crypto_chain(sg, sg_next(src), 0, 2);
+   scatterwalk_crypto_chain(sg, sg_next(src), 2);
 }
 
 static int tls_enc_record(struct aead_request *aead_req,
-- 
2.18.0.233.g985f88cf7e-goog



[PATCH] crypto: skcipher - fix aligning block size in skcipher_copy_iv()

2018-07-23 Thread Eric Biggers
From: Eric Biggers 

The ALIGN() macro needs to be passed the alignment, not the alignmask
(which is the alignment minus 1).

Fixes: b286d8b1a690 ("crypto: skcipher - Add skcipher walk interface")
Cc:  # v4.10+
Signed-off-by: Eric Biggers 
---
 crypto/skcipher.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crypto/skcipher.c b/crypto/skcipher.c
index 7d6a49fe3047..4f6b8dadaceb 100644
--- a/crypto/skcipher.c
+++ b/crypto/skcipher.c
@@ -398,7 +398,7 @@ static int skcipher_copy_iv(struct skcipher_walk *walk)
unsigned size;
u8 *iv;
 
-   aligned_bs = ALIGN(bs, alignmask);
+   aligned_bs = ALIGN(bs, alignmask + 1);
 
/* Minimum size to align buffer by alignmask. */
size = alignmask & ~a;
-- 
2.18.0.233.g985f88cf7e-goog



[PATCH 2/3] crypto: hisilicon SEC security accelerator driver

2018-07-23 Thread Jonathan Cameron
This accelerator is found inside hisilicon hip06 and hip07 SoCs.
Each instance provides a number of queues which feed a different number of
backend acceleration units.

The queues are operating in an out of order mode in the interests of
throughput. The silicon does not do tracking of dependencies between
multiple 'messages' or update of the IVs as appropriate for training.
Hence where relevant we need to do this in software.

Signed-off-by: Jonathan Cameron 
---
 drivers/crypto/Kconfig  |2 +
 drivers/crypto/Makefile |1 +
 drivers/crypto/hisilicon/Kconfig|   14 +
 drivers/crypto/hisilicon/Makefile   |2 +
 drivers/crypto/hisilicon/sec/Makefile   |3 +
 drivers/crypto/hisilicon/sec/sec_algs.c | 1122 ++
 drivers/crypto/hisilicon/sec/sec_drv.c  | 1323 +++
 drivers/crypto/hisilicon/sec/sec_drv.h  |  428 ++
 8 files changed, 2895 insertions(+)

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index d1ea1a07cecb..d0b80d0d1f8b 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -750,4 +750,6 @@ config CRYPTO_DEV_CCREE
  cryptographic operations on the system REE.
  If unsure say Y.
 
+source "drivers/crypto/hisilicon/Kconfig"
+
 endif # CRYPTO_HW
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 7ae87b4f6c8d..ee43aed8cb69 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -45,3 +45,4 @@ obj-$(CONFIG_CRYPTO_DEV_VMX) += vmx/
 obj-$(CONFIG_CRYPTO_DEV_BCM_SPU) += bcm/
 obj-$(CONFIG_CRYPTO_DEV_SAFEXCEL) += inside-secure/
 obj-$(CONFIG_CRYPTO_DEV_ARTPEC6) += axis/
+obj-y += hisilicon/
diff --git a/drivers/crypto/hisilicon/Kconfig b/drivers/crypto/hisilicon/Kconfig
new file mode 100644
index ..8ca9c503bcb0
--- /dev/null
+++ b/drivers/crypto/hisilicon/Kconfig
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config CRYPTO_DEV_HISI_SEC
+   tristate "Support for Hisilicon SEC crypto block cipher accelerator"
+   select CRYPTO_BLKCIPHER
+   select CRYPTO_ALGAPI
+   select SG_SPLIT
+   depends on ARM64 || COMPILE_TEST
+   depends on HAS_IOMEM
+   help
+ Support for Hisilicon SEC Engine in Hip06 and Hip07
+
+ To compile this as a module, choose M here: the module
+ will be called hisi_sec.
diff --git a/drivers/crypto/hisilicon/Makefile 
b/drivers/crypto/hisilicon/Makefile
new file mode 100644
index ..463f46ace182
--- /dev/null
+++ b/drivers/crypto/hisilicon/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_CRYPTO_DEV_HISI_SEC) += sec/
diff --git a/drivers/crypto/hisilicon/sec/Makefile 
b/drivers/crypto/hisilicon/sec/Makefile
new file mode 100644
index ..a55b698e0c27
--- /dev/null
+++ b/drivers/crypto/hisilicon/sec/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_CRYPTO_DEV_HISI_SEC) += hisi_sec.o
+hisi_sec-y = sec_algs.o sec_drv.o
diff --git a/drivers/crypto/hisilicon/sec/sec_algs.c 
b/drivers/crypto/hisilicon/sec/sec_algs.c
new file mode 100644
index ..d69d3ce358b0
--- /dev/null
+++ b/drivers/crypto/hisilicon/sec/sec_algs.c
@@ -0,0 +1,1122 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2016-2017 Hisilicon Limited. */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "sec_drv.h"
+
+#define SEC_MAX_CIPHER_KEY 64
+#define SEC_REQ_LIMIT SZ_32M
+
+struct sec_c_alg_cfg {
+   unsigned c_alg  : 3;
+   unsigned c_mode : 3;
+   unsigned key_len: 2;
+   unsigned c_width: 2;
+};
+
+static const struct sec_c_alg_cfg sec_c_alg_cfgs[] =  {
+   [SEC_C_DES_ECB_64] = {
+   .c_alg = SEC_C_ALG_DES,
+   .c_mode = SEC_C_MODE_ECB,
+   .key_len = SEC_KEY_LEN_DES,
+   },
+   [SEC_C_DES_CBC_64] = {
+   .c_alg = SEC_C_ALG_DES,
+   .c_mode = SEC_C_MODE_CBC,
+   .key_len = SEC_KEY_LEN_DES,
+   },
+   [SEC_C_3DES_ECB_192_3KEY] = {
+   .c_alg = SEC_C_ALG_3DES,
+   .c_mode = SEC_C_MODE_ECB,
+   .key_len = SEC_KEY_LEN_3DES_3_KEY,
+   },
+   [SEC_C_3DES_ECB_192_2KEY] = {
+   .c_alg = SEC_C_ALG_3DES,
+   .c_mode = SEC_C_MODE_ECB,
+   .key_len = SEC_KEY_LEN_3DES_2_KEY,
+   },
+   [SEC_C_3DES_CBC_192_3KEY] = {
+   .c_alg = SEC_C_ALG_3DES,
+   .c_mode = SEC_C_MODE_CBC,
+   .key_len = SEC_KEY_LEN_3DES_3_KEY,
+   },
+   [SEC_C_3DES_CBC_192_2KEY] = {
+   .c_alg = SEC_C_ALG_3DES,
+   .c_mode = SEC_C_MODE_CBC,
+   .key_len = SEC_KEY_LEN_3DES_2_KEY,
+   },
+   [SEC_C_AES_ECB_128] = {
+   .c_alg = SEC_C_ALG_AES,
+   .c_mode = SEC_C_MODE_ECB,
+   .key_len = 

[PATCH V2 0/3] Hisilicon SEC crypto driver (hip06 / hip07)

2018-07-23 Thread Jonathan Cameron
The driver provides in kernel support for the Hisilicon SEC accelerator
found in the hip06 and hip07 SoCs.  There are 4 such units on the D05
board for which an appropriate DT binding has been provided.  ACPI also
works with an appropriate UEFI build.

The hardware does not update the IV in chaining or counting modes.
This is done in the drive ron completion of the cipher operation.

The driver support AES, DES and 3DES block ciphers in a range of
modes (others to follow). Hash and AAED support to follow.

Sorry for the delay on this one, other priorities and all that...

Changes since V1.
1) DT binding fixes suggested by Rob Herring in patches 1 and 3.
2) Added XTS key check as suggested by Stephan Muller.
3) A trivial use after free found during testing of the above.

Changes since RFC.
1) Addition of backlog queuing as needed to support dm-crypt usecases.
2) iommu presence tests now done as Robin Murphy suggested.
3) Hardware limiation to 32MB requests worked aroud in driver so it will
   now support very large requests (512*32MB).  Larger request handling
   than this would require a longer queue with the associate overheads and
   is considered unlikely to be necessary.
4) The specific handling related to the inline IV patch set from Stephan
   has been dropped for now.
5) Interrupt handler was previous more complex than necessary so has been
   reworked.
6) Use of the bounce buffer for small packeets is dropped for now.  This is a
   performance optimization that made the code harder to review and can be
   reintroduced as necessary at a later date.
7) Restructuring of some code to simplify hash and aaed (hash implemented
   but not ready fo upstream at this time)
8) Various minor fixes and reworks of the code
   * several off by one errors in the cleanup paths
   * single template for enc and dec
   * drop dec_key as not used (enc_key was used in both cases)
   * drop dma pool for IVs as it breaks chaining.
   * lots of spinlocks changed to mutexes as not taken in atomic context.
   * nasty memory leak cleaned up.

Jonathan Cameron (3):
  dt-bindings: Add bindings for Hisilicon SEC crypto accelerators.
  crypto: hisilicon SEC security accelerator driver
  arm64: dts: hisi: add SEC crypto accelerator nodes for hip07 SoC

 .../bindings/crypto/hisilicon,hip07-sec.txt|   67 +
 arch/arm64/boot/dts/hisilicon/hip07.dtsi   |  284 +
 drivers/crypto/Kconfig |2 +
 drivers/crypto/Makefile|1 +
 drivers/crypto/hisilicon/Kconfig   |   14 +
 drivers/crypto/hisilicon/Makefile  |2 +
 drivers/crypto/hisilicon/sec/Makefile  |3 +
 drivers/crypto/hisilicon/sec/sec_algs.c| 1122 +
 drivers/crypto/hisilicon/sec/sec_drv.c | 1323 
 drivers/crypto/hisilicon/sec/sec_drv.h |  428 +++
 10 files changed, 3246 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/crypto/hisilicon,hip07-sec.txt
 create mode 100644 drivers/crypto/hisilicon/Kconfig
 create mode 100644 drivers/crypto/hisilicon/Makefile
 create mode 100644 drivers/crypto/hisilicon/sec/Makefile
 create mode 100644 drivers/crypto/hisilicon/sec/sec_algs.c
 create mode 100644 drivers/crypto/hisilicon/sec/sec_drv.c
 create mode 100644 drivers/crypto/hisilicon/sec/sec_drv.h

-- 
2.16.2




[PATCH 3/3] arm64: dts: hisi: add SEC crypto accelerator nodes for hip07 SoC

2018-07-23 Thread Jonathan Cameron
Enable all 4 SEC units available on d05 boards.

Signed-off-by: Jonathan Cameron 
---
 arch/arm64/boot/dts/hisilicon/hip07.dtsi | 284 +++
 1 file changed, 284 insertions(+)

diff --git a/arch/arm64/boot/dts/hisilicon/hip07.dtsi 
b/arch/arm64/boot/dts/hisilicon/hip07.dtsi
index 0600a6a84ab7..6d046f4f7019 100644
--- a/arch/arm64/boot/dts/hisilicon/hip07.dtsi
+++ b/arch/arm64/boot/dts/hisilicon/hip07.dtsi
@@ -1049,7 +1049,74 @@
num-pins = <2>;
};
};
+   p0_mbigen_alg_a:interrupt-controller@d008 {
+   compatible = "hisilicon,mbigen-v2";
+   reg = <0x0 0xd008 0x0 0x1>;
 
+   p0_mbigen_sec_a: intc_sec {
+   msi-parent = <_its_dsa_a 0x40400>;
+   interrupt-controller;
+   #interrupt-cells = <2>;
+   num-pins = <33>;
+   };
+   p0_mbigen_smmu_alg_a: intc_smmu_alg {
+   msi-parent = <_its_dsa_a 0x40b1b>;
+   interrupt-controller;
+   #interrupt-cells = <2>;
+   num-pins = <3>;
+   };
+   };
+   p0_mbigen_alg_b:interrupt-controller@8,d008 {
+   compatible = "hisilicon,mbigen-v2";
+   reg = <0x8 0xd008 0x0 0x1>;
+
+   p0_mbigen_sec_b: intc_sec {
+   msi-parent = <_its_dsa_b 0x42400>;
+   interrupt-controller;
+   #interrupt-cells = <2>;
+   num-pins = <33>;
+   };
+   p0_mbigen_smmu_alg_b: intc_smmu_alg {
+   msi-parent = <_its_dsa_b 0x42b1b>;
+   interrupt-controller;
+   #interrupt-cells = <2>;
+   num-pins = <3>;
+   };
+   };
+   p1_mbigen_alg_a:interrupt-controller@400,d008 {
+   compatible = "hisilicon,mbigen-v2";
+   reg = <0x400 0xd008 0x0 0x1>;
+
+   p1_mbigen_sec_a: intc_sec {
+   msi-parent = <_its_dsa_a 0x44400>;
+   interrupt-controller;
+   #interrupt-cells = <2>;
+   num-pins = <33>;
+   };
+   p1_mbigen_smmu_alg_a: intc_smmu_alg {
+   msi-parent = <_its_dsa_a 0x44b1b>;
+   interrupt-controller;
+   #interrupt-cells = <2>;
+   num-pins = <3>;
+   };
+   };
+   p1_mbigen_alg_b:interrupt-controller@408,d008 {
+   compatible = "hisilicon,mbigen-v2";
+   reg = <0x408 0xd008 0x0 0x1>;
+
+   p1_mbigen_sec_b: intc_sec {
+   msi-parent = <_its_dsa_b 0x46400>;
+   interrupt-controller;
+   #interrupt-cells = <2>;
+   num-pins = <33>;
+   };
+   p1_mbigen_smmu_alg_b: intc_smmu_alg {
+   msi-parent = <_its_dsa_b 0x46b1b>;
+   interrupt-controller;
+   #interrupt-cells = <2>;
+   num-pins = <3>;
+   };
+   };
p0_mbigen_dsa_a: interrupt-controller@c008 {
compatible = "hisilicon,mbigen-v2";
reg = <0x0 0xc008 0x0 0x1>;
@@ -1107,6 +1174,58 @@
hisilicon,broken-prefetch-cmd;
status = "disabled";
};
+   p0_smmu_alg_a: smmu_alg@d004 {
+   compatible = "arm,smmu-v3";
+   reg = <0x0 0xd004 0x0 0x2>;
+   interrupt-parent = <_mbigen_smmu_alg_a>;
+   interrupts = <733 1>,
+   <734 1>,
+   <735 1>;
+   interrupt-names = "eventq", "gerror", "priq";
+   #iommu-cells = <1>;
+   dma-coherent;
+   hisilicon,broken-prefetch-cmd;
+   /* smmu-cb-memtype = <0x0 0x1>;*/
+   };
+   p0_smmu_alg_b: smmu_alg@8,d004 {
+   compatible = "arm,smmu-v3";
+   reg = <0x8 0xd004 0x0 0x2>;
+   interrupt-parent = <_mbigen_smmu_alg_b>;
+   interrupts = <733 1>,
+   <734 1>,
+   <735 1>;
+   interrupt-names = "eventq", "gerror", "priq";
+   #iommu-cells = <1>;
+   dma-coherent;
+   hisilicon,broken-prefetch-cmd;
+   /* smmu-cb-memtype = <0x0 0x1>;*/
+   };
+   p1_smmu_alg_a: smmu_alg@400,d004 {
+   compatible = "arm,smmu-v3";
+   reg = <0x400 0xd004 0x0 0x2>;
+   interrupt-parent = <_mbigen_smmu_alg_a>;
+   interrupts = <733 1>,
+   <734 1>,
+   <735 1>;
+   interrupt-names = "eventq", "gerror", "priq";

[PATCH 1/3] dt-bindings: Add bindings for Hisilicon SEC crypto accelerators.

2018-07-23 Thread Jonathan Cameron
The hip06 and hip07 SoCs contain a number of these crypto units which
accelerate AES and DES operations.

Signed-off-by: Jonathan Cameron 
---
 .../bindings/crypto/hisilicon,hip07-sec.txt| 67 ++
 1 file changed, 67 insertions(+)

diff --git a/Documentation/devicetree/bindings/crypto/hisilicon,hip07-sec.txt 
b/Documentation/devicetree/bindings/crypto/hisilicon,hip07-sec.txt
new file mode 100644
index ..78d2db9d4de5
--- /dev/null
+++ b/Documentation/devicetree/bindings/crypto/hisilicon,hip07-sec.txt
@@ -0,0 +1,67 @@
+* Hisilicon hip07 Security Accelerator (SEC)
+
+Required properties:
+- compatible: Must contain one of
+  - "hisilicon,hip06-sec"
+  - "hisilicon,hip07-sec"
+- reg: Memory addresses and lengths of the memory regions through which
+  this device is controlled.
+  Region 0 has registers to control the backend processing engines.
+  Region 1 has registers for functionality common to all queues.
+  Regions 2-18 have registers for the 16 individual queues which are isolated
+  both in hardware and within the driver.
+- interrupts: Interrupt specifiers.
+  Refer to interrupt-controller/interrupts.txt for generic interrupt client 
node
+  bindings.
+  Interrupt 0 is for the SEC unit error queue.
+  Interrupt 2N + 1 is the completion interrupt for queue N.
+  Interrupt 2N + 2 is the error interrupt for queue N.
+- dma-coherent:  The driver assumes coherent dma is possible.
+
+Optional properties:
+- iommus: The SEC units are behind smmu-v3 iommus.
+  Refer to iommu/arm,smmu-v3.txt for more information.
+
+Example:
+
+p1_sec_a: crypto@400,d200 {
+   compatible = "hisilicon,hip07-sec";
+   reg = <0x400 0xd000 0x0 0x1
+  0x400 0xd200 0x0 0x1
+  0x400 0xd201 0x0 0x1
+  0x400 0xd202 0x0 0x1
+  0x400 0xd203 0x0 0x1
+  0x400 0xd204 0x0 0x1
+  0x400 0xd205 0x0 0x1
+  0x400 0xd206 0x0 0x1
+  0x400 0xd207 0x0 0x1
+  0x400 0xd208 0x0 0x1
+  0x400 0xd209 0x0 0x1
+  0x400 0xd20a 0x0 0x1
+  0x400 0xd20b 0x0 0x1
+  0x400 0xd20c 0x0 0x1
+  0x400 0xd20d 0x0 0x1
+  0x400 0xd20e 0x0 0x1
+  0x400 0xd20f 0x0 0x1
+  0x400 0xd210 0x0 0x1>;
+   interrupt-parent = <_mbigen_sec_a>;
+   iommus = <_smmu_alg_a 0x600>;
+   dma-coherent;
+   interrupts = <576 4>,
+<577 1>, <578 4>,
+<579 1>, <580 4>,
+<581 1>, <582 4>,
+<583 1>, <584 4>,
+<585 1>, <586 4>,
+<587 1>, <588 4>,
+<589 1>, <590 4>,
+<591 1>, <592 4>,
+<593 1>, <594 4>,
+<595 1>, <596 4>,
+<597 1>, <598 4>,
+<599 1>, <600 4>,
+<601 1>, <602 4>,
+<603 1>, <604 4>,
+<605 1>, <606 4>,
+<607 1>, <608 4>;
+};
-- 
2.16.2




Re: [PATCH 2/3] crypto: hisilicon SEC security accelerator driver

2018-07-23 Thread Jonathan Cameron
On Fri, 20 Jul 2018 20:17:22 +0200
Stephan Müller  wrote:

> Am Montag, 16. Juli 2018, 12:43:41 CEST schrieb Jonathan Cameron:
> 
> Hi Jonathan,
> 
> > +static int sec_alg_skcipher_setkey_aes_xts(struct crypto_skcipher *tfm,
> > +  const u8 *key, unsigned int
> > keylen) +{
> > +   enum sec_cipher_alg alg;
> > +
> > +   switch (keylen) {
> > +   case AES_KEYSIZE_128 * 2:
> > +   alg = SEC_C_AES_XTS_128;
> > +   break;
> > +   case AES_KEYSIZE_256 * 2:
> > +   alg = SEC_C_AES_XTS_256;
> > +   break;
> > +   default:
> > +   return -EINVAL;
> > +   }
> > +
> > +   return sec_alg_skcipher_setkey(tfm, key, keylen, alg);
> > +}  
> 
> Can you please call the function xts_check_key or xts_verify_key before 
> setting the key?
> 
Will do.

Thanks,

Jonathan



[PATCH] crypto: tcrypt - reschedule during speed tests

2018-07-23 Thread Horia Geantă
Avoid RCU stalls in the case of non-preemptible kernel and lengthy
speed tests by rescheduling when advancing from one block size
to another.

Signed-off-by: Horia Geantă 
---
 crypto/tcrypt.c | 36 
 1 file changed, 24 insertions(+), 12 deletions(-)

diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 078ec36007bf..bdde95e8d369 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -415,12 +415,14 @@ static void test_mb_aead_speed(const char *algo, int enc, 
int secs,
 
}
 
-   if (secs)
+   if (secs) {
ret = test_mb_aead_jiffies(data, enc, *b_size,
   secs, num_mb);
-   else
+   cond_resched();
+   } else {
ret = test_mb_aead_cycles(data, enc, *b_size,
  num_mb);
+   }
 
if (ret) {
pr_err("%s() failed return code=%d\n", e, ret);
@@ -660,11 +662,13 @@ static void test_aead_speed(const char *algo, int enc, 
unsigned int secs,
   *b_size + (enc ? 0 : authsize),
   iv);
 
-   if (secs)
+   if (secs) {
ret = test_aead_jiffies(req, enc, *b_size,
secs);
-   else
+   cond_resched();
+   } else {
ret = test_aead_cycles(req, enc, *b_size);
+   }
 
if (ret) {
pr_err("%s() failed return code=%d\n", e, ret);
@@ -876,11 +880,13 @@ static void test_mb_ahash_speed(const char *algo, 
unsigned int secs,
i, speed[i].blen, speed[i].plen,
speed[i].blen / speed[i].plen);
 
-   if (secs)
+   if (secs) {
ret = test_mb_ahash_jiffies(data, speed[i].blen, secs,
num_mb);
-   else
+   cond_resched();
+   } else {
ret = test_mb_ahash_cycles(data, speed[i].blen, num_mb);
+   }
 
 
if (ret) {
@@ -1103,12 +1109,14 @@ static void test_ahash_speed_common(const char *algo, 
unsigned int secs,
 
ahash_request_set_crypt(req, sg, output, speed[i].plen);
 
-   if (secs)
+   if (secs) {
ret = test_ahash_jiffies(req, speed[i].blen,
 speed[i].plen, output, secs);
-   else
+   cond_resched();
+   } else {
ret = test_ahash_cycles(req, speed[i].blen,
speed[i].plen, output);
+   }
 
if (ret) {
pr_err("hashing failed ret=%d\n", ret);
@@ -1367,13 +1375,15 @@ static void test_mb_skcipher_speed(const char *algo, 
int enc, int secs,
   iv);
}
 
-   if (secs)
+   if (secs) {
ret = test_mb_acipher_jiffies(data, enc,
  *b_size, secs,
  num_mb);
-   else
+   cond_resched();
+   } else {
ret = test_mb_acipher_cycles(data, enc,
 *b_size, num_mb);
+   }
 
if (ret) {
pr_err("%s() failed flags=%x\n", e,
@@ -1581,12 +1591,14 @@ static void test_skcipher_speed(const char *algo, int 
enc, unsigned int secs,
 
skcipher_request_set_crypt(req, sg, sg, *b_size, iv);
 
-   if (secs)
+   if (secs) {
ret = test_acipher_jiffies(req, enc,
   *b_size, secs);
-   else
+   cond_resched();
+   } else {
ret = test_acipher_cycles(req, enc,
  *b_size);
+   }
 
if (ret) {
pr_err("%s() failed flags=%x\n", e,
-- 
2.16.2