Re: [PATCH 2/2] crypto: caam - add Derived Key Protocol (DKP) support

2017-11-23 Thread Horia Geantă
On 11/10/2017 4:34 PM, Horia Geantă wrote:
> Offload split key generation in CAAM engine, using DKP.
> DKP is supported starting with Era 6.
> 
> Note that the way assoclen is transmitted from the job descriptor
> to the shared descriptor changes - DPOVRD register is used instead
> of MATH3 (where available), since DKP protocol thrashes the MATH
> registers.
> 
> Signed-off-by: Horia Geantă 
When CAAM Job Ring platform devices are configured to go through ARM
SMMU, errors are reported:
arm-smmu 500.iommu: Unhandled context fault: fsr=0x402,
iova=0xffef9000, fsynr=0x3, cb=1

This is due to incorrect DMA mapping direction for the buffers where
keys are stored, they have to change from DMA_TO_DEVICE to
DMA_BIDIRECTIONAL - with DKP keys are initially written by CPU and then
overwritten by the crypto engine.

Will follow up with v2 shortly.

Thanks,
Horia


[PATCH 2/2] crypto: caam - add Derived Key Protocol (DKP) support

2017-11-10 Thread Horia Geantă
Offload split key generation in CAAM engine, using DKP.
DKP is supported starting with Era 6.

Note that the way assoclen is transmitted from the job descriptor
to the shared descriptor changes - DPOVRD register is used instead
of MATH3 (where available), since DKP protocol thrashes the MATH
registers.

Signed-off-by: Horia Geantă 
---
 drivers/crypto/caam/caamalg.c  |  52 +--
 drivers/crypto/caam/caamalg_desc.c | 176 ++---
 drivers/crypto/caam/caamalg_desc.h |  10 +--
 drivers/crypto/caam/caamalg_qi.c   |  31 ++-
 drivers/crypto/caam/caamhash.c |  56 
 drivers/crypto/caam/desc.h |  29 ++
 drivers/crypto/caam/desc_constr.h  |  41 +
 drivers/crypto/caam/key_gen.c  |  30 ---
 drivers/crypto/caam/key_gen.h  |  30 +++
 9 files changed, 323 insertions(+), 132 deletions(-)

diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index baa8dd52472d..700dc09b80da 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -118,6 +118,7 @@ static int aead_null_set_sh_desc(struct crypto_aead *aead)
 {
struct caam_ctx *ctx = crypto_aead_ctx(aead);
struct device *jrdev = ctx->jrdev;
+   struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
u32 *desc;
int rem_bytes = CAAM_DESC_BYTES_MAX - AEAD_DESC_JOB_IO_LEN -
ctx->adata.keylen_pad;
@@ -136,7 +137,8 @@ static int aead_null_set_sh_desc(struct crypto_aead *aead)
 
/* aead_encrypt shared descriptor */
desc = ctx->sh_desc_enc;
-   cnstr_shdsc_aead_null_encap(desc, >adata, ctx->authsize);
+   cnstr_shdsc_aead_null_encap(desc, >adata, ctx->authsize,
+   ctrlpriv->era);
dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
   desc_bytes(desc), DMA_TO_DEVICE);
 
@@ -154,7 +156,8 @@ static int aead_null_set_sh_desc(struct crypto_aead *aead)
 
/* aead_decrypt shared descriptor */
desc = ctx->sh_desc_dec;
-   cnstr_shdsc_aead_null_decap(desc, >adata, ctx->authsize);
+   cnstr_shdsc_aead_null_decap(desc, >adata, ctx->authsize,
+   ctrlpriv->era);
dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
   desc_bytes(desc), DMA_TO_DEVICE);
 
@@ -168,6 +171,7 @@ static int aead_set_sh_desc(struct crypto_aead *aead)
unsigned int ivsize = crypto_aead_ivsize(aead);
struct caam_ctx *ctx = crypto_aead_ctx(aead);
struct device *jrdev = ctx->jrdev;
+   struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
u32 ctx1_iv_off = 0;
u32 *desc, *nonce = NULL;
u32 inl_mask;
@@ -234,7 +238,7 @@ static int aead_set_sh_desc(struct crypto_aead *aead)
desc = ctx->sh_desc_enc;
cnstr_shdsc_aead_encap(desc, >cdata, >adata, ivsize,
   ctx->authsize, is_rfc3686, nonce, ctx1_iv_off,
-  false);
+  false, ctrlpriv->era);
dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
   desc_bytes(desc), DMA_TO_DEVICE);
 
@@ -266,7 +270,7 @@ static int aead_set_sh_desc(struct crypto_aead *aead)
desc = ctx->sh_desc_dec;
cnstr_shdsc_aead_decap(desc, >cdata, >adata, ivsize,
   ctx->authsize, alg->caam.geniv, is_rfc3686,
-  nonce, ctx1_iv_off, false);
+  nonce, ctx1_iv_off, false, ctrlpriv->era);
dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
   desc_bytes(desc), DMA_TO_DEVICE);
 
@@ -300,7 +304,7 @@ static int aead_set_sh_desc(struct crypto_aead *aead)
desc = ctx->sh_desc_enc;
cnstr_shdsc_aead_givencap(desc, >cdata, >adata, ivsize,
  ctx->authsize, is_rfc3686, nonce,
- ctx1_iv_off, false);
+ ctx1_iv_off, false, ctrlpriv->era);
dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
   desc_bytes(desc), DMA_TO_DEVICE);
 
@@ -503,6 +507,7 @@ static int aead_setkey(struct crypto_aead *aead,
 {
struct caam_ctx *ctx = crypto_aead_ctx(aead);
struct device *jrdev = ctx->jrdev;
+   struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
struct crypto_authenc_keys keys;
int ret = 0;
 
@@ -517,6 +522,27 @@ static int aead_setkey(struct crypto_aead *aead,
   DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
 #endif
 
+   /*
+* If DKP is supported, use it in the shared descriptor to generate
+* the split key.
+*/
+   if (ctrlpriv->era >= 6) {
+   ctx->adata.keylen = keys.authkeylen;
+