summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHoria Geantă <horia.geanta@nxp.com>2017-11-07 15:25:16 (GMT)
committerXie Xiaobo <xiaobo.xie@nxp.com>2017-12-12 07:32:39 (GMT)
commit75d7b3008fca8f98937573795e62aad3a4cb43d7 (patch)
treec60aa1787db1030a89af9ce28cba0c9cc618fad4
parent34673fb6cbe216d2121eed6713e7b1556a130df2 (diff)
downloadlinux-75d7b3008fca8f98937573795e62aad3a4cb43d7.tar.xz
crypto: caam/qi - add DKP support for tls
Add DKP support for tls using caam/qi as backend. Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
-rw-r--r--drivers/crypto/caam/caamalg_desc.c48
-rw-r--r--drivers/crypto/caam/caamalg_desc.h4
-rw-r--r--drivers/crypto/caam/caamalg_qi.c31
3 files changed, 60 insertions, 23 deletions
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);