All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver
@ 2017-06-02 12:24 David Gstir
  2017-06-02 12:24 ` [RFC PATCH 1/2] crypto: caam - properly set IV after {en,de}crypt David Gstir
                   ` (4 more replies)
  0 siblings, 5 replies; 27+ messages in thread
From: David Gstir @ 2017-06-02 12:24 UTC (permalink / raw)
  To: horia.geanta, dan.douglass, herbert, davem
  Cc: richard, linux-crypto, linux-kernel, David Gstir

Hi!

While testing fscrypt's filename encryption, I noticed that the implementation
of cts(cbc(aes)) is broken when the CAAM hardware crypto driver is enabled.
Some digging showed that the refactoring of crypto/cts.c in v4.8 
(commit 0605c41cc53ca) exposed some problems with CAAM's aes-cbc
implementation. This can be tested quite easily by loading the tcrypt
module with mode=38. Looks like the cts mode is not used very often
and this went unnoticed since 4.8...

This patch series is an attempt to fix that and get cts(cbc(aes)) working
properly again when the CAAM driver is enabled.

Specifically, the issues are:

1) The cts implementation assumes ->info of ablkcipher_request (or ->iv of
   skcipher_request respectively) to be set to the last ciphertext block when
   the aes-cbc encryption is finished. Meaning that ->info is changed by the
   aes-cbc code. The CAAM driver does not do that and leaves ->info as-is.

   It is not fully clear to me yet if this is a requirement of the crypto API,
   or if this is just a side effect that is exploited by the cts implementation?

   For now, I assumed it is a requirement of the crypto API since I've seen
   other crypto drivers (e.g. AMD's CCP) do that. So the patch fixes the CAAM
   crypto driver accordingly.

   Also, the aead code in the CAAM driver, more specifically the gcm mode code
   seems to have the same flaw, so it'll need a similar fix in case.


2) The cts implementation uses aes-cbc twice to perform its job. The second
   time, it is called from within the callback of the first call to aes-cbc.
   This usage is not properly handled in the CAAM driver which triggers the
   BUG below.

   My current proposal is to use in_interrupt() to detect such cases and set
   the k*alloc flags accordingly. However, since using in_interrupt() is not
   really nice, I'm wondering if there is a better way to handle this?


Thanks,
David

<snip>
[  126.252543] BUG: sleeping function called from invalid context at mm/slab.h:432
[  126.260099] in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/0
[  126.266837] no locks held by swapper/0/0.
[  126.270969] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.12.0-rc3-00052-g0ddec680d395 #287
[  126.279226] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[  126.285821] Backtrace:
[  126.288406] [<c010c3e4>] (dump_backtrace) from [<c010c690>] (show_stack+0x18/0x1c)
[  126.296057]  r7:00000000 r6:60000113 r5:00000000 r4:c102ab48
[  126.301798] [<c010c678>] (show_stack) from [<c0427060>] (dump_stack+0xb4/0xe8)
[  126.309106] [<c0426fac>] (dump_stack) from [<c014f020>] (___might_sleep+0x17c/0x2a0)
[  126.316929]  r9:00000000 r8:c0a016dc r7:c101ee3e r6:000001b0 r5:c0c12fac r4:ffffe000
[  126.324751] [<c014eea4>] (___might_sleep) from [<c014f1a8>] (__might_sleep+0x64/0xa4)
[  126.332655]  r7:014080c1 r6:00000000 r5:000001b0 r4:c0c12fac
[  126.338397] [<c014f144>] (__might_sleep) from [<c0224a20>] (__kmalloc+0x130/0x1b8)
[  126.346039]  r6:c071a8ec r5:014080c1 r4:eec01e00
[  126.350742] [<c02248f0>] (__kmalloc) from [<c071a8ec>] (ablkcipher_edesc_alloc.constprop.1+0x200/0x900)
[  126.360213]  r10:00000000 r9:00000000 r8:c0a016dc r7:c0a016dc r6:ee05ac10 r5:edfdaec0
[  126.368109]  r4:00000001 r3:00000020
[  126.371765] [<c071a6ec>] (ablkcipher_edesc_alloc.constprop.1) from [<c071b010>] (ablkcipher_encrypt+0x24/0x9c)
[  126.381843]  r10:00000000 r9:00000020 r8:00000001 r7:ee05ac10 r6:ed597000 r5:edfdaec0
[  126.389738]  r4:ed475d08
[  126.392354] [<c071afec>] (ablkcipher_encrypt) from [<c03d6f20>] (skcipher_encrypt_ablkcipher+0x68/0x6c)
[  126.401822]  r7:ed475d08 r6:ed597000 r5:00000400 r4:ed475d08
[  126.407566] [<c03d6eb8>] (skcipher_encrypt_ablkcipher) from [<c03e8a70>] (cts_cbc_encrypt+0x118/0x124)
[  126.416947]  r7:ed475d08 r6:c1001cc0 r5:00000010 r4:edfdae00
[  126.422686] [<c03e8958>] (cts_cbc_encrypt) from [<c03e8b88>] (crypto_cts_encrypt_done+0x20/0x54)
[  126.431548]  r10:00000000 r9:ee05ac10 r8:00000000 r7:00000010 r6:edc8e6c0 r5:edc8e6d8
[  126.439443]  r4:edfdae00
[  126.442056] [<c03e8b68>] (crypto_cts_encrypt_done) from [<c07195a0>] (ablkcipher_encrypt_done+0x88/0x9c)
[  126.445180] fec 2188000.ethernet eth0: MDIO read timeout
[  126.456948]  r5:edc8e6d8 r4:edfdaec0
[  126.460604] [<c0719518>] (ablkcipher_encrypt_done) from [<c0715ca0>] (caam_jr_dequeue+0x214/0x2d4)
[  126.469639]  r9:00000001 r8:ee088010 r7:000001ff r6:00000001 r5:00000000 r4:edfdaec0
[  126.477467] [<c0715a8c>] (caam_jr_dequeue) from [<c012b3f0>] (tasklet_action+0x98/0x154)
[  126.485160] fec 2188000.ethernet eth0: MDIO read timeout
[  126.490975]  r10:c1080b80 r9:c1008b84 r8:00000000 r7:c1000000 r6:00000000 r5:ee088028
[  126.498870]  r4:ee088024
[  126.501484] [<c012b358>] (tasklet_action) from [<c012b60c>] (__do_softirq+0xf0/0x2a4)
[  126.509390]  r10:40000006 r9:c1002080 r8:00000101 r7:c1002098 r6:c1000000 r5:00000006
[  126.517285]  r4:00000000
[  126.519896] [<c012b51c>] (__do_softirq) from [<c012bb90>] (irq_exit+0xec/0x168)
[  126.525127] fec 2188000.ethernet eth0: MDIO write timeout
[  126.532709]  r10:c1008cf0 r9:eec08400 r8:00000001 r7:00000000 r6:c1008b84 r5:00000000
[  126.540603]  r4:c0fd940c
[  126.543222] [<c012baa4>] (irq_exit) from [<c017ff24>] (__handle_domain_irq+0x74/0xe8)
[  126.551135] [<c017feb0>] (__handle_domain_irq) from [<c01015fc>] (gic_handle_irq+0x58/0xbc)
[  126.559564]  r9:f4000100 r8:c102af80 r7:c1001ea8 r6:000003ff r5:000003eb r4:f400010c
[  126.567384] [<c01015a4>] (gic_handle_irq) from [<c010d2f0>] (__irq_svc+0x70/0x98)
[  126.574937] Exception stack(0xc1001ea8 to 0xc1001ef0)
[  126.580065] 1ea0:                   00000001 2e39a000 00000000 c100c080 00000000 ef374698
[  126.588320] 1ec0: 653b20b1 0000001d 653afed6 0000001d 00000000 c1001f24 c1001ec8 c1001ef8
[  126.596568] 1ee0: c016fcf4 c06f1fbc 20000013 ffffffff
[  126.601696]  r10:00000000 r9:c1000000 r8:653afed6 r7:c1001edc r6:ffffffff r5:20000013
[  126.609591]  r4:c06f1fbc
[  126.612210] [<c06f1e34>] (cpuidle_enter_state) from [<c06f2120>] (cpuidle_enter+0x1c/0x20)
[  126.620551]  r10:c100f8c0 r9:ef374698 r8:c1008b84 r7:c0fda690 r6:c10089ec r5:c1008a38
[  126.628448]  r4:c1000000 r3:ef374698
[  126.632114] [<c06f2104>] (cpuidle_enter) from [<c0167330>] (call_cpuidle+0x28/0x44)
[  126.639859] [<c0167308>] (call_cpuidle) from [<c0167608>] (do_idle+0x1ac/0x220)
[  126.647249] [<c016745c>] (do_idle) from [<c0167a20>] (cpu_startup_entry+0x20/0x24)
[  126.654895]  r10:c0e60a50 r9:efffc940 r8:c1080000 r7:c10089c0 r6:c1080000 r5:00000002
[  126.662793]  r4:000000bd r3:c0e733c4
[  126.666457] [<c0167a00>] (cpu_startup_entry) from [<c09cfbd4>] (rest_init+0x154/0x198)
[  126.674463] [<c09cfa80>] (rest_init) from [<c0e00cf0>] (start_kernel+0x344/0x3b8)
[  126.682015]  r5:ffffffff r4:c108004c
[  126.685668] [<c0e009ac>] (start_kernel) from [<1000807c>] (0x1000807c)
</snip>

  crypto: caam - properly set IV after {en,de}crypt
  crypto: caam - fix k*alloc if called from own cipher callback

 drivers/crypto/caam/caamalg.c | 55 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 45 insertions(+), 10 deletions(-)

-- 
2.12.0

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [RFC PATCH 1/2] crypto: caam - properly set IV after {en,de}crypt
  2017-06-02 12:24 [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver David Gstir
@ 2017-06-02 12:24 ` David Gstir
  2017-06-19 10:31   ` Horia Geantă
  2017-06-02 12:24 ` [RFC PATCH 2/2] crypto: caam - fix k*alloc if called from own cipher callback David Gstir
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 27+ messages in thread
From: David Gstir @ 2017-06-02 12:24 UTC (permalink / raw)
  To: horia.geanta, dan.douglass, herbert, davem
  Cc: richard, linux-crypto, linux-kernel, David Gstir

Certain cipher modes like CTS expect the IV (req->info) of
ablkcipher_request (or equivalently req->iv of skcipher_request) to
contain the last ciphertext block when the {en,de}crypt operation is done.
This is currently not the case for the CAAM driver which in turn breaks
e.g. cts(cbc(aes)) when the CAAM driver is enabled.

This patch fixes the CAAM driver to properly set the IV after the
{en,de}crypt operation of ablkcipher finishes.

Signed-off-by: David Gstir <david@sigma-star.at>
---
 drivers/crypto/caam/caamalg.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 398807d1b77e..d13c1aee4427 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -882,10 +882,11 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
 {
 	struct ablkcipher_request *req = context;
 	struct ablkcipher_edesc *edesc;
-#ifdef DEBUG
 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
+	int nents;
 
+#ifdef DEBUG
 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 #endif
 
@@ -904,6 +905,19 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
 #endif
 
 	ablkcipher_unmap(jrdev, edesc, req);
+
+	if (req->src == req->dst)
+		nents = edesc->src_nents;
+	else
+		nents = edesc->dst_nents;
+
+	/*
+	 * The crypto API expects us to set the IV (req->info) to the last
+	 * ciphertext block. This is used e.g. by the CTS mode.
+	 */
+	sg_pcopy_to_buffer(req->dst, nents, req->info, ivsize,
+			   req->nbytes - ivsize);
+
 	kfree(edesc);
 
 	ablkcipher_request_complete(req, err);
@@ -914,10 +928,10 @@ static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
 {
 	struct ablkcipher_request *req = context;
 	struct ablkcipher_edesc *edesc;
-#ifdef DEBUG
 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
 
+#ifdef DEBUG
 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 #endif
 
@@ -935,6 +949,14 @@ static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
 #endif
 
 	ablkcipher_unmap(jrdev, edesc, req);
+
+	/*
+	 * The crypto API expects us to set the IV (req->info) to the last
+	 * ciphertext block.
+	 */
+	sg_pcopy_to_buffer(req->src, edesc->src_nents, req->info, ivsize,
+			   req->nbytes - ivsize);
+
 	kfree(edesc);
 
 	ablkcipher_request_complete(req, err);
-- 
2.12.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [RFC PATCH 2/2] crypto: caam - fix k*alloc if called from own cipher callback
  2017-06-02 12:24 [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver David Gstir
  2017-06-02 12:24 ` [RFC PATCH 1/2] crypto: caam - properly set IV after {en,de}crypt David Gstir
@ 2017-06-02 12:24 ` David Gstir
  2017-06-13 11:53 ` [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver David Gstir
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 27+ messages in thread
From: David Gstir @ 2017-06-02 12:24 UTC (permalink / raw)
  To: horia.geanta, dan.douglass, herbert, davem
  Cc: richard, linux-crypto, linux-kernel, David Gstir

There are cases (e.g. the cts mode) where a cipher can be called again
from its own callback. In our case this callback is executed from within
a tasklet in the jobring, we must not sleep when allocating memory.

This patch detects such cases by using in_interrupt() to properly set the
k*alloc flags. In most cases we will still use GFP_KERNEL if the flags
CRYPTO_TFM_REQ_MAY_SLEEP or CRYPTO_TFM_REQ_MAY_BACKLOG are set for the
cipher request.

Signed-off-by: David Gstir <david@sigma-star.at>
---
 drivers/crypto/caam/caamalg.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index d13c1aee4427..4c4a5d1ad875 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -1209,13 +1209,18 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
+	gfp_t flags;
 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
 	struct aead_edesc *edesc;
 	int sec4_sg_index, sec4_sg_len, sec4_sg_bytes;
 	unsigned int authsize = ctx->authsize;
 
+	if (!in_interrupt() && req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
+						  CRYPTO_TFM_REQ_MAY_SLEEP))
+		flags = GFP_KERNEL;
+	else
+		flags = GFP_ATOMIC;
+
 	if (unlikely(req->dst != req->src)) {
 		src_nents = sg_nents_for_len(req->src, req->assoclen +
 					     req->cryptlen);
@@ -1497,9 +1502,7 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
-		       GFP_KERNEL : GFP_ATOMIC;
+	gfp_t flags;
 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
 	struct ablkcipher_edesc *edesc;
 	dma_addr_t iv_dma = 0;
@@ -1507,6 +1510,12 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
 	int dst_sg_idx, sec4_sg_ents, sec4_sg_bytes;
 
+	if (!in_interrupt() && req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
+						  CRYPTO_TFM_REQ_MAY_SLEEP))
+		flags = GFP_KERNEL;
+	else
+		flags = GFP_ATOMIC;
+
 	src_nents = sg_nents_for_len(req->src, req->nbytes);
 	if (unlikely(src_nents < 0)) {
 		dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
@@ -1703,9 +1712,7 @@ static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc(
 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
-		       GFP_KERNEL : GFP_ATOMIC;
+	gfp_t flags;
 	int src_nents, mapped_src_nents, dst_nents, mapped_dst_nents;
 	struct ablkcipher_edesc *edesc;
 	dma_addr_t iv_dma = 0;
@@ -1713,6 +1720,12 @@ static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc(
 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
 	int dst_sg_idx, sec4_sg_ents, sec4_sg_bytes;
 
+	if (!in_interrupt() && req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
+						  CRYPTO_TFM_REQ_MAY_SLEEP))
+		flags = GFP_KERNEL;
+	else
+		flags = GFP_ATOMIC;
+
 	src_nents = sg_nents_for_len(req->src, req->nbytes);
 	if (unlikely(src_nents < 0)) {
 		dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
-- 
2.12.0

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver
  2017-06-02 12:24 [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver David Gstir
  2017-06-02 12:24 ` [RFC PATCH 1/2] crypto: caam - properly set IV after {en,de}crypt David Gstir
  2017-06-02 12:24 ` [RFC PATCH 2/2] crypto: caam - fix k*alloc if called from own cipher callback David Gstir
@ 2017-06-13 11:53 ` David Gstir
  2017-06-15 14:57 ` Horia Geantă
  2017-06-28 13:27 ` [PATCH] crypto: caam - properly set IV after {en,de}crypt David Gstir
  4 siblings, 0 replies; 27+ messages in thread
From: David Gstir @ 2017-06-13 11:53 UTC (permalink / raw)
  To: horia.geanta, dan.douglass, herbert, davem
  Cc: richard, linux-crypto, linux-kernel

Friendly ping. Any feedback on that?

Thanks,
David

> On 2 Jun 2017, at 14:24, David Gstir <david@sigma-star.at> wrote:
> 
> Hi!
> 
> While testing fscrypt's filename encryption, I noticed that the implementation
> of cts(cbc(aes)) is broken when the CAAM hardware crypto driver is enabled.
> Some digging showed that the refactoring of crypto/cts.c in v4.8 
> (commit 0605c41cc53ca) exposed some problems with CAAM's aes-cbc
> implementation. This can be tested quite easily by loading the tcrypt
> module with mode=38. Looks like the cts mode is not used very often
> and this went unnoticed since 4.8...
> 
> This patch series is an attempt to fix that and get cts(cbc(aes)) working
> properly again when the CAAM driver is enabled.
> 
> Specifically, the issues are:
> 
> 1) The cts implementation assumes ->info of ablkcipher_request (or ->iv of
>   skcipher_request respectively) to be set to the last ciphertext block when
>   the aes-cbc encryption is finished. Meaning that ->info is changed by the
>   aes-cbc code. The CAAM driver does not do that and leaves ->info as-is.
> 
>   It is not fully clear to me yet if this is a requirement of the crypto API,
>   or if this is just a side effect that is exploited by the cts implementation?
> 
>   For now, I assumed it is a requirement of the crypto API since I've seen
>   other crypto drivers (e.g. AMD's CCP) do that. So the patch fixes the CAAM
>   crypto driver accordingly.
> 
>   Also, the aead code in the CAAM driver, more specifically the gcm mode code
>   seems to have the same flaw, so it'll need a similar fix in case.
> 
> 
> 2) The cts implementation uses aes-cbc twice to perform its job. The second
>   time, it is called from within the callback of the first call to aes-cbc.
>   This usage is not properly handled in the CAAM driver which triggers the
>   BUG below.
> 
>   My current proposal is to use in_interrupt() to detect such cases and set
>   the k*alloc flags accordingly. However, since using in_interrupt() is not
>   really nice, I'm wondering if there is a better way to handle this?
> 
> 
> Thanks,
> David
> 
> <snip>
> [  126.252543] BUG: sleeping function called from invalid context at mm/slab.h:432
> [  126.260099] in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/0
> [  126.266837] no locks held by swapper/0/0.
> [  126.270969] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.12.0-rc3-00052-g0ddec680d395 #287
> [  126.279226] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
> [  126.285821] Backtrace:
> [  126.288406] [<c010c3e4>] (dump_backtrace) from [<c010c690>] (show_stack+0x18/0x1c)
> [  126.296057]  r7:00000000 r6:60000113 r5:00000000 r4:c102ab48
> [  126.301798] [<c010c678>] (show_stack) from [<c0427060>] (dump_stack+0xb4/0xe8)
> [  126.309106] [<c0426fac>] (dump_stack) from [<c014f020>] (___might_sleep+0x17c/0x2a0)
> [  126.316929]  r9:00000000 r8:c0a016dc r7:c101ee3e r6:000001b0 r5:c0c12fac r4:ffffe000
> [  126.324751] [<c014eea4>] (___might_sleep) from [<c014f1a8>] (__might_sleep+0x64/0xa4)
> [  126.332655]  r7:014080c1 r6:00000000 r5:000001b0 r4:c0c12fac
> [  126.338397] [<c014f144>] (__might_sleep) from [<c0224a20>] (__kmalloc+0x130/0x1b8)
> [  126.346039]  r6:c071a8ec r5:014080c1 r4:eec01e00
> [  126.350742] [<c02248f0>] (__kmalloc) from [<c071a8ec>] (ablkcipher_edesc_alloc.constprop.1+0x200/0x900)
> [  126.360213]  r10:00000000 r9:00000000 r8:c0a016dc r7:c0a016dc r6:ee05ac10 r5:edfdaec0
> [  126.368109]  r4:00000001 r3:00000020
> [  126.371765] [<c071a6ec>] (ablkcipher_edesc_alloc.constprop.1) from [<c071b010>] (ablkcipher_encrypt+0x24/0x9c)
> [  126.381843]  r10:00000000 r9:00000020 r8:00000001 r7:ee05ac10 r6:ed597000 r5:edfdaec0
> [  126.389738]  r4:ed475d08
> [  126.392354] [<c071afec>] (ablkcipher_encrypt) from [<c03d6f20>] (skcipher_encrypt_ablkcipher+0x68/0x6c)
> [  126.401822]  r7:ed475d08 r6:ed597000 r5:00000400 r4:ed475d08
> [  126.407566] [<c03d6eb8>] (skcipher_encrypt_ablkcipher) from [<c03e8a70>] (cts_cbc_encrypt+0x118/0x124)
> [  126.416947]  r7:ed475d08 r6:c1001cc0 r5:00000010 r4:edfdae00
> [  126.422686] [<c03e8958>] (cts_cbc_encrypt) from [<c03e8b88>] (crypto_cts_encrypt_done+0x20/0x54)
> [  126.431548]  r10:00000000 r9:ee05ac10 r8:00000000 r7:00000010 r6:edc8e6c0 r5:edc8e6d8
> [  126.439443]  r4:edfdae00
> [  126.442056] [<c03e8b68>] (crypto_cts_encrypt_done) from [<c07195a0>] (ablkcipher_encrypt_done+0x88/0x9c)
> [  126.445180] fec 2188000.ethernet eth0: MDIO read timeout
> [  126.456948]  r5:edc8e6d8 r4:edfdaec0
> [  126.460604] [<c0719518>] (ablkcipher_encrypt_done) from [<c0715ca0>] (caam_jr_dequeue+0x214/0x2d4)
> [  126.469639]  r9:00000001 r8:ee088010 r7:000001ff r6:00000001 r5:00000000 r4:edfdaec0
> [  126.477467] [<c0715a8c>] (caam_jr_dequeue) from [<c012b3f0>] (tasklet_action+0x98/0x154)
> [  126.485160] fec 2188000.ethernet eth0: MDIO read timeout
> [  126.490975]  r10:c1080b80 r9:c1008b84 r8:00000000 r7:c1000000 r6:00000000 r5:ee088028
> [  126.498870]  r4:ee088024
> [  126.501484] [<c012b358>] (tasklet_action) from [<c012b60c>] (__do_softirq+0xf0/0x2a4)
> [  126.509390]  r10:40000006 r9:c1002080 r8:00000101 r7:c1002098 r6:c1000000 r5:00000006
> [  126.517285]  r4:00000000
> [  126.519896] [<c012b51c>] (__do_softirq) from [<c012bb90>] (irq_exit+0xec/0x168)
> [  126.525127] fec 2188000.ethernet eth0: MDIO write timeout
> [  126.532709]  r10:c1008cf0 r9:eec08400 r8:00000001 r7:00000000 r6:c1008b84 r5:00000000
> [  126.540603]  r4:c0fd940c
> [  126.543222] [<c012baa4>] (irq_exit) from [<c017ff24>] (__handle_domain_irq+0x74/0xe8)
> [  126.551135] [<c017feb0>] (__handle_domain_irq) from [<c01015fc>] (gic_handle_irq+0x58/0xbc)
> [  126.559564]  r9:f4000100 r8:c102af80 r7:c1001ea8 r6:000003ff r5:000003eb r4:f400010c
> [  126.567384] [<c01015a4>] (gic_handle_irq) from [<c010d2f0>] (__irq_svc+0x70/0x98)
> [  126.574937] Exception stack(0xc1001ea8 to 0xc1001ef0)
> [  126.580065] 1ea0:                   00000001 2e39a000 00000000 c100c080 00000000 ef374698
> [  126.588320] 1ec0: 653b20b1 0000001d 653afed6 0000001d 00000000 c1001f24 c1001ec8 c1001ef8
> [  126.596568] 1ee0: c016fcf4 c06f1fbc 20000013 ffffffff
> [  126.601696]  r10:00000000 r9:c1000000 r8:653afed6 r7:c1001edc r6:ffffffff r5:20000013
> [  126.609591]  r4:c06f1fbc
> [  126.612210] [<c06f1e34>] (cpuidle_enter_state) from [<c06f2120>] (cpuidle_enter+0x1c/0x20)
> [  126.620551]  r10:c100f8c0 r9:ef374698 r8:c1008b84 r7:c0fda690 r6:c10089ec r5:c1008a38
> [  126.628448]  r4:c1000000 r3:ef374698
> [  126.632114] [<c06f2104>] (cpuidle_enter) from [<c0167330>] (call_cpuidle+0x28/0x44)
> [  126.639859] [<c0167308>] (call_cpuidle) from [<c0167608>] (do_idle+0x1ac/0x220)
> [  126.647249] [<c016745c>] (do_idle) from [<c0167a20>] (cpu_startup_entry+0x20/0x24)
> [  126.654895]  r10:c0e60a50 r9:efffc940 r8:c1080000 r7:c10089c0 r6:c1080000 r5:00000002
> [  126.662793]  r4:000000bd r3:c0e733c4
> [  126.666457] [<c0167a00>] (cpu_startup_entry) from [<c09cfbd4>] (rest_init+0x154/0x198)
> [  126.674463] [<c09cfa80>] (rest_init) from [<c0e00cf0>] (start_kernel+0x344/0x3b8)
> [  126.682015]  r5:ffffffff r4:c108004c
> [  126.685668] [<c0e009ac>] (start_kernel) from [<1000807c>] (0x1000807c)
> </snip>
> 
>  crypto: caam - properly set IV after {en,de}crypt
>  crypto: caam - fix k*alloc if called from own cipher callback
> 
> drivers/crypto/caam/caamalg.c | 55 +++++++++++++++++++++++++++++++++++--------
> 1 file changed, 45 insertions(+), 10 deletions(-)
> 
> -- 
> 2.12.0

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver
  2017-06-02 12:24 [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver David Gstir
                   ` (2 preceding siblings ...)
  2017-06-13 11:53 ` [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver David Gstir
@ 2017-06-15 14:57 ` Horia Geantă
  2017-06-16  7:57   ` Horia Geantă
  2017-06-28 13:27 ` [PATCH] crypto: caam - properly set IV after {en,de}crypt David Gstir
  4 siblings, 1 reply; 27+ messages in thread
From: Horia Geantă @ 2017-06-15 14:57 UTC (permalink / raw)
  To: David Gstir, Dan Douglass, herbert, davem, Radu Solea
  Cc: richard, linux-crypto, linux-kernel

On 6/2/2017 3:25 PM, David Gstir wrote:
> Hi!
> 
> While testing fscrypt's filename encryption, I noticed that the implementation
> of cts(cbc(aes)) is broken when the CAAM hardware crypto driver is enabled.
> Some digging showed that the refactoring of crypto/cts.c in v4.8 
> (commit 0605c41cc53ca) exposed some problems with CAAM's aes-cbc
> implementation. This can be tested quite easily by loading the tcrypt
> module with mode=38. Looks like the cts mode is not used very often
> and this went unnoticed since 4.8...
> 
> This patch series is an attempt to fix that and get cts(cbc(aes)) working
> properly again when the CAAM driver is enabled.
> 
David, thanks for taking time to fix these.

> Specifically, the issues are:
> 
> 1) The cts implementation assumes ->info of ablkcipher_request (or ->iv of
>    skcipher_request respectively) to be set to the last ciphertext block when
>    the aes-cbc encryption is finished. Meaning that ->info is changed by the
>    aes-cbc code. The CAAM driver does not do that and leaves ->info as-is.
> 
>    It is not fully clear to me yet if this is a requirement of the crypto API,
>    or if this is just a side effect that is exploited by the cts implementation?
> 
>    For now, I assumed it is a requirement of the crypto API since I've seen
>    other crypto drivers (e.g. AMD's CCP) do that. So the patch fixes the CAAM
>    crypto driver accordingly.
> 
IIUC, yes, the Crypto API requires ->info to be updated.

Dan, Radu,

IIRC, you've hit smth. similar while testing CAAM on i.MX.
Could you please review David's fix, compare it with yours, so in the
end we would choose the one that fits best?

>    Also, the aead code in the CAAM driver, more specifically the gcm mode code
>    seems to have the same flaw, so it'll need a similar fix in case.
> 
> 
> 2) The cts implementation uses aes-cbc twice to perform its job. The second
>    time, it is called from within the callback of the first call to aes-cbc.
>    This usage is not properly handled in the CAAM driver which triggers the
>    BUG below.
> 
Dan, Radu - have you seen this on i.MX?

>    My current proposal is to use in_interrupt() to detect such cases and set
>    the k*alloc flags accordingly. However, since using in_interrupt() is not
>    really nice, I'm wondering if there is a better way to handle this?
> 
Nothing else crosses my mind right now, but I'd like to sleep on it.

> 
> Thanks,
> David
> 
> <snip>
> [  126.252543] BUG: sleeping function called from invalid context at mm/slab.h:432
> [  126.260099] in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/0
> [  126.266837] no locks held by swapper/0/0.
> [  126.270969] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.12.0-rc3-00052-g0ddec680d395 #287
> [  126.279226] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
> [  126.285821] Backtrace:
> [  126.288406] [<c010c3e4>] (dump_backtrace) from [<c010c690>] (show_stack+0x18/0x1c)
> [  126.296057]  r7:00000000 r6:60000113 r5:00000000 r4:c102ab48
> [  126.301798] [<c010c678>] (show_stack) from [<c0427060>] (dump_stack+0xb4/0xe8)
> [  126.309106] [<c0426fac>] (dump_stack) from [<c014f020>] (___might_sleep+0x17c/0x2a0)
> [  126.316929]  r9:00000000 r8:c0a016dc r7:c101ee3e r6:000001b0 r5:c0c12fac r4:ffffe000
> [  126.324751] [<c014eea4>] (___might_sleep) from [<c014f1a8>] (__might_sleep+0x64/0xa4)
> [  126.332655]  r7:014080c1 r6:00000000 r5:000001b0 r4:c0c12fac
> [  126.338397] [<c014f144>] (__might_sleep) from [<c0224a20>] (__kmalloc+0x130/0x1b8)
> [  126.346039]  r6:c071a8ec r5:014080c1 r4:eec01e00
> [  126.350742] [<c02248f0>] (__kmalloc) from [<c071a8ec>] (ablkcipher_edesc_alloc.constprop.1+0x200/0x900)
> [  126.360213]  r10:00000000 r9:00000000 r8:c0a016dc r7:c0a016dc r6:ee05ac10 r5:edfdaec0
> [  126.368109]  r4:00000001 r3:00000020
> [  126.371765] [<c071a6ec>] (ablkcipher_edesc_alloc.constprop.1) from [<c071b010>] (ablkcipher_encrypt+0x24/0x9c)
> [  126.381843]  r10:00000000 r9:00000020 r8:00000001 r7:ee05ac10 r6:ed597000 r5:edfdaec0
> [  126.389738]  r4:ed475d08
> [  126.392354] [<c071afec>] (ablkcipher_encrypt) from [<c03d6f20>] (skcipher_encrypt_ablkcipher+0x68/0x6c)
> [  126.401822]  r7:ed475d08 r6:ed597000 r5:00000400 r4:ed475d08
> [  126.407566] [<c03d6eb8>] (skcipher_encrypt_ablkcipher) from [<c03e8a70>] (cts_cbc_encrypt+0x118/0x124)
> [  126.416947]  r7:ed475d08 r6:c1001cc0 r5:00000010 r4:edfdae00
> [  126.422686] [<c03e8958>] (cts_cbc_encrypt) from [<c03e8b88>] (crypto_cts_encrypt_done+0x20/0x54)
> [  126.431548]  r10:00000000 r9:ee05ac10 r8:00000000 r7:00000010 r6:edc8e6c0 r5:edc8e6d8
> [  126.439443]  r4:edfdae00
> [  126.442056] [<c03e8b68>] (crypto_cts_encrypt_done) from [<c07195a0>] (ablkcipher_encrypt_done+0x88/0x9c)
> [  126.445180] fec 2188000.ethernet eth0: MDIO read timeout
> [  126.456948]  r5:edc8e6d8 r4:edfdaec0
> [  126.460604] [<c0719518>] (ablkcipher_encrypt_done) from [<c0715ca0>] (caam_jr_dequeue+0x214/0x2d4)
> [  126.469639]  r9:00000001 r8:ee088010 r7:000001ff r6:00000001 r5:00000000 r4:edfdaec0
> [  126.477467] [<c0715a8c>] (caam_jr_dequeue) from [<c012b3f0>] (tasklet_action+0x98/0x154)
> [  126.485160] fec 2188000.ethernet eth0: MDIO read timeout
> [  126.490975]  r10:c1080b80 r9:c1008b84 r8:00000000 r7:c1000000 r6:00000000 r5:ee088028
> [  126.498870]  r4:ee088024
> [  126.501484] [<c012b358>] (tasklet_action) from [<c012b60c>] (__do_softirq+0xf0/0x2a4)
> [  126.509390]  r10:40000006 r9:c1002080 r8:00000101 r7:c1002098 r6:c1000000 r5:00000006
> [  126.517285]  r4:00000000
> [  126.519896] [<c012b51c>] (__do_softirq) from [<c012bb90>] (irq_exit+0xec/0x168)
> [  126.525127] fec 2188000.ethernet eth0: MDIO write timeout
> [  126.532709]  r10:c1008cf0 r9:eec08400 r8:00000001 r7:00000000 r6:c1008b84 r5:00000000
> [  126.540603]  r4:c0fd940c
> [  126.543222] [<c012baa4>] (irq_exit) from [<c017ff24>] (__handle_domain_irq+0x74/0xe8)
> [  126.551135] [<c017feb0>] (__handle_domain_irq) from [<c01015fc>] (gic_handle_irq+0x58/0xbc)
> [  126.559564]  r9:f4000100 r8:c102af80 r7:c1001ea8 r6:000003ff r5:000003eb r4:f400010c
> [  126.567384] [<c01015a4>] (gic_handle_irq) from [<c010d2f0>] (__irq_svc+0x70/0x98)
> [  126.574937] Exception stack(0xc1001ea8 to 0xc1001ef0)
> [  126.580065] 1ea0:                   00000001 2e39a000 00000000 c100c080 00000000 ef374698
> [  126.588320] 1ec0: 653b20b1 0000001d 653afed6 0000001d 00000000 c1001f24 c1001ec8 c1001ef8
> [  126.596568] 1ee0: c016fcf4 c06f1fbc 20000013 ffffffff
> [  126.601696]  r10:00000000 r9:c1000000 r8:653afed6 r7:c1001edc r6:ffffffff r5:20000013
> [  126.609591]  r4:c06f1fbc
> [  126.612210] [<c06f1e34>] (cpuidle_enter_state) from [<c06f2120>] (cpuidle_enter+0x1c/0x20)
> [  126.620551]  r10:c100f8c0 r9:ef374698 r8:c1008b84 r7:c0fda690 r6:c10089ec r5:c1008a38
> [  126.628448]  r4:c1000000 r3:ef374698
> [  126.632114] [<c06f2104>] (cpuidle_enter) from [<c0167330>] (call_cpuidle+0x28/0x44)
> [  126.639859] [<c0167308>] (call_cpuidle) from [<c0167608>] (do_idle+0x1ac/0x220)
> [  126.647249] [<c016745c>] (do_idle) from [<c0167a20>] (cpu_startup_entry+0x20/0x24)
> [  126.654895]  r10:c0e60a50 r9:efffc940 r8:c1080000 r7:c10089c0 r6:c1080000 r5:00000002
> [  126.662793]  r4:000000bd r3:c0e733c4
> [  126.666457] [<c0167a00>] (cpu_startup_entry) from [<c09cfbd4>] (rest_init+0x154/0x198)
> [  126.674463] [<c09cfa80>] (rest_init) from [<c0e00cf0>] (start_kernel+0x344/0x3b8)
> [  126.682015]  r5:ffffffff r4:c108004c
> [  126.685668] [<c0e009ac>] (start_kernel) from [<1000807c>] (0x1000807c)
> </snip>
> 
>   crypto: caam - properly set IV after {en,de}crypt
>   crypto: caam - fix k*alloc if called from own cipher callback
> 
>  drivers/crypto/caam/caamalg.c | 55 +++++++++++++++++++++++++++++++++++--------
>  1 file changed, 45 insertions(+), 10 deletions(-)
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver
  2017-06-15 14:57 ` Horia Geantă
@ 2017-06-16  7:57   ` Horia Geantă
  2017-06-16  7:59     ` Herbert Xu
  0 siblings, 1 reply; 27+ messages in thread
From: Horia Geantă @ 2017-06-16  7:57 UTC (permalink / raw)
  To: David Gstir, Dan Douglass, herbert, davem, Radu Solea
  Cc: richard, linux-crypto, linux-kernel

On 6/15/2017 5:57 PM, Horia Geantă wrote:
> On 6/2/2017 3:25 PM, David Gstir wrote:
>> Hi!
>>
>> While testing fscrypt's filename encryption, I noticed that the implementation
>> of cts(cbc(aes)) is broken when the CAAM hardware crypto driver is enabled.
>> Some digging showed that the refactoring of crypto/cts.c in v4.8 
>> (commit 0605c41cc53ca) exposed some problems with CAAM's aes-cbc
>> implementation. This can be tested quite easily by loading the tcrypt
>> module with mode=38. Looks like the cts mode is not used very often
>> and this went unnoticed since 4.8...
>>
>> This patch series is an attempt to fix that and get cts(cbc(aes)) working
>> properly again when the CAAM driver is enabled.
>>
> David, thanks for taking time to fix these.
> 
>> Specifically, the issues are:
[snip]
>> 2) The cts implementation uses aes-cbc twice to perform its job. The second
>>    time, it is called from within the callback of the first call to aes-cbc.
>>    This usage is not properly handled in the CAAM driver which triggers the
>>    BUG below.
>>
> Dan, Radu - have you seen this on i.MX?
> 
>>    My current proposal is to use in_interrupt() to detect such cases and set
>>    the k*alloc flags accordingly. However, since using in_interrupt() is not
>>    really nice, I'm wondering if there is a better way to handle this?
>>
> Nothing else crosses my mind right now, but I'd like to sleep on it.
> 
Herbert,

Commit 0605c41cc53ca ("crypto: cts - Convert to skcipher") appends
CRYPTO_TFM_REQ_MAY_BACKLOG to the original crypto request flags for the
last block - when calling cts_cbc_encrypt().
Is it really needed?

For cts(cbc(aes)) with cbc(aes) offloaded in HW, i.e. running in async
mode, we get the below stack for CAAM driver.
Driver is told that it can sleep (CRYPTO_TFM_REQ_MAY_BACKLOG flag), so
it uses GFP_KERNEL to allocate memory. However, this is incorrect, since
driver runs in atomic context (softirq).

I wouldn't say that:
-David's suggestion - adding in_interrupt()
- or in general: trying to detect in CAAM driver whether we are in
atomic context using anything else than what crypto API provides
(MAY_BACKLOG, MAY_SLEEP flags)

is something we want to do.
IIUC, in general caller (cts / crypto API) is responsible for telling
the callee if it will run in atomic context or not:
https://lwn.net/Articles/274695/

Thanks,
Horia

>> <snip>
>> [  126.252543] BUG: sleeping function called from invalid context at mm/slab.h:432
>> [  126.260099] in_atomic(): 1, irqs_disabled(): 0, pid: 0, name: swapper/0
>> [  126.266837] no locks held by swapper/0/0.
>> [  126.270969] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.12.0-rc3-00052-g0ddec680d395 #287
>> [  126.279226] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
>> [  126.285821] Backtrace:
>> [  126.288406] [<c010c3e4>] (dump_backtrace) from [<c010c690>] (show_stack+0x18/0x1c)
>> [  126.296057]  r7:00000000 r6:60000113 r5:00000000 r4:c102ab48
>> [  126.301798] [<c010c678>] (show_stack) from [<c0427060>] (dump_stack+0xb4/0xe8)
>> [  126.309106] [<c0426fac>] (dump_stack) from [<c014f020>] (___might_sleep+0x17c/0x2a0)
>> [  126.316929]  r9:00000000 r8:c0a016dc r7:c101ee3e r6:000001b0 r5:c0c12fac r4:ffffe000
>> [  126.324751] [<c014eea4>] (___might_sleep) from [<c014f1a8>] (__might_sleep+0x64/0xa4)
>> [  126.332655]  r7:014080c1 r6:00000000 r5:000001b0 r4:c0c12fac
>> [  126.338397] [<c014f144>] (__might_sleep) from [<c0224a20>] (__kmalloc+0x130/0x1b8)
>> [  126.346039]  r6:c071a8ec r5:014080c1 r4:eec01e00
>> [  126.350742] [<c02248f0>] (__kmalloc) from [<c071a8ec>] (ablkcipher_edesc_alloc.constprop.1+0x200/0x900)
>> [  126.360213]  r10:00000000 r9:00000000 r8:c0a016dc r7:c0a016dc r6:ee05ac10 r5:edfdaec0
>> [  126.368109]  r4:00000001 r3:00000020
>> [  126.371765] [<c071a6ec>] (ablkcipher_edesc_alloc.constprop.1) from [<c071b010>] (ablkcipher_encrypt+0x24/0x9c)
>> [  126.381843]  r10:00000000 r9:00000020 r8:00000001 r7:ee05ac10 r6:ed597000 r5:edfdaec0
>> [  126.389738]  r4:ed475d08
>> [  126.392354] [<c071afec>] (ablkcipher_encrypt) from [<c03d6f20>] (skcipher_encrypt_ablkcipher+0x68/0x6c)
>> [  126.401822]  r7:ed475d08 r6:ed597000 r5:00000400 r4:ed475d08
>> [  126.407566] [<c03d6eb8>] (skcipher_encrypt_ablkcipher) from [<c03e8a70>] (cts_cbc_encrypt+0x118/0x124)
>> [  126.416947]  r7:ed475d08 r6:c1001cc0 r5:00000010 r4:edfdae00
>> [  126.422686] [<c03e8958>] (cts_cbc_encrypt) from [<c03e8b88>] (crypto_cts_encrypt_done+0x20/0x54)
>> [  126.431548]  r10:00000000 r9:ee05ac10 r8:00000000 r7:00000010 r6:edc8e6c0 r5:edc8e6d8
>> [  126.439443]  r4:edfdae00
>> [  126.442056] [<c03e8b68>] (crypto_cts_encrypt_done) from [<c07195a0>] (ablkcipher_encrypt_done+0x88/0x9c)
>> [  126.445180] fec 2188000.ethernet eth0: MDIO read timeout
>> [  126.456948]  r5:edc8e6d8 r4:edfdaec0
>> [  126.460604] [<c0719518>] (ablkcipher_encrypt_done) from [<c0715ca0>] (caam_jr_dequeue+0x214/0x2d4)
>> [  126.469639]  r9:00000001 r8:ee088010 r7:000001ff r6:00000001 r5:00000000 r4:edfdaec0
>> [  126.477467] [<c0715a8c>] (caam_jr_dequeue) from [<c012b3f0>] (tasklet_action+0x98/0x154)
>> [  126.485160] fec 2188000.ethernet eth0: MDIO read timeout
>> [  126.490975]  r10:c1080b80 r9:c1008b84 r8:00000000 r7:c1000000 r6:00000000 r5:ee088028
>> [  126.498870]  r4:ee088024
>> [  126.501484] [<c012b358>] (tasklet_action) from [<c012b60c>] (__do_softirq+0xf0/0x2a4)
>> [  126.509390]  r10:40000006 r9:c1002080 r8:00000101 r7:c1002098 r6:c1000000 r5:00000006
>> [  126.517285]  r4:00000000
>> [  126.519896] [<c012b51c>] (__do_softirq) from [<c012bb90>] (irq_exit+0xec/0x168)
>> [  126.525127] fec 2188000.ethernet eth0: MDIO write timeout
>> [  126.532709]  r10:c1008cf0 r9:eec08400 r8:00000001 r7:00000000 r6:c1008b84 r5:00000000
>> [  126.540603]  r4:c0fd940c
>> [  126.543222] [<c012baa4>] (irq_exit) from [<c017ff24>] (__handle_domain_irq+0x74/0xe8)
>> [  126.551135] [<c017feb0>] (__handle_domain_irq) from [<c01015fc>] (gic_handle_irq+0x58/0xbc)
>> [  126.559564]  r9:f4000100 r8:c102af80 r7:c1001ea8 r6:000003ff r5:000003eb r4:f400010c
>> [  126.567384] [<c01015a4>] (gic_handle_irq) from [<c010d2f0>] (__irq_svc+0x70/0x98)
>> [  126.574937] Exception stack(0xc1001ea8 to 0xc1001ef0)
>> [  126.580065] 1ea0:                   00000001 2e39a000 00000000 c100c080 00000000 ef374698
>> [  126.588320] 1ec0: 653b20b1 0000001d 653afed6 0000001d 00000000 c1001f24 c1001ec8 c1001ef8
>> [  126.596568] 1ee0: c016fcf4 c06f1fbc 20000013 ffffffff
>> [  126.601696]  r10:00000000 r9:c1000000 r8:653afed6 r7:c1001edc r6:ffffffff r5:20000013
>> [  126.609591]  r4:c06f1fbc
>> [  126.612210] [<c06f1e34>] (cpuidle_enter_state) from [<c06f2120>] (cpuidle_enter+0x1c/0x20)
>> [  126.620551]  r10:c100f8c0 r9:ef374698 r8:c1008b84 r7:c0fda690 r6:c10089ec r5:c1008a38
>> [  126.628448]  r4:c1000000 r3:ef374698
>> [  126.632114] [<c06f2104>] (cpuidle_enter) from [<c0167330>] (call_cpuidle+0x28/0x44)
>> [  126.639859] [<c0167308>] (call_cpuidle) from [<c0167608>] (do_idle+0x1ac/0x220)
>> [  126.647249] [<c016745c>] (do_idle) from [<c0167a20>] (cpu_startup_entry+0x20/0x24)
>> [  126.654895]  r10:c0e60a50 r9:efffc940 r8:c1080000 r7:c10089c0 r6:c1080000 r5:00000002
>> [  126.662793]  r4:000000bd r3:c0e733c4
>> [  126.666457] [<c0167a00>] (cpu_startup_entry) from [<c09cfbd4>] (rest_init+0x154/0x198)
>> [  126.674463] [<c09cfa80>] (rest_init) from [<c0e00cf0>] (start_kernel+0x344/0x3b8)
>> [  126.682015]  r5:ffffffff r4:c108004c
>> [  126.685668] [<c0e009ac>] (start_kernel) from [<1000807c>] (0x1000807c)
>> </snip>
>>
>>   crypto: caam - properly set IV after {en,de}crypt
>>   crypto: caam - fix k*alloc if called from own cipher callback
>>
>>  drivers/crypto/caam/caamalg.c | 55 +++++++++++++++++++++++++++++++++++--------
>>  1 file changed, 45 insertions(+), 10 deletions(-)
>>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver
  2017-06-16  7:57   ` Horia Geantă
@ 2017-06-16  7:59     ` Herbert Xu
  2017-06-16 21:01       ` Horia Geantă
  0 siblings, 1 reply; 27+ messages in thread
From: Herbert Xu @ 2017-06-16  7:59 UTC (permalink / raw)
  To: Horia Geantă
  Cc: David Gstir, Dan Douglass, davem, Radu Solea, richard,
	linux-crypto, linux-kernel

On Fri, Jun 16, 2017 at 07:57:00AM +0000, Horia Geantă wrote:
>
> Commit 0605c41cc53ca ("crypto: cts - Convert to skcipher") appends
> CRYPTO_TFM_REQ_MAY_BACKLOG to the original crypto request flags for the
> last block - when calling cts_cbc_encrypt().
> Is it really needed?

Yes, because at this point we cannot tell the sender to back off.

> For cts(cbc(aes)) with cbc(aes) offloaded in HW, i.e. running in async
> mode, we get the below stack for CAAM driver.
> Driver is told that it can sleep (CRYPTO_TFM_REQ_MAY_BACKLOG flag), so
> it uses GFP_KERNEL to allocate memory. However, this is incorrect, since
> driver runs in atomic context (softirq).

This is wrong.  Whether you can sleep or not is determined by
MAY_SLEEP, not MAY_BACKLOG.  MAY_BACKLOG only indicates that this
request must be queued, even if the queue is full.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver
  2017-06-16  7:59     ` Herbert Xu
@ 2017-06-16 21:01       ` Horia Geantă
  2017-06-17  9:05         ` David Gstir
  0 siblings, 1 reply; 27+ messages in thread
From: Horia Geantă @ 2017-06-16 21:01 UTC (permalink / raw)
  To: Herbert Xu
  Cc: David Gstir, Dan Douglass, davem, Radu Solea, richard,
	linux-crypto, linux-kernel

On 6/16/2017 11:00 AM, Herbert Xu wrote:
> On Fri, Jun 16, 2017 at 07:57:00AM +0000, Horia Geantă wrote:
>>
>> Commit 0605c41cc53ca ("crypto: cts - Convert to skcipher") appends
>> CRYPTO_TFM_REQ_MAY_BACKLOG to the original crypto request flags for the
>> last block - when calling cts_cbc_encrypt().
>> Is it really needed?
> 
> Yes, because at this point we cannot tell the sender to back off.
> 
>> For cts(cbc(aes)) with cbc(aes) offloaded in HW, i.e. running in async
>> mode, we get the below stack for CAAM driver.
>> Driver is told that it can sleep (CRYPTO_TFM_REQ_MAY_BACKLOG flag), so
>> it uses GFP_KERNEL to allocate memory. However, this is incorrect, since
>> driver runs in atomic context (softirq).
> 
> This is wrong.  Whether you can sleep or not is determined by
> MAY_SLEEP, not MAY_BACKLOG.  MAY_BACKLOG only indicates that this
> request must be queued, even if the queue is full.
> 
Indeed, CAAM driver incorrectly decides to use GFP_KERNEL for allocation
when MAY_BACKLOG flag is set. This seems to be a long-standing issue, I
will send a fix (separately).

Still I think we have a problem.
David reported that the user is fscrypt. Looking into fscrypt code, I
see that besides MAY_BACKLOG, MAY_SLEEP flag is also set. So we end up
in the situation I described earlier: the last block is encrypted in
atomic context and with MAY_SLEEP set.

Thanks,
Horia

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver
  2017-06-16 21:01       ` Horia Geantă
@ 2017-06-17  9:05         ` David Gstir
  2017-06-19  8:44           ` [PATCH 1/2] crypto: caam - fix gfp allocation flags (part I) Horia Geantă
  0 siblings, 1 reply; 27+ messages in thread
From: David Gstir @ 2017-06-17  9:05 UTC (permalink / raw)
  To: Horia Geantă
  Cc: Herbert Xu, Dan Douglass, davem, Radu Solea, richard,
	linux-crypto, linux-kernel

Horia,

> On 16 Jun 2017, at 23:01, Horia Geantă <horia.geanta@nxp.com> wrote:
> 
> On 6/16/2017 11:00 AM, Herbert Xu wrote:
>> On Fri, Jun 16, 2017 at 07:57:00AM +0000, Horia Geantă wrote:
>>> 
>>> Commit 0605c41cc53ca ("crypto: cts - Convert to skcipher") appends
>>> CRYPTO_TFM_REQ_MAY_BACKLOG to the original crypto request flags for the
>>> last block - when calling cts_cbc_encrypt().
>>> Is it really needed?
>> 
>> Yes, because at this point we cannot tell the sender to back off.
>> 
>>> For cts(cbc(aes)) with cbc(aes) offloaded in HW, i.e. running in async
>>> mode, we get the below stack for CAAM driver.
>>> Driver is told that it can sleep (CRYPTO_TFM_REQ_MAY_BACKLOG flag), so
>>> it uses GFP_KERNEL to allocate memory. However, this is incorrect, since
>>> driver runs in atomic context (softirq).
>> 
>> This is wrong.  Whether you can sleep or not is determined by
>> MAY_SLEEP, not MAY_BACKLOG.  MAY_BACKLOG only indicates that this
>> request must be queued, even if the queue is full.
>> 
> Indeed, CAAM driver incorrectly decides to use GFP_KERNEL for allocation
> when MAY_BACKLOG flag is set. This seems to be a long-standing issue, I
> will send a fix (separately).
> 
> Still I think we have a problem.
> David reported that the user is fscrypt. Looking into fscrypt code, I
> see that besides MAY_BACKLOG, MAY_SLEEP flag is also set. So we end up
> in the situation I described earlier: the last block is encrypted in
> atomic context and with MAY_SLEEP set.

Fixing the MAY_BACKLOG issue in the CAAM driver should get rid of the problem
altogether since the CTS code clears the MAY_SLEEP flag when encrypting the
last block [1].

David

[1] http://elixir.free-electrons.com/linux/v4.12-rc5/source/crypto/cts.c#L124

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 1/2] crypto: caam - fix gfp allocation flags (part I)
  2017-06-17  9:05         ` David Gstir
@ 2017-06-19  8:44           ` Horia Geantă
  2017-06-19  8:44             ` [PATCH 2/2] crypto: caam - fix gfp allocation flags (part II) Horia Geantă
  2017-06-22  9:00             ` [PATCH 1/2] crypto: caam - fix gfp allocation flags (part I) Herbert Xu
  0 siblings, 2 replies; 27+ messages in thread
From: Horia Geantă @ 2017-06-19  8:44 UTC (permalink / raw)
  To: Herbert Xu, David Gstir
  Cc: David S. Miller, Dan Douglass, richard, Radu Solea, linux-crypto,
	linux-kernel

Changes in the SW cts (ciphertext stealing) code in
commit 0605c41cc53ca ("crypto: cts - Convert to skcipher")
revealed a problem in the CAAM driver:
when cts(cbc(aes)) is executed and cts runs in SW,
cbc(aes) is offloaded in CAAM; cts encrypts the last block
in atomic context and CAAM incorrectly decides to use GFP_KERNEL
for memory allocation.

Fix this by allowing GFP_KERNEL (sleeping) only when MAY_SLEEP flag is
set, i.e. remove MAY_BACKLOG flag.

We split the fix in two parts - first is sent to -stable, while the
second is not (since there is no known failure case).

Link: http://lkml.kernel.org/g/20170602122446.2427-1-david@sigma-star.at
Cc: <stable@vger.kernel.org> # 4.8+
Reported-by: David Gstir <david@sigma-star.at>
Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
---
 drivers/crypto/caam/caamalg.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 398807d1b77e..4ecf92e3b404 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -1475,8 +1475,7 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
 		       GFP_KERNEL : GFP_ATOMIC;
 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
 	struct ablkcipher_edesc *edesc;
-- 
2.12.0.264.gd6db3f216544

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 2/2] crypto: caam - fix gfp allocation flags (part II)
  2017-06-19  8:44           ` [PATCH 1/2] crypto: caam - fix gfp allocation flags (part I) Horia Geantă
@ 2017-06-19  8:44             ` Horia Geantă
  2017-06-22  9:00               ` Herbert Xu
  2017-06-22  9:00             ` [PATCH 1/2] crypto: caam - fix gfp allocation flags (part I) Herbert Xu
  1 sibling, 1 reply; 27+ messages in thread
From: Horia Geantă @ 2017-06-19  8:44 UTC (permalink / raw)
  To: Herbert Xu, David Gstir
  Cc: David S. Miller, Dan Douglass, richard, Radu Solea, linux-crypto,
	linux-kernel

This is the 2nd part of fixing the usage of GFP_KERNEL for memory
allocations, taking care off all the places that haven't caused a real
problem / failure.
Again, the issue being fixed is that GFP_KERNEL should be used only when
MAY_SLEEP flag is set, i.e. MAY_BACKLOG flag usage is orthogonal.

Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
---
 drivers/crypto/caam/caamalg.c    |  7 +++----
 drivers/crypto/caam/caamalg_qi.c | 10 ++++------
 drivers/crypto/caam/caamhash.c   | 32 ++++++++++++++++----------------
 drivers/crypto/caam/caampkc.c    |  4 ++--
 4 files changed, 25 insertions(+), 28 deletions(-)

diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 4ecf92e3b404..fde399c88779 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -1187,8 +1187,8 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
+		       GFP_KERNEL : GFP_ATOMIC;
 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
 	struct aead_edesc *edesc;
 	int sec4_sg_index, sec4_sg_len, sec4_sg_bytes;
@@ -1680,8 +1680,7 @@ static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc(
 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
+	gfp_t flags = (req->base.flags &  CRYPTO_TFM_REQ_MAY_SLEEP) ?
 		       GFP_KERNEL : GFP_ATOMIC;
 	int src_nents, mapped_src_nents, dst_nents, mapped_dst_nents;
 	struct ablkcipher_edesc *edesc;
diff --git a/drivers/crypto/caam/caamalg_qi.c b/drivers/crypto/caam/caamalg_qi.c
index ea0e5b8b9171..78c4c0485c58 100644
--- a/drivers/crypto/caam/caamalg_qi.c
+++ b/drivers/crypto/caam/caamalg_qi.c
@@ -555,8 +555,8 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
 						 typeof(*alg), aead);
 	struct device *qidev = ctx->qidev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
+		       GFP_KERNEL : GFP_ATOMIC;
 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
 	struct aead_edesc *edesc;
 	dma_addr_t qm_sg_dma, iv_dma = 0;
@@ -808,8 +808,7 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
 	struct device *qidev = ctx->qidev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
 		       GFP_KERNEL : GFP_ATOMIC;
 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
 	struct ablkcipher_edesc *edesc;
@@ -953,8 +952,7 @@ static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc(
 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
 	struct device *qidev = ctx->qidev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
 		       GFP_KERNEL : GFP_ATOMIC;
 	int src_nents, mapped_src_nents, dst_nents, mapped_dst_nents;
 	struct ablkcipher_edesc *edesc;
diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index da4f94eab3da..7c44c90ad593 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -719,8 +719,8 @@ static int ahash_update_ctx(struct ahash_request *req)
 	struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
 	struct caam_hash_state *state = ahash_request_ctx(req);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
+		       GFP_KERNEL : GFP_ATOMIC;
 	u8 *buf = current_buf(state);
 	int *buflen = current_buflen(state);
 	u8 *next_buf = alt_buf(state);
@@ -849,8 +849,8 @@ static int ahash_final_ctx(struct ahash_request *req)
 	struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
 	struct caam_hash_state *state = ahash_request_ctx(req);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
+		       GFP_KERNEL : GFP_ATOMIC;
 	int buflen = *current_buflen(state);
 	u32 *desc;
 	int sec4_sg_bytes, sec4_sg_src_index;
@@ -926,8 +926,8 @@ static int ahash_finup_ctx(struct ahash_request *req)
 	struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
 	struct caam_hash_state *state = ahash_request_ctx(req);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
+		       GFP_KERNEL : GFP_ATOMIC;
 	int buflen = *current_buflen(state);
 	u32 *desc;
 	int sec4_sg_src_index;
@@ -1013,8 +1013,8 @@ static int ahash_digest(struct ahash_request *req)
 	struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
 	struct caam_hash_state *state = ahash_request_ctx(req);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
+		       GFP_KERNEL : GFP_ATOMIC;
 	u32 *desc;
 	int digestsize = crypto_ahash_digestsize(ahash);
 	int src_nents, mapped_nents;
@@ -1093,8 +1093,8 @@ static int ahash_final_no_ctx(struct ahash_request *req)
 	struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
 	struct caam_hash_state *state = ahash_request_ctx(req);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
+		       GFP_KERNEL : GFP_ATOMIC;
 	u8 *buf = current_buf(state);
 	int buflen = *current_buflen(state);
 	u32 *desc;
@@ -1154,8 +1154,8 @@ static int ahash_update_no_ctx(struct ahash_request *req)
 	struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
 	struct caam_hash_state *state = ahash_request_ctx(req);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
+		       GFP_KERNEL : GFP_ATOMIC;
 	u8 *buf = current_buf(state);
 	int *buflen = current_buflen(state);
 	u8 *next_buf = alt_buf(state);
@@ -1280,8 +1280,8 @@ static int ahash_finup_no_ctx(struct ahash_request *req)
 	struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
 	struct caam_hash_state *state = ahash_request_ctx(req);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
+		       GFP_KERNEL : GFP_ATOMIC;
 	int buflen = *current_buflen(state);
 	u32 *desc;
 	int sec4_sg_bytes, sec4_sg_src_index, src_nents, mapped_nents;
@@ -1370,8 +1370,8 @@ static int ahash_update_first(struct ahash_request *req)
 	struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
 	struct caam_hash_state *state = ahash_request_ctx(req);
 	struct device *jrdev = ctx->jrdev;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
+		       GFP_KERNEL : GFP_ATOMIC;
 	u8 *next_buf = alt_buf(state);
 	int *next_buflen = alt_buflen(state);
 	int to_hash;
diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c
index 9c508ba6b0f1..7a897209f181 100644
--- a/drivers/crypto/caam/caampkc.c
+++ b/drivers/crypto/caam/caampkc.c
@@ -173,8 +173,8 @@ static struct rsa_edesc *rsa_edesc_alloc(struct akcipher_request *req,
 	struct caam_rsa_ctx *ctx = akcipher_tfm_ctx(tfm);
 	struct device *dev = ctx->dev;
 	struct rsa_edesc *edesc;
-	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
-		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
+	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
+		       GFP_KERNEL : GFP_ATOMIC;
 	int sgc;
 	int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes;
 	int src_nents, dst_nents;
-- 
2.12.0.264.gd6db3f216544

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [RFC PATCH 1/2] crypto: caam - properly set IV after {en,de}crypt
  2017-06-02 12:24 ` [RFC PATCH 1/2] crypto: caam - properly set IV after {en,de}crypt David Gstir
@ 2017-06-19 10:31   ` Horia Geantă
  2017-06-20  1:28     ` Herbert Xu
  2017-06-28  8:32     ` Horia Geantă
  0 siblings, 2 replies; 27+ messages in thread
From: Horia Geantă @ 2017-06-19 10:31 UTC (permalink / raw)
  To: David Gstir, Dan Douglass, herbert, davem
  Cc: richard, linux-crypto, linux-kernel

On 6/2/2017 3:25 PM, David Gstir wrote:
> Certain cipher modes like CTS expect the IV (req->info) of
> ablkcipher_request (or equivalently req->iv of skcipher_request) to
> contain the last ciphertext block when the {en,de}crypt operation is done.
> This is currently not the case for the CAAM driver which in turn breaks
> e.g. cts(cbc(aes)) when the CAAM driver is enabled.
> 
> This patch fixes the CAAM driver to properly set the IV after the
> {en,de}crypt operation of ablkcipher finishes.
> 
> Signed-off-by: David Gstir <david@sigma-star.at>
> ---
>  drivers/crypto/caam/caamalg.c | 26 ++++++++++++++++++++++++--
>  1 file changed, 24 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
> index 398807d1b77e..d13c1aee4427 100644
> --- a/drivers/crypto/caam/caamalg.c
> +++ b/drivers/crypto/caam/caamalg.c
> @@ -882,10 +882,11 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
>  {
>  	struct ablkcipher_request *req = context;
>  	struct ablkcipher_edesc *edesc;
> -#ifdef DEBUG
>  	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
>  	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
> +	int nents;
>  
> +#ifdef DEBUG
>  	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
>  #endif
>  
> @@ -904,6 +905,19 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
>  #endif
>  
>  	ablkcipher_unmap(jrdev, edesc, req);
> +
> +	if (req->src == req->dst)
> +		nents = edesc->src_nents;
> +	else
> +		nents = edesc->dst_nents;
> +
> +	/*
> +	 * The crypto API expects us to set the IV (req->info) to the last
> +	 * ciphertext block. This is used e.g. by the CTS mode.
> +	 */

IIUC, IV update is required only in case of CBC.
Since this callback is used also for CTR, we should avoid the copy:
if ((ctx->cdata.algtype & OP_ALG_AAI_MASK) == OP_ALG_AAI_CBC) ...

> +	sg_pcopy_to_buffer(req->dst, nents, req->info, ivsize,
> +			   req->nbytes - ivsize);

scatterwalk_map_and_copy() should be used instead.

> +
>  	kfree(edesc);
>  
>  	ablkcipher_request_complete(req, err);
> @@ -914,10 +928,10 @@ static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
>  {
>  	struct ablkcipher_request *req = context;
>  	struct ablkcipher_edesc *edesc;
> -#ifdef DEBUG
>  	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
>  	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
>  
> +#ifdef DEBUG
>  	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
>  #endif
>  
> @@ -935,6 +949,14 @@ static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
>  #endif
>  
>  	ablkcipher_unmap(jrdev, edesc, req);
> +
> +	/*
> +	 * The crypto API expects us to set the IV (req->info) to the last
> +	 * ciphertext block.
> +	 */
> +	sg_pcopy_to_buffer(req->src, edesc->src_nents, req->info, ivsize,
> +			   req->nbytes - ivsize);
> +
>  	kfree(edesc);
>  
>  	ablkcipher_request_complete(req, err);
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC PATCH 1/2] crypto: caam - properly set IV after {en,de}crypt
  2017-06-19 10:31   ` Horia Geantă
@ 2017-06-20  1:28     ` Herbert Xu
  2017-06-26  5:40       ` David Gstir
  2017-06-28  8:32     ` Horia Geantă
  1 sibling, 1 reply; 27+ messages in thread
From: Herbert Xu @ 2017-06-20  1:28 UTC (permalink / raw)
  To: Horia Geantă
  Cc: David Gstir, Dan Douglass, davem, richard, linux-crypto, linux-kernel

On Mon, Jun 19, 2017 at 10:31:27AM +0000, Horia Geantă wrote:
>
> IIUC, IV update is required only in case of CBC.
> Since this callback is used also for CTR, we should avoid the copy:
> if ((ctx->cdata.algtype & OP_ALG_AAI_MASK) == OP_ALG_AAI_CBC) ...

No it is needed for CTR too.

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 1/2] crypto: caam - fix gfp allocation flags (part I)
  2017-06-19  8:44           ` [PATCH 1/2] crypto: caam - fix gfp allocation flags (part I) Horia Geantă
  2017-06-19  8:44             ` [PATCH 2/2] crypto: caam - fix gfp allocation flags (part II) Horia Geantă
@ 2017-06-22  9:00             ` Herbert Xu
  1 sibling, 0 replies; 27+ messages in thread
From: Herbert Xu @ 2017-06-22  9:00 UTC (permalink / raw)
  To: Horia Geantă
  Cc: David Gstir, David S. Miller, Dan Douglass, richard, Radu Solea,
	linux-crypto, linux-kernel

On Mon, Jun 19, 2017 at 11:44:45AM +0300, Horia Geantă wrote:
> Changes in the SW cts (ciphertext stealing) code in
> commit 0605c41cc53ca ("crypto: cts - Convert to skcipher")
> revealed a problem in the CAAM driver:
> when cts(cbc(aes)) is executed and cts runs in SW,
> cbc(aes) is offloaded in CAAM; cts encrypts the last block
> in atomic context and CAAM incorrectly decides to use GFP_KERNEL
> for memory allocation.
> 
> Fix this by allowing GFP_KERNEL (sleeping) only when MAY_SLEEP flag is
> set, i.e. remove MAY_BACKLOG flag.
> 
> We split the fix in two parts - first is sent to -stable, while the
> second is not (since there is no known failure case).
> 
> Link: http://lkml.kernel.org/g/20170602122446.2427-1-david@sigma-star.at
> Cc: <stable@vger.kernel.org> # 4.8+
> Reported-by: David Gstir <david@sigma-star.at>
> Signed-off-by: Horia Geantă <horia.geanta@nxp.com>

Patch applied.  Thanks.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 2/2] crypto: caam - fix gfp allocation flags (part II)
  2017-06-19  8:44             ` [PATCH 2/2] crypto: caam - fix gfp allocation flags (part II) Horia Geantă
@ 2017-06-22  9:00               ` Herbert Xu
  0 siblings, 0 replies; 27+ messages in thread
From: Herbert Xu @ 2017-06-22  9:00 UTC (permalink / raw)
  To: Horia Geantă
  Cc: David Gstir, David S. Miller, Dan Douglass, richard, Radu Solea,
	linux-crypto, linux-kernel

On Mon, Jun 19, 2017 at 11:44:46AM +0300, Horia Geantă wrote:
> This is the 2nd part of fixing the usage of GFP_KERNEL for memory
> allocations, taking care off all the places that haven't caused a real
> problem / failure.
> Again, the issue being fixed is that GFP_KERNEL should be used only when
> MAY_SLEEP flag is set, i.e. MAY_BACKLOG flag usage is orthogonal.
> 
> Signed-off-by: Horia Geantă <horia.geanta@nxp.com>

Patch applied.  Thanks.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC PATCH 1/2] crypto: caam - properly set IV after {en,de}crypt
  2017-06-20  1:28     ` Herbert Xu
@ 2017-06-26  5:40       ` David Gstir
  2017-06-26  6:47         ` Herbert Xu
  0 siblings, 1 reply; 27+ messages in thread
From: David Gstir @ 2017-06-26  5:40 UTC (permalink / raw)
  To: Herbert Xu
  Cc: Horia Geantă,
	Dan Douglass, davem, richard, linux-crypto, linux-kernel

Herbert,

> On 20 Jun 2017, at 03:28, Herbert Xu <herbert@gondor.apana.org.au> wrote:
> 
> On Mon, Jun 19, 2017 at 10:31:27AM +0000, Horia Geantă wrote:
>> 
>> IIUC, IV update is required only in case of CBC.
>> Since this callback is used also for CTR, we should avoid the copy:
>> if ((ctx->cdata.algtype & OP_ALG_AAI_MASK) == OP_ALG_AAI_CBC) ...
> 
> No it is needed for CTR too.

So, am I correct in assuming that it is required for all modes including AEAD modes like GCM?
In that case I'll include a fix for the CAAM GCM mode too.

Thanks,
David

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC PATCH 1/2] crypto: caam - properly set IV after {en,de}crypt
  2017-06-26  5:40       ` David Gstir
@ 2017-06-26  6:47         ` Herbert Xu
  0 siblings, 0 replies; 27+ messages in thread
From: Herbert Xu @ 2017-06-26  6:47 UTC (permalink / raw)
  To: David Gstir
  Cc: Horia Geantă,
	Dan Douglass, davem, richard, linux-crypto, linux-kernel

On Mon, Jun 26, 2017 at 07:40:58AM +0200, David Gstir wrote:
>
> So, am I correct in assuming that it is required for all modes including AEAD modes like GCM?
> In that case I'll include a fix for the CAAM GCM mode too.

It's only required for skcihper.  As we do not do chunking/streaming
with our AEAD interface it is not required for GCM.
  
Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC PATCH 1/2] crypto: caam - properly set IV after {en,de}crypt
  2017-06-19 10:31   ` Horia Geantă
  2017-06-20  1:28     ` Herbert Xu
@ 2017-06-28  8:32     ` Horia Geantă
  2017-06-28  9:03       ` David Gstir
  1 sibling, 1 reply; 27+ messages in thread
From: Horia Geantă @ 2017-06-28  8:32 UTC (permalink / raw)
  To: David Gstir, Dan Douglass, herbert, davem
  Cc: richard, linux-crypto, linux-kernel

On 6/19/2017 1:31 PM, Horia Geantă wrote:
> On 6/2/2017 3:25 PM, David Gstir wrote:
>> Certain cipher modes like CTS expect the IV (req->info) of
>> ablkcipher_request (or equivalently req->iv of skcipher_request) to
>> contain the last ciphertext block when the {en,de}crypt operation is done.
>> This is currently not the case for the CAAM driver which in turn breaks
>> e.g. cts(cbc(aes)) when the CAAM driver is enabled.
>>
>> This patch fixes the CAAM driver to properly set the IV after the
>> {en,de}crypt operation of ablkcipher finishes.
>>
>> Signed-off-by: David Gstir <david@sigma-star.at>
>> ---
>>  drivers/crypto/caam/caamalg.c | 26 ++++++++++++++++++++++++--
>>  1 file changed, 24 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
>> index 398807d1b77e..d13c1aee4427 100644
>> --- a/drivers/crypto/caam/caamalg.c
>> +++ b/drivers/crypto/caam/caamalg.c
>> @@ -882,10 +882,11 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
>>  {
>>  	struct ablkcipher_request *req = context;
>>  	struct ablkcipher_edesc *edesc;
>> -#ifdef DEBUG
>>  	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
>>  	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
>> +	int nents;
>>  
>> +#ifdef DEBUG
>>  	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
>>  #endif
>>  
>> @@ -904,6 +905,19 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
>>  #endif
[snip]
>> +	sg_pcopy_to_buffer(req->dst, nents, req->info, ivsize,
>> +			   req->nbytes - ivsize);
> 
> scatterwalk_map_and_copy() should be used instead.
> 
David, IIUC this is the only change needed in this patch (applies both
for encryption and decryption, of course).
Will you formally resubmit?

Thanks,
Horia

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFC PATCH 1/2] crypto: caam - properly set IV after {en,de}crypt
  2017-06-28  8:32     ` Horia Geantă
@ 2017-06-28  9:03       ` David Gstir
  0 siblings, 0 replies; 27+ messages in thread
From: David Gstir @ 2017-06-28  9:03 UTC (permalink / raw)
  To: Horia Geantă
  Cc: Dan Douglass, herbert, davem, richard, linux-crypto, linux-kernel

Horia,

> On 28 Jun 2017, at 10:32, Horia Geantă <horia.geanta@nxp.com> wrote:
> 
>>> +	sg_pcopy_to_buffer(req->dst, nents, req->info, ivsize,
>>> +			   req->nbytes - ivsize);
>> 
>> scatterwalk_map_and_copy() should be used instead.
>> 
> David, IIUC this is the only change needed in this patch (applies both
> for encryption and decryption, of course).
> Will you formally resubmit?

Thanks for the reminder. I did not get arround it yet.
Will send the new patch within the next few hours.

Thanks,
David

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH] crypto: caam - properly set IV after {en,de}crypt
  2017-06-02 12:24 [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver David Gstir
                   ` (3 preceding siblings ...)
  2017-06-15 14:57 ` Horia Geantă
@ 2017-06-28 13:27 ` David Gstir
  2017-06-28 13:42   ` Horia Geantă
  2017-07-12 10:51   ` Herbert Xu
  4 siblings, 2 replies; 27+ messages in thread
From: David Gstir @ 2017-06-28 13:27 UTC (permalink / raw)
  To: horia.geanta, dan.douglass, herbert, davem
  Cc: richard, linux-crypto, linux-kernel, David Gstir, stable

Certain cipher modes like CTS expect the IV (req->info) of
ablkcipher_request (or equivalently req->iv of skcipher_request) to
contain the last ciphertext block when the {en,de}crypt operation is done.
This is currently not the case for the CAAM driver which in turn breaks
e.g. cts(cbc(aes)) when the CAAM driver is enabled.

This patch fixes the CAAM driver to properly set the IV after the
{en,de}crypt operation of ablkcipher finishes.

This issue was revealed by the changes in the SW CTS mode in commit
0605c41cc53ca ("crypto: cts - Convert to skcipher")

Cc: <stable@vger.kernel.org> # 4.8+
Signed-off-by: David Gstir <david@sigma-star.at>
---
 drivers/crypto/caam/caamalg.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 398807d1b77e..c45b5bf65254 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -882,10 +882,10 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
 {
 	struct ablkcipher_request *req = context;
 	struct ablkcipher_edesc *edesc;
-#ifdef DEBUG
 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
 
+#ifdef DEBUG
 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 #endif
 
@@ -904,6 +904,14 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
 #endif
 
 	ablkcipher_unmap(jrdev, edesc, req);
+
+	/*
+	 * The crypto API expects us to set the IV (req->info) to the last
+	 * ciphertext block. This is used e.g. by the CTS mode.
+	 */
+	scatterwalk_map_and_copy(req->info, req->dst, req->nbytes - ivsize,
+				 ivsize, 0);
+
 	kfree(edesc);
 
 	ablkcipher_request_complete(req, err);
@@ -914,10 +922,10 @@ static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
 {
 	struct ablkcipher_request *req = context;
 	struct ablkcipher_edesc *edesc;
-#ifdef DEBUG
 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
 
+#ifdef DEBUG
 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
 #endif
 
@@ -935,6 +943,14 @@ static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
 #endif
 
 	ablkcipher_unmap(jrdev, edesc, req);
+
+	/*
+	 * The crypto API expects us to set the IV (req->info) to the last
+	 * ciphertext block.
+	 */
+	scatterwalk_map_and_copy(req->info, req->src, req->nbytes - ivsize,
+				 ivsize, 0);
+
 	kfree(edesc);
 
 	ablkcipher_request_complete(req, err);
-- 
2.12.3

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH] crypto: caam - properly set IV after {en,de}crypt
  2017-06-28 13:27 ` [PATCH] crypto: caam - properly set IV after {en,de}crypt David Gstir
@ 2017-06-28 13:42   ` Horia Geantă
  2017-06-29 10:19     ` Horia Geantă
  2017-07-12 10:51   ` Herbert Xu
  1 sibling, 1 reply; 27+ messages in thread
From: Horia Geantă @ 2017-06-28 13:42 UTC (permalink / raw)
  To: David Gstir, Dan Douglass, herbert, davem
  Cc: richard, linux-crypto, linux-kernel, stable

On 6/28/2017 4:27 PM, David Gstir wrote:
> Certain cipher modes like CTS expect the IV (req->info) of
> ablkcipher_request (or equivalently req->iv of skcipher_request) to
> contain the last ciphertext block when the {en,de}crypt operation is done.
> This is currently not the case for the CAAM driver which in turn breaks
> e.g. cts(cbc(aes)) when the CAAM driver is enabled.
> 
> This patch fixes the CAAM driver to properly set the IV after the
> {en,de}crypt operation of ablkcipher finishes.
> 
> This issue was revealed by the changes in the SW CTS mode in commit
> 0605c41cc53ca ("crypto: cts - Convert to skcipher")
> 
> Cc: <stable@vger.kernel.org> # 4.8+
> Signed-off-by: David Gstir <david@sigma-star.at>
Reviewed-by: Horia Geantă <horia.geanta@nxp.com>

Thanks,
Horia


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] crypto: caam - properly set IV after {en,de}crypt
  2017-06-28 13:42   ` Horia Geantă
@ 2017-06-29 10:19     ` Horia Geantă
  2017-08-14  7:59       ` Gilad Ben-Yossef
  0 siblings, 1 reply; 27+ messages in thread
From: Horia Geantă @ 2017-06-29 10:19 UTC (permalink / raw)
  To: David Gstir, Dan Douglass, herbert, davem
  Cc: richard, linux-crypto, linux-kernel, stable

On 6/28/2017 4:42 PM, Horia Geantă wrote:
> On 6/28/2017 4:27 PM, David Gstir wrote:
>> Certain cipher modes like CTS expect the IV (req->info) of
>> ablkcipher_request (or equivalently req->iv of skcipher_request) to
>> contain the last ciphertext block when the {en,de}crypt operation is done.
>> This is currently not the case for the CAAM driver which in turn breaks
>> e.g. cts(cbc(aes)) when the CAAM driver is enabled.
>>
>> This patch fixes the CAAM driver to properly set the IV after the
>> {en,de}crypt operation of ablkcipher finishes.
>>
>> This issue was revealed by the changes in the SW CTS mode in commit
>> 0605c41cc53ca ("crypto: cts - Convert to skcipher")
>>
>> Cc: <stable@vger.kernel.org> # 4.8+
>> Signed-off-by: David Gstir <david@sigma-star.at>
> Reviewed-by: Horia Geantă <horia.geanta@nxp.com>
> 
Btw, instead of updating the IV in SW, CAAM engine could be programmed
to do it - by saving the Context Register of the AES accelerator.

Unfortunately this would require changes in quite a few places: shared
descriptor, HW S/G generation logic, IV dma (un)mapping and maybe others.

So it's better to have this fix now (which, considering size, is
appropriate for -stable) and later, if needed, offload IV updating in HW.

Regards,
Horia

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] crypto: caam - properly set IV after {en,de}crypt
  2017-06-28 13:27 ` [PATCH] crypto: caam - properly set IV after {en,de}crypt David Gstir
  2017-06-28 13:42   ` Horia Geantă
@ 2017-07-12 10:51   ` Herbert Xu
  1 sibling, 0 replies; 27+ messages in thread
From: Herbert Xu @ 2017-07-12 10:51 UTC (permalink / raw)
  To: David Gstir
  Cc: horia.geanta, dan.douglass, davem, richard, linux-crypto,
	linux-kernel, stable

On Wed, Jun 28, 2017 at 03:27:10PM +0200, David Gstir wrote:
> Certain cipher modes like CTS expect the IV (req->info) of
> ablkcipher_request (or equivalently req->iv of skcipher_request) to
> contain the last ciphertext block when the {en,de}crypt operation is done.
> This is currently not the case for the CAAM driver which in turn breaks
> e.g. cts(cbc(aes)) when the CAAM driver is enabled.
> 
> This patch fixes the CAAM driver to properly set the IV after the
> {en,de}crypt operation of ablkcipher finishes.
> 
> This issue was revealed by the changes in the SW CTS mode in commit
> 0605c41cc53ca ("crypto: cts - Convert to skcipher")
> 
> Cc: <stable@vger.kernel.org> # 4.8+
> Signed-off-by: David Gstir <david@sigma-star.at>

Patch applied.  Thanks.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] crypto: caam - properly set IV after {en,de}crypt
  2017-06-29 10:19     ` Horia Geantă
@ 2017-08-14  7:59       ` Gilad Ben-Yossef
  2017-09-05 15:33         ` Horia Geantă
  0 siblings, 1 reply; 27+ messages in thread
From: Gilad Ben-Yossef @ 2017-08-14  7:59 UTC (permalink / raw)
  To: Horia Geantă
  Cc: David Gstir, Dan Douglass, herbert, davem, richard, linux-crypto,
	linux-kernel, stable

Hi,

On Thu, Jun 29, 2017 at 1:19 PM, Horia Geantă <horia.geanta@nxp.com> wrote:
> On 6/28/2017 4:42 PM, Horia Geantă wrote:
>> On 6/28/2017 4:27 PM, David Gstir wrote:
>>> Certain cipher modes like CTS expect the IV (req->info) of
>>> ablkcipher_request (or equivalently req->iv of skcipher_request) to
>>> contain the last ciphertext block when the {en,de}crypt operation is done.
>>> This is currently not the case for the CAAM driver which in turn breaks
>>> e.g. cts(cbc(aes)) when the CAAM driver is enabled.
>>>
>>> This patch fixes the CAAM driver to properly set the IV after the
>>> {en,de}crypt operation of ablkcipher finishes.
>>>
>>> This issue was revealed by the changes in the SW CTS mode in commit
>>> 0605c41cc53ca ("crypto: cts - Convert to skcipher")
>>>
>>> Cc: <stable@vger.kernel.org> # 4.8+
>>> Signed-off-by: David Gstir <david@sigma-star.at>
>> Reviewed-by: Horia Geantă <horia.geanta@nxp.com>
>>
> Btw, instead of updating the IV in SW, CAAM engine could be programmed
> to do it - by saving the Context Register of the AES accelerator.
>
> Unfortunately this would require changes in quite a few places: shared
> descriptor, HW S/G generation logic, IV dma (un)mapping and maybe others.
>
> So it's better to have this fix now (which, considering size, is
> appropriate for -stable) and later, if needed, offload IV updating in HW.
>

My apologies for reviving this thread from the dead, but doesn't the patch fail
for in-place decryption since we are copying from req->dst after
the operation is done, and therefore it no longer contains the ciphertext?

I'm asking since I ran into a similar issue in the ccree driver and thought
to deploy a similar fix but could not convince myself why this works.

Thanks!
Gilad

-- 
Gilad Ben-Yossef
Chief Coffee Drinker

"If you take a class in large-scale robotics, can you end up in a
situation where the homework eats your dog?"
 -- Jean-Baptiste Queru

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] crypto: caam - properly set IV after {en,de}crypt
  2017-08-14  7:59       ` Gilad Ben-Yossef
@ 2017-09-05 15:33         ` Horia Geantă
  2017-09-06 10:14           ` Gilad Ben-Yossef
  0 siblings, 1 reply; 27+ messages in thread
From: Horia Geantă @ 2017-09-05 15:33 UTC (permalink / raw)
  To: Gilad Ben-Yossef
  Cc: David Gstir, Dan Douglass, herbert, davem, richard, linux-crypto,
	linux-kernel, stable

On 8/14/2017 10:59 AM, Gilad Ben-Yossef wrote:
> Hi,
> 
> On Thu, Jun 29, 2017 at 1:19 PM, Horia Geantă <horia.geanta@nxp.com> wrote:
>> On 6/28/2017 4:42 PM, Horia Geantă wrote:
>>> On 6/28/2017 4:27 PM, David Gstir wrote:
>>>> Certain cipher modes like CTS expect the IV (req->info) of
>>>> ablkcipher_request (or equivalently req->iv of skcipher_request) to
>>>> contain the last ciphertext block when the {en,de}crypt operation is done.
>>>> This is currently not the case for the CAAM driver which in turn breaks
>>>> e.g. cts(cbc(aes)) when the CAAM driver is enabled.
>>>>
>>>> This patch fixes the CAAM driver to properly set the IV after the
>>>> {en,de}crypt operation of ablkcipher finishes.
>>>>
>>>> This issue was revealed by the changes in the SW CTS mode in commit
>>>> 0605c41cc53ca ("crypto: cts - Convert to skcipher")
>>>>
>>>> Cc: <stable@vger.kernel.org> # 4.8+
>>>> Signed-off-by: David Gstir <david@sigma-star.at>
>>> Reviewed-by: Horia Geantă <horia.geanta@nxp.com>
>>>
>> Btw, instead of updating the IV in SW, CAAM engine could be programmed
>> to do it - by saving the Context Register of the AES accelerator.
>>
>> Unfortunately this would require changes in quite a few places: shared
>> descriptor, HW S/G generation logic, IV dma (un)mapping and maybe others.
>>
>> So it's better to have this fix now (which, considering size, is
>> appropriate for -stable) and later, if needed, offload IV updating in HW.
>>
> 
> My apologies for reviving this thread from the dead, but doesn't the patch fail
> for in-place decryption since we are copying from req->dst after
> the operation is done, and therefore it no longer contains the ciphertext?
> 
You are right, thanks! Will follow up with a fix.
Though cts(cbc(aes)) in particular is working, see below.

> I'm asking since I ran into a similar issue in the ccree driver and thought
> to deploy a similar fix but could not convince myself why this works.
> 
IIUC cts(cbc(aes)) in-place decryption (with cbc(aes) offloaded to CAAM
engine) works since SW implementation of cts, when performing the
ciphertext stealing phase in cts_cbc_decrypt() does not use req->iv, but
a previously value, saved before staring decryption in crypto_cts_decrypt():

if (cbc_blocks <= 1)
	memcpy(space, req->iv, bsize);
else
	scatterwalk_map_and_copy(space, req->src, offset - 2 * bsize,
                                 bsize, 0);

Horia

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] crypto: caam - properly set IV after {en,de}crypt
  2017-09-05 15:33         ` Horia Geantă
@ 2017-09-06 10:14           ` Gilad Ben-Yossef
  2017-09-07 10:12             ` Horia Geantă
  0 siblings, 1 reply; 27+ messages in thread
From: Gilad Ben-Yossef @ 2017-09-06 10:14 UTC (permalink / raw)
  To: Horia Geantă
  Cc: David Gstir, Dan Douglass, herbert, davem, richard, linux-crypto,
	linux-kernel, stable

On Tue, Sep 5, 2017 at 6:33 PM, Horia Geantă <horia.geanta@nxp.com> wrote:
> On 8/14/2017 10:59 AM, Gilad Ben-Yossef wrote:
>> Hi,
>>
>> On Thu, Jun 29, 2017 at 1:19 PM, Horia Geantă <horia.geanta@nxp.com> wrote:
>>> On 6/28/2017 4:42 PM, Horia Geantă wrote:
>>>> On 6/28/2017 4:27 PM, David Gstir wrote:
>>>>> Certain cipher modes like CTS expect the IV (req->info) of
>>>>> ablkcipher_request (or equivalently req->iv of skcipher_request) to
>>>>> contain the last ciphertext block when the {en,de}crypt operation is done.
>>>>> This is currently not the case for the CAAM driver which in turn breaks
>>>>> e.g. cts(cbc(aes)) when the CAAM driver is enabled.
>>>>>
>>>>> This patch fixes the CAAM driver to properly set the IV after the
>>>>> {en,de}crypt operation of ablkcipher finishes.
>>>>>
>>>>> This issue was revealed by the changes in the SW CTS mode in commit
>>>>> 0605c41cc53ca ("crypto: cts - Convert to skcipher")
>>>>>
>>>>> Cc: <stable@vger.kernel.org> # 4.8+
>>>>> Signed-off-by: David Gstir <david@sigma-star.at>
>>>> Reviewed-by: Horia Geantă <horia.geanta@nxp.com>
>>>>
>>> Btw, instead of updating the IV in SW, CAAM engine could be programmed
>>> to do it - by saving the Context Register of the AES accelerator.
>>>
>>> Unfortunately this would require changes in quite a few places: shared
>>> descriptor, HW S/G generation logic, IV dma (un)mapping and maybe others.
>>>
>>> So it's better to have this fix now (which, considering size, is
>>> appropriate for -stable) and later, if needed, offload IV updating in HW.
>>>
>>
>> My apologies for reviving this thread from the dead, but doesn't the patch fail
>> for in-place decryption since we are copying from req->dst after
>> the operation is done, and therefore it no longer contains the ciphertext?
>>
> You are right, thanks! Will follow up with a fix.
> Though cts(cbc(aes)) in particular is working, see below.
>
>> I'm asking since I ran into a similar issue in the ccree driver and thought
>> to deploy a similar fix but could not convince myself why this works.
>>
> IIUC cts(cbc(aes)) in-place decryption (with cbc(aes) offloaded to CAAM
> engine) works since SW implementation of cts, when performing the
> ciphertext stealing phase in cts_cbc_decrypt() does not use req->iv, but
> a previously value, saved before staring decryption in crypto_cts_decrypt():
>
> if (cbc_blocks <= 1)
>         memcpy(space, req->iv, bsize);
> else
>         scatterwalk_map_and_copy(space, req->src, offset - 2 * bsize,
>                                  bsize, 0);
>

Is that not a performance bug in software CTS than? I mean all those
transformation
drivers doing that extra copy and possibly malloc and free to save the
data for the info
and than have the CTS implementation ignore that and do its own memory copy?

Gilad
-- 
Gilad Ben-Yossef
Chief Coffee Drinker

"If you take a class in large-scale robotics, can you end up in a
situation where the homework eats your dog?"
 -- Jean-Baptiste Queru

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH] crypto: caam - properly set IV after {en,de}crypt
  2017-09-06 10:14           ` Gilad Ben-Yossef
@ 2017-09-07 10:12             ` Horia Geantă
  0 siblings, 0 replies; 27+ messages in thread
From: Horia Geantă @ 2017-09-07 10:12 UTC (permalink / raw)
  To: Gilad Ben-Yossef
  Cc: David Gstir, Dan Douglass, herbert, davem, richard, linux-crypto,
	linux-kernel, stable

On 9/6/2017 1:14 PM, Gilad Ben-Yossef wrote:
> On Tue, Sep 5, 2017 at 6:33 PM, Horia Geantă <horia.geanta@nxp.com> wrote:
>> On 8/14/2017 10:59 AM, Gilad Ben-Yossef wrote:
>>> Hi,
>>>
>>> On Thu, Jun 29, 2017 at 1:19 PM, Horia Geantă <horia.geanta@nxp.com> wrote:
>>>> On 6/28/2017 4:42 PM, Horia Geantă wrote:
>>>>> On 6/28/2017 4:27 PM, David Gstir wrote:
>>>>>> Certain cipher modes like CTS expect the IV (req->info) of
>>>>>> ablkcipher_request (or equivalently req->iv of skcipher_request) to
>>>>>> contain the last ciphertext block when the {en,de}crypt operation is done.
>>>>>> This is currently not the case for the CAAM driver which in turn breaks
>>>>>> e.g. cts(cbc(aes)) when the CAAM driver is enabled.
>>>>>>
>>>>>> This patch fixes the CAAM driver to properly set the IV after the
>>>>>> {en,de}crypt operation of ablkcipher finishes.
>>>>>>
>>>>>> This issue was revealed by the changes in the SW CTS mode in commit
>>>>>> 0605c41cc53ca ("crypto: cts - Convert to skcipher")
>>>>>>
>>>>>> Cc: <stable@vger.kernel.org> # 4.8+
>>>>>> Signed-off-by: David Gstir <david@sigma-star.at>
>>>>> Reviewed-by: Horia Geantă <horia.geanta@nxp.com>
>>>>>
>>>> Btw, instead of updating the IV in SW, CAAM engine could be programmed
>>>> to do it - by saving the Context Register of the AES accelerator.
>>>>
>>>> Unfortunately this would require changes in quite a few places: shared
>>>> descriptor, HW S/G generation logic, IV dma (un)mapping and maybe others.
>>>>
>>>> So it's better to have this fix now (which, considering size, is
>>>> appropriate for -stable) and later, if needed, offload IV updating in HW.
>>>>
>>>
>>> My apologies for reviving this thread from the dead, but doesn't the patch fail
>>> for in-place decryption since we are copying from req->dst after
>>> the operation is done, and therefore it no longer contains the ciphertext?
>>>
>> You are right, thanks! Will follow up with a fix.
>> Though cts(cbc(aes)) in particular is working, see below.
>>
>>> I'm asking since I ran into a similar issue in the ccree driver and thought
>>> to deploy a similar fix but could not convince myself why this works.
>>>
>> IIUC cts(cbc(aes)) in-place decryption (with cbc(aes) offloaded to CAAM
>> engine) works since SW implementation of cts, when performing the
>> ciphertext stealing phase in cts_cbc_decrypt() does not use req->iv, but
>> a previously value, saved before staring decryption in crypto_cts_decrypt():
>>
>> if (cbc_blocks <= 1)
>>         memcpy(space, req->iv, bsize);
>> else
>>         scatterwalk_map_and_copy(space, req->src, offset - 2 * bsize,
>>                                  bsize, 0);
>>
> 
> Is that not a performance bug in software CTS than? I mean all those
> transformation
> drivers doing that extra copy and possibly malloc and free to save the
> data for the info
> and than have the CTS implementation ignore that and do its own memory copy?
> 
AFAICT, in case cbc_blocks > 1 cts saves the second from last full
block, while underlying cbc subrequest saves the last full block.

Horia

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2017-09-07 10:12 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-02 12:24 [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver David Gstir
2017-06-02 12:24 ` [RFC PATCH 1/2] crypto: caam - properly set IV after {en,de}crypt David Gstir
2017-06-19 10:31   ` Horia Geantă
2017-06-20  1:28     ` Herbert Xu
2017-06-26  5:40       ` David Gstir
2017-06-26  6:47         ` Herbert Xu
2017-06-28  8:32     ` Horia Geantă
2017-06-28  9:03       ` David Gstir
2017-06-02 12:24 ` [RFC PATCH 2/2] crypto: caam - fix k*alloc if called from own cipher callback David Gstir
2017-06-13 11:53 ` [RFC PATCH 0/2] crypto: caam - fix cts(cbc(aes)) with CAAM driver David Gstir
2017-06-15 14:57 ` Horia Geantă
2017-06-16  7:57   ` Horia Geantă
2017-06-16  7:59     ` Herbert Xu
2017-06-16 21:01       ` Horia Geantă
2017-06-17  9:05         ` David Gstir
2017-06-19  8:44           ` [PATCH 1/2] crypto: caam - fix gfp allocation flags (part I) Horia Geantă
2017-06-19  8:44             ` [PATCH 2/2] crypto: caam - fix gfp allocation flags (part II) Horia Geantă
2017-06-22  9:00               ` Herbert Xu
2017-06-22  9:00             ` [PATCH 1/2] crypto: caam - fix gfp allocation flags (part I) Herbert Xu
2017-06-28 13:27 ` [PATCH] crypto: caam - properly set IV after {en,de}crypt David Gstir
2017-06-28 13:42   ` Horia Geantă
2017-06-29 10:19     ` Horia Geantă
2017-08-14  7:59       ` Gilad Ben-Yossef
2017-09-05 15:33         ` Horia Geantă
2017-09-06 10:14           ` Gilad Ben-Yossef
2017-09-07 10:12             ` Horia Geantă
2017-07-12 10:51   ` Herbert Xu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.