Re: [PATCH] crypto: caam - Add support for hashing export and import functions

2015-10-17 Thread Herbert Xu
On Sat, Oct 17, 2015 at 06:38:23PM +0100, Russell King - ARM Linux wrote:
> On Fri, Oct 16, 2015 at 04:19:33PM -0700, Victoria Milhoan wrote:
> > @@ -1569,6 +1601,10 @@ static int ahash_import(struct ahash_request *req, 
> > const void *in)
> > struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
> > struct caam_hash_state *state = ahash_request_ctx(req);
> >  
> > +   /* Allocate new data buffers to use for this request */
> > +   state->buf_0 = kmalloc(CAAM_MAX_HASH_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
> > +   state->buf_1 = kmalloc(CAAM_MAX_HASH_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
> > +
> 
> I'm really not sure you can do this at all.  What if the previous
> digest calculation prior to the accept() cloning the state was for
> a non-hash-block aligned size of data.  The above will lose that
> state, and produce an incorrect hash result.  Herbert, can you
> confirm please?

Well the patch you're responding to is simply bogus.  It is making
an allocation and then immediately overwriting that pointer value
with memcpy from the imported state.

Thanks,
-- 
Email: Herbert Xu 
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] crypto: caam - Add support for hashing export and import functions

2015-10-17 Thread Russell King - ARM Linux
On Sat, Oct 17, 2015 at 11:52:54AM +0100, Russell King - ARM Linux wrote:
> Now, with that change, and with your change to buf_0/buf_1, I see
> (before the import/export functions are used) several of these errors:
> 
> caam_jr 2101000.jr0: 4501: DECO: desc idx 5: SGT Length Error. The 
> descriptor is trying to read more data than is contained in the SGT table.
> 
> when checking using openssh.  They don't occur when testing with openssl
> performing normal hashes (as per my previously posted script) but only
> with openssh.

The hardware seems to be quite justified in complaining - I've added code
to dump out the scatter list as well:

jobdesc@879: e4bd7c18: b0861c08 3cd29080 f140 34bd7c38  ...<..@.8|.4
jobdesc@879: e4bd7c28: 0068 f840 3ccf3640 0028  h.@.@6.<(...
sg@882: e4bd7c38:  3ccf3640 0028 
sg@882: e4bd7c48:  34bd7300 0006 
sg@882: e4bd7c58:  7528a070 4020 

If I'm interpreting this correctly:

f140 34bd7c38 0068

tells the CAAM to read 0x68 bytes using the scatterlist at 0x34bd7c38.

The scatterlist here contains three entries, which have lengths 0x28,
0x6 and 0x20, which total up to 0x4e bytes, not 0x68.

Now, looking at how the scatterlist is created, I have yet more questions.

1. What's this dma_map_sg_chained() and dma_unmap_sg_chained() stuff?
   What's wrong with just calling dma_map_sg() on the scatterlist, giving
   it the number of entries we want to map?  dma_map_sg() is supposed to
   deal with chained scatterlists, if it doesn't, it's buggy.

2. src_map_to_sec4_sg() fails to check whether dma_map_sg_chained() failed.
   if it failed, we continue anyway, poking invalid addresses into the
   hardware scatterlist, thereby causing memory corruption.

3. __sg_count() - what's going on with this.  This seems to assume that
   scatterlists aren't chained as:

if (!sg_is_last(sg) && (sg + 1)->length == 0)

   sg + 1 may _not_ be sg_next(sg) - and this will walk off the end of
   the array.

4. Is the try_buf_map_to_sec4_sg() call correct?  Shouldn't it be:

@@ -838,7 +838,7 @@ static int ahash_update_ctx(struct ahash_request *req)
state->buf_dma = try_buf_map_to_sec4_sg(jrdev,
edesc->sec4_sg + 1,
buf, state->buf_dma,
-   *next_buflen, *buflen);
+   *buflen, last_buflen);
 
if (src_nents) {
src_map_to_sec4_sg(jrdev, req->src, src_nents,

   Indeed, with this change, my ssh test works, and the DECO errors are
   gone.

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] crypto: caam - Add support for hashing export and import functions

2015-10-17 Thread Russell King - ARM Linux
On Fri, Oct 16, 2015 at 04:19:33PM -0700, Victoria Milhoan wrote:
> @@ -1569,6 +1601,10 @@ static int ahash_import(struct ahash_request *req, 
> const void *in)
>   struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
>   struct caam_hash_state *state = ahash_request_ctx(req);
>  
> + /* Allocate new data buffers to use for this request */
> + state->buf_0 = kmalloc(CAAM_MAX_HASH_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
> + state->buf_1 = kmalloc(CAAM_MAX_HASH_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
> +

I'm really not sure you can do this at all.  What if the previous
digest calculation prior to the accept() cloning the state was for
a non-hash-block aligned size of data.  The above will lose that
state, and produce an incorrect hash result.  Herbert, can you
confirm please?

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] crypto: caam - Add support for hashing export and import functions

2015-10-17 Thread Russell King - ARM Linux
On Fri, Oct 16, 2015 at 04:19:33PM -0700, Victoria Milhoan wrote:
> @@ -1569,6 +1601,10 @@ static int ahash_import(struct ahash_request *req, 
> const void *in)
>   struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
>   struct caam_hash_state *state = ahash_request_ctx(req);
>  
> + /* Allocate new data buffers to use for this request */
> + state->buf_0 = kmalloc(CAAM_MAX_HASH_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
> + state->buf_1 = kmalloc(CAAM_MAX_HASH_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
> +
>   memcpy(ctx, in, sizeof(struct caam_hash_ctx));
>   memcpy(state, in + sizeof(struct caam_hash_ctx),
>  sizeof(struct caam_hash_state));

This is buggy.  You loose the reference to the two buffers you've just
allocated because this memcpy() overwrites it.

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] crypto: caam - Add support for hashing export and import functions

2015-10-17 Thread Russell King - ARM Linux
On Fri, Oct 16, 2015 at 04:19:33PM -0700, Victoria Milhoan wrote:
> @@ -319,7 +319,7 @@ static int ahash_set_sh_desc(struct crypto_ahash *ahash)
>   have_key = OP_ALG_AAI_HMAC_PRECOMP;
>  
>   /* ahash_update shared descriptor */
> - desc = ctx->sh_desc_update;
> + desc = kmalloc(DESC_HASH_MAX_USED_BYTES, GFP_KERNEL | GFP_DMA);

What if kmalloc() fails?  Should this really oops the kernel?  Ditto
for every other kmalloc you've added below.
 
> @@ -1557,6 +1575,20 @@ static int ahash_export(struct ahash_request *req, 
> void *out)
>   struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
>   struct caam_hash_state *state = ahash_request_ctx(req);
>  
> + /*
> +  * Do not export the data buffers. New buffers are
> +  * allocated during import.
> +  */
> + kfree(state->buf_0);
> + kfree(state->buf_1);
> + state->buf_0 = NULL;
> + state->buf_1 = NULL;
> +
> + state->current_buf = 0;
> + state->buf_dma = 0;
> + state->buflen_0 = 0;
> + state->buflen_1 = 0;
> +

So what if I export, and then continue using _this_ context later?

> @@ -1605,6 +1641,8 @@ static struct caam_hash_template driver_hash[] = {
>   .setkey = ahash_setkey,
>   .halg = {
>   .digestsize = SHA1_DIGEST_SIZE,
> + .statesize = sizeof(struct caam_hash_ctx) +
> +  sizeof(struct caam_hash_state),

Much prefer to have a 'struct caam_hash_export_state' thing rather than
litter the code with the knowledge that these two go together.

>   },
>   },
>   .alg_type = OP_ALG_ALGSEL_SHA1,
> @@ -1626,6 +1664,8 @@ static struct caam_hash_template driver_hash[] = {
>   .setkey = ahash_setkey,
>   .halg = {
>   .digestsize = SHA224_DIGEST_SIZE,
> + .statesize = sizeof(struct caam_hash_ctx) +
> +  sizeof(struct caam_hash_state),
>   },
>   },
>   .alg_type = OP_ALG_ALGSEL_SHA224,
> @@ -1647,6 +1687,8 @@ static struct caam_hash_template driver_hash[] = {
>   .setkey = ahash_setkey,
>   .halg = {
>   .digestsize = SHA256_DIGEST_SIZE,
> + .statesize = sizeof(struct caam_hash_ctx) +
> +  sizeof(struct caam_hash_state),
>   },
>   },
>   .alg_type = OP_ALG_ALGSEL_SHA256,
> @@ -1668,6 +1710,8 @@ static struct caam_hash_template driver_hash[] = {
>   .setkey = ahash_setkey,
>   .halg = {
>   .digestsize = SHA384_DIGEST_SIZE,
> + .statesize = sizeof(struct caam_hash_ctx) +
> +  sizeof(struct caam_hash_state),
>   },
>   },
>   .alg_type = OP_ALG_ALGSEL_SHA384,
> @@ -1689,6 +1733,8 @@ static struct caam_hash_template driver_hash[] = {
>   .setkey = ahash_setkey,
>   .halg = {
>   .digestsize = SHA512_DIGEST_SIZE,
> + .statesize = sizeof(struct caam_hash_ctx) +
> +  sizeof(struct caam_hash_state),
>   },
>   },
>   .alg_type = OP_ALG_ALGSEL_SHA512,
> @@ -1710,6 +1756,8 @@ static struct caam_hash_template driver_hash[] = {
>   .setkey = ahash_setkey,
>   .halg = {
>   .digestsize = MD5_DIGEST_SIZE,
> + .statesize = sizeof(struct caam_hash_ctx) +
> +  sizeof(struct caam_hash_state),
>   },
>   },
>   .alg_type = OP_ALG_ALGSEL_MD5,
> @@ -1796,6 +1844,12 @@ static void caam_hash_cra_exit(struct crypto_tfm *tfm)
>   dma_unmap_single(ctx->jrdev, ctx->sh_desc_finup_dma,
>desc_bytes(ctx->sh_desc_finup), DMA_TO_DEVICE);
>  
> + kfree(ctx->sh_desc_update);
> + kfree(ctx->sh_desc_update_first);
> + kfree(ctx->sh_desc_fin);
> + kfree(ctx->sh_desc_digest);
> + kfree(ctx->sh_desc_finup);
> +

What happens to these when ahash_import() overwrites all the context
state?  Doesn't this mean we end up with double-kfree()s ?

Also, did you test this DMA debug enabled?

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org

Re: [PATCH] crypto: caam - Add support for hashing export and import functions

2015-10-17 Thread Russell King - ARM Linux
On Fri, Oct 16, 2015 at 04:19:33PM -0700, Victoria Milhoan wrote:
> @@ -1557,6 +1575,20 @@ static int ahash_export(struct ahash_request *req, 
> void *out)
>   struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
>   struct caam_hash_state *state = ahash_request_ctx(req);
>  
> + /*
> +  * Do not export the data buffers. New buffers are
> +  * allocated during import.
> +  */
> + kfree(state->buf_0);
> + kfree(state->buf_1);
> + state->buf_0 = NULL;
> + state->buf_1 = NULL;
> +
> + state->current_buf = 0;
> + state->buf_dma = 0;
> + state->buflen_0 = 0;
> + state->buflen_1 = 0;
> +
>   memcpy(out, ctx, sizeof(struct caam_hash_ctx));
>   memcpy(out + sizeof(struct caam_hash_ctx), state,
>  sizeof(struct caam_hash_state));
> @@ -1569,6 +1601,10 @@ static int ahash_import(struct ahash_request *req, 
> const void *in)
>   struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
>   struct caam_hash_state *state = ahash_request_ctx(req);
>  
> + /* Allocate new data buffers to use for this request */
> + state->buf_0 = kmalloc(CAAM_MAX_HASH_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
> + state->buf_1 = kmalloc(CAAM_MAX_HASH_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
> +
>   memcpy(ctx, in, sizeof(struct caam_hash_ctx));
>   memcpy(state, in + sizeof(struct caam_hash_ctx),
>  sizeof(struct caam_hash_state));

Why are we even saving and restoring the caam_hash_ctx here?

That comes from: crypto_tfm_ctx(crypto_ahash_tfm(tfm)), which, tracing
that through the inline functions comes out as:

tfm->base.__crt_ctx

tfm comes from: __crypto_ahash_cast(req->base.tfm), where req->base.tfm
is a pointer to struct crypto_ahash's base member.

When a hash is accept()ed, req->base.tfm is copied from the original
socket handle to the new socket handle (see ahash_request_set_tfm(),
called from hash_accept_parent(), which is in turn called from
af_alg_accept() in hash_accept()).  So both the exporting and importing
hashes end up with the same struct caam_hash_ctx.

We can see this if we add debug print:

[156147.994219] ahash_export(ctx=ed087080,state=e2a6e600)
[156147.994257] ahash_import(ctx=ed087080,state=e2a6d600)
[156147.998256] ahash_export(ctx=ed083080,state=e2a6c600)
[156147.998294] ahash_import(ctx=ed083080,state=edb9ee00)
[156147.998659] ahash_export(ctx=ed087080,state=e2a6e600)
[156147.998700] ahash_import(ctx=ed087080,state=e2a6fa00)
[156147.999002] ahash_export(ctx=ed080880,state=e2a6d200)
[156147.999040] ahash_import(ctx=ed080880,state=e2a6d600)

Notice that the state changes between each export and import, but the
context doesn't.

So, I think we can (and should) completely drop the saving and restoring
of context in these functions.

Now, with that change, and with your change to buf_0/buf_1, I see
(before the import/export functions are used) several of these errors:

caam_jr 2101000.jr0: 4501: DECO: desc idx 5: SGT Length Error. The 
descriptor is trying to read more data than is contained in the SGT table.

when checking using openssh.  They don't occur when testing with openssl
performing normal hashes (as per my previously posted script) but only
with openssh.

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] crypto: caam - Add support for hashing export and import functions

2015-10-17 Thread Russell King - ARM Linux
On Sat, Oct 17, 2015 at 06:57:44AM -0700, Victoria Milhoan wrote:
> Correct - this was apparently the wrong patch I pushed out. The one I'm
> actively using has this fixed (this is the only difference). I will make
> this change in v2 after reviewing your other comments.

Thanks Victoria, but please perform the tests I've suggested in one of
my previous emails - merely testing with openssl's built-in tests aren't
sufficient.  Also, openssl is non-obvious with what it's testing,
especially if you're using "openssl speed".  I'm afraid it's a case of
"you don't know what's being tested unless you've read the openssl
source" :(

However, while trying to debug the DECO stuff, I've stumbled across this:

static inline void append_ptr(u32 *desc, dma_addr_t ptr)
{
dma_addr_t *offset = (dma_addr_t *)desc_end(desc);

*offset = ptr;

(*desc) += CAAM_PTR_SZ / CAAM_CMD_SZ;
}

where I think 'desc' points to memory used for the descriptor, which is
read by hardware, correct?

If that's true, why are we using dma_addr_t here?  dma_addr_t can be
either 32-bit or 64-bit depending on the kernel configuration, and I
suspect if this driver is built with dma_addr_t set to 64-bit, things
will go awry.

Also, what endianness are the hardware descriptors?  Are they always
native CPU endian, or are they fixed as little endian?  If they're always
little endian, is there any reason not to use __le32 and cpu_to_le32()/
le32_to_cpu() as appropriate to ensure that it works on big endian
systems?

-- 
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] crypto: caam - Add support for hashing export and import functions

2015-10-17 Thread Victoria Milhoan
On Sat, 17 Oct 2015 10:43:00 +0100
Russell King - ARM Linux  wrote:

> On Fri, Oct 16, 2015 at 04:19:33PM -0700, Victoria Milhoan wrote:
> > @@ -1569,6 +1601,10 @@ static int ahash_import(struct ahash_request *req, 
> > const void *in)
> > struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash);
> > struct caam_hash_state *state = ahash_request_ctx(req);
> >  
> > +   /* Allocate new data buffers to use for this request */
> > +   state->buf_0 = kmalloc(CAAM_MAX_HASH_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
> > +   state->buf_1 = kmalloc(CAAM_MAX_HASH_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
> > +
> > memcpy(ctx, in, sizeof(struct caam_hash_ctx));
> > memcpy(state, in + sizeof(struct caam_hash_ctx),
> >sizeof(struct caam_hash_state));
> 
> This is buggy.  You loose the reference to the two buffers you've just
> allocated because this memcpy() overwrites it.

Correct - this was apparently the wrong patch I pushed out. The one I'm actively
using has this fixed (this is the only difference). I will make this change in
v2 after reviewing your other comments.

> 
> -- 
> FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
> according to speedtest.net.


-- 
Victoria Milhoan 

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


[PATCH] crypto: caam - Add support for hashing export and import functions

2015-10-16 Thread Victoria Milhoan
Add support for the export and import functions used by hashing algorithms
by specifying the size of the data saved/restored. The size of the data is
provided during algorithm registration.

Also, modify the structures saved/restored in order to meet the size limit
of 512 bytes imposed by the the Crypto API.

Signed-off-by: Victoria Milhoan 
---
 drivers/crypto/caam/caamhash.c | 82 ++
 1 file changed, 68 insertions(+), 14 deletions(-)

diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index 9609f66..bb81ab6 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -100,11 +100,11 @@ static struct list_head hash_list;
 /* ahash per-session context */
 struct caam_hash_ctx {
struct device *jrdev;
-   u32 sh_desc_update[DESC_HASH_MAX_USED_LEN];
-   u32 sh_desc_update_first[DESC_HASH_MAX_USED_LEN];
-   u32 sh_desc_fin[DESC_HASH_MAX_USED_LEN];
-   u32 sh_desc_digest[DESC_HASH_MAX_USED_LEN];
-   u32 sh_desc_finup[DESC_HASH_MAX_USED_LEN];
+   u32 *sh_desc_update;
+   u32 *sh_desc_update_first;
+   u32 *sh_desc_fin;
+   u32 *sh_desc_digest;
+   u32 *sh_desc_finup;
dma_addr_t sh_desc_update_dma;
dma_addr_t sh_desc_update_first_dma;
dma_addr_t sh_desc_fin_dma;
@@ -123,9 +123,9 @@ struct caam_hash_ctx {
 struct caam_hash_state {
dma_addr_t buf_dma;
dma_addr_t ctx_dma;
-   u8 buf_0[CAAM_MAX_HASH_BLOCK_SIZE] cacheline_aligned;
+   u8 *buf_0;
int buflen_0;
-   u8 buf_1[CAAM_MAX_HASH_BLOCK_SIZE] cacheline_aligned;
+   u8 *buf_1;
int buflen_1;
u8 caam_ctx[MAX_CTX_LEN] cacheline_aligned;
int (*update)(struct ahash_request *req);
@@ -319,7 +319,7 @@ static int ahash_set_sh_desc(struct crypto_ahash *ahash)
have_key = OP_ALG_AAI_HMAC_PRECOMP;
 
/* ahash_update shared descriptor */
-   desc = ctx->sh_desc_update;
+   desc = kmalloc(DESC_HASH_MAX_USED_BYTES, GFP_KERNEL | GFP_DMA);
 
init_sh_desc(desc, HDR_SHARE_SERIAL);
 
@@ -334,6 +334,7 @@ static int ahash_set_sh_desc(struct crypto_ahash *ahash)
/* Load data and write to result or context */
ahash_append_load_str(desc, ctx->ctx_len);
 
+   ctx->sh_desc_update = desc;
ctx->sh_desc_update_dma = dma_map_single(jrdev, desc, desc_bytes(desc),
 DMA_TO_DEVICE);
if (dma_mapping_error(jrdev, ctx->sh_desc_update_dma)) {
@@ -347,11 +348,12 @@ static int ahash_set_sh_desc(struct crypto_ahash *ahash)
 #endif
 
/* ahash_update_first shared descriptor */
-   desc = ctx->sh_desc_update_first;
+   desc = kmalloc(DESC_HASH_MAX_USED_BYTES, GFP_KERNEL | GFP_DMA);
 
ahash_data_to_out(desc, have_key | ctx->alg_type, OP_ALG_AS_INIT,
  ctx->ctx_len, ctx);
 
+   ctx->sh_desc_update_first = desc;
ctx->sh_desc_update_first_dma = dma_map_single(jrdev, desc,
   desc_bytes(desc),
   DMA_TO_DEVICE);
@@ -366,11 +368,12 @@ static int ahash_set_sh_desc(struct crypto_ahash *ahash)
 #endif
 
/* ahash_final shared descriptor */
-   desc = ctx->sh_desc_fin;
+   desc = kmalloc(DESC_HASH_MAX_USED_BYTES, GFP_KERNEL | GFP_DMA);
 
ahash_ctx_data_to_out(desc, have_key | ctx->alg_type,
  OP_ALG_AS_FINALIZE, digestsize, ctx);
 
+   ctx->sh_desc_fin = desc;
ctx->sh_desc_fin_dma = dma_map_single(jrdev, desc, desc_bytes(desc),
  DMA_TO_DEVICE);
if (dma_mapping_error(jrdev, ctx->sh_desc_fin_dma)) {
@@ -384,11 +387,12 @@ static int ahash_set_sh_desc(struct crypto_ahash *ahash)
 #endif
 
/* ahash_finup shared descriptor */
-   desc = ctx->sh_desc_finup;
+   desc = kmalloc(DESC_HASH_MAX_USED_BYTES, GFP_KERNEL | GFP_DMA);
 
ahash_ctx_data_to_out(desc, have_key | ctx->alg_type,
  OP_ALG_AS_FINALIZE, digestsize, ctx);
 
+   ctx->sh_desc_finup = desc;
ctx->sh_desc_finup_dma = dma_map_single(jrdev, desc, desc_bytes(desc),
DMA_TO_DEVICE);
if (dma_mapping_error(jrdev, ctx->sh_desc_finup_dma)) {
@@ -402,11 +406,12 @@ static int ahash_set_sh_desc(struct crypto_ahash *ahash)
 #endif
 
/* ahash_digest shared descriptor */
-   desc = ctx->sh_desc_digest;
+   desc = kmalloc(DESC_HASH_MAX_USED_BYTES, GFP_KERNEL | GFP_DMA);
 
ahash_data_to_out(desc, have_key | ctx->alg_type, OP_ALG_AS_INITFINAL,
  digestsize, ctx);
 
+   ctx->sh_desc_digest = desc;
ctx->sh_desc_digest_dma = dma_map_single(jrdev, desc,
 desc_bytes(desc),