From 75d7b3008fca8f98937573795e62aad3a4cb43d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Horia=20Geant=C4=83?= Date: Tue, 7 Nov 2017 17:25:16 +0200 Subject: crypto: caam/qi - add DKP support for tls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add DKP support for tls using caam/qi as backend. Signed-off-by: Horia Geantă diff --git a/drivers/crypto/caam/caamalg_desc.c b/drivers/crypto/caam/caamalg_desc.c index 6a7769e..8795ebd 100644 --- a/drivers/crypto/caam/caamalg_desc.c +++ b/drivers/crypto/caam/caamalg_desc.c @@ -626,19 +626,20 @@ EXPORT_SYMBOL(cnstr_shdsc_aead_givencap); * @cdata: pointer to block cipher transform definitions * Valid algorithm values - one of OP_ALG_ALGSEL_AES ANDed * with OP_ALG_AAI_CBC - * @adata: pointer to authentication transform definitions. Note that since a - * split key is to be used, the size of the split key itself is - * specified. Valid algorithm values OP_ALG_ALGSEL_SHA1 ANDed with - * OP_ALG_AAI_HMAC_PRECOMP. + * @adata: pointer to authentication transform definitions. + * A split key is required for SEC Era < 6; the size of the split key + * is specified in this case. Valid algorithm values OP_ALG_ALGSEL_SHA1 + * ANDed with OP_ALG_AAI_HMAC_PRECOMP. * @assoclen: associated data length * @ivsize: initialization vector size * @authsize: authentication data size * @blocksize: block cipher size + * @era: SEC Era */ void cnstr_shdsc_tls_encap(u32 * const desc, struct alginfo *cdata, struct alginfo *adata, unsigned int assoclen, unsigned int ivsize, unsigned int authsize, - unsigned int blocksize) + unsigned int blocksize, int era) { u32 *key_jump_cmd, *zero_payload_jump_cmd; u32 genpad, idx_ld_datasz, idx_ld_pad, stidx; @@ -666,13 +667,18 @@ void cnstr_shdsc_tls_encap(u32 * const desc, struct alginfo *cdata, key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_SHRD); - if (adata->key_inline) - append_key_as_imm(desc, adata->key_virt, adata->keylen_pad, - adata->keylen, CLASS_2 | KEY_DEST_MDHA_SPLIT | - KEY_ENC); - else - append_key(desc, adata->key_dma, adata->keylen, CLASS_2 | - KEY_DEST_MDHA_SPLIT | KEY_ENC); + if (era < 6) { + if (adata->key_inline) + append_key_as_imm(desc, adata->key_virt, + adata->keylen_pad, adata->keylen, + CLASS_2 | KEY_DEST_MDHA_SPLIT | + KEY_ENC); + else + append_key(desc, adata->key_dma, adata->keylen, + CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC); + } else { + append_proto_dkp(desc, adata); + } if (cdata->key_inline) append_key_as_imm(desc, cdata->key_virt, cdata->keylen, @@ -779,19 +785,20 @@ EXPORT_SYMBOL(cnstr_shdsc_tls_encap); * @cdata: pointer to block cipher transform definitions * Valid algorithm values - one of OP_ALG_ALGSEL_AES ANDed * with OP_ALG_AAI_CBC - * @adata: pointer to authentication transform definitions. Note that since a - * split key is to be used, the size of the split key itself is - * specified. Valid algorithm values OP_ALG_ALGSEL_ SHA1 ANDed with - * OP_ALG_AAI_HMAC_PRECOMP. + * @adata: pointer to authentication transform definitions. + * A split key is required for SEC Era < 6; the size of the split key + * is specified in this case. Valid algorithm values OP_ALG_ALGSEL_SHA1 + * ANDed with OP_ALG_AAI_HMAC_PRECOMP. * @assoclen: associated data length * @ivsize: initialization vector size * @authsize: authentication data size * @blocksize: block cipher size + * @era: SEC Era */ void cnstr_shdsc_tls_decap(u32 * const desc, struct alginfo *cdata, struct alginfo *adata, unsigned int assoclen, unsigned int ivsize, unsigned int authsize, - unsigned int blocksize) + unsigned int blocksize, int era) { u32 stidx, jumpback; u32 *key_jump_cmd, *zero_payload_jump_cmd, *skip_zero_jump_cmd; @@ -809,8 +816,11 @@ void cnstr_shdsc_tls_decap(u32 * const desc, struct alginfo *cdata, key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_SHRD); - append_key(desc, adata->key_dma, adata->keylen, CLASS_2 | - KEY_DEST_MDHA_SPLIT | KEY_ENC); + if (era < 6) + append_key(desc, adata->key_dma, adata->keylen, CLASS_2 | + KEY_DEST_MDHA_SPLIT | KEY_ENC); + else + append_proto_dkp(desc, adata); append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG); diff --git a/drivers/crypto/caam/caamalg_desc.h b/drivers/crypto/caam/caamalg_desc.h index 3899e91..e6c95fa 100644 --- a/drivers/crypto/caam/caamalg_desc.h +++ b/drivers/crypto/caam/caamalg_desc.h @@ -77,12 +77,12 @@ void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata, void cnstr_shdsc_tls_encap(u32 *const desc, struct alginfo *cdata, struct alginfo *adata, unsigned int assoclen, unsigned int ivsize, unsigned int authsize, - unsigned int blocksize); + unsigned int blocksize, int era); void cnstr_shdsc_tls_decap(u32 *const desc, struct alginfo *cdata, struct alginfo *adata, unsigned int assoclen, unsigned int ivsize, unsigned int authsize, - unsigned int blocksize); + unsigned int blocksize, int era); void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata, unsigned int ivsize, unsigned int icvsize, diff --git a/drivers/crypto/caam/caamalg_qi.c b/drivers/crypto/caam/caamalg_qi.c index 1369018..f9b0ebf 100644 --- a/drivers/crypto/caam/caamalg_qi.c +++ b/drivers/crypto/caam/caamalg_qi.c @@ -291,6 +291,7 @@ static int tls_set_sh_desc(struct crypto_aead *tls) unsigned int assoclen = 13; /* always 13 bytes for TLS */ unsigned int data_len[2]; u32 inl_mask; + struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctx->jrdev->parent); if (!ctx->cdata.keylen || !ctx->authsize) return 0; @@ -321,17 +322,20 @@ static int tls_set_sh_desc(struct crypto_aead *tls) ctx->cdata.key_inline = !!(inl_mask & 2); cnstr_shdsc_tls_encap(ctx->sh_desc_enc, &ctx->cdata, &ctx->adata, - assoclen, ivsize, ctx->authsize, blocksize); + assoclen, ivsize, ctx->authsize, blocksize, + ctrlpriv->era); /* * TLS 1.0 decrypt shared descriptor * Keys do not fit inline, regardless of algorithms used */ + ctx->adata.key_inline = false; ctx->adata.key_dma = ctx->key_dma; ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad; cnstr_shdsc_tls_decap(ctx->sh_desc_dec, &ctx->cdata, &ctx->adata, - assoclen, ivsize, ctx->authsize, blocksize); + assoclen, ivsize, ctx->authsize, blocksize, + ctrlpriv->era); return 0; } @@ -351,6 +355,7 @@ static int tls_setkey(struct crypto_aead *tls, const u8 *key, { struct caam_ctx *ctx = crypto_aead_ctx(tls); struct device *jrdev = ctx->jrdev; + struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent); struct crypto_authenc_keys keys; int ret = 0; @@ -365,6 +370,27 @@ static int tls_setkey(struct crypto_aead *tls, const u8 *key, 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; + ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype & + OP_ALG_ALGSEL_MASK); + + if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE) + goto badkey; + + memcpy(ctx->key, keys.authkey, keys.authkeylen); + memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, + keys.enckeylen); + dma_sync_single_for_device(jrdev, ctx->key_dma, + ctx->adata.keylen_pad + + keys.enckeylen, DMA_TO_DEVICE); + goto skip_split_key; + } + ret = gen_split_key(jrdev, ctx->key, &ctx->adata, keys.authkey, keys.authkeylen, CAAM_MAX_KEY_SIZE - keys.enckeylen); @@ -384,6 +410,7 @@ static int tls_setkey(struct crypto_aead *tls, const u8 *key, ctx->adata.keylen_pad + keys.enckeylen, 1); #endif +skip_split_key: ctx->cdata.keylen = keys.enckeylen; ret = tls_set_sh_desc(tls); -- cgit v0.10.2