From f931841b3f043000a1e7a221cbeaba792e740673 Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Tue, 22 Nov 2016 13:52:35 -0800 Subject: [PATCH 1/2] defconfig: msm: disable CRYPTO_DEC_QCE device on msm8998 CRYPTO_DEV_QCE device only provides a subset of crypto algorithms, and it also has conflict with HW crypto device CRYPTO_DEV_QCRYPTO, so disable it. Change-Id: I406a41ac961757d31209ae0a0a4b4d9cc4d31a1e Signed-off-by: Zhen Kong --- arch/arm64/configs/msmcortex-perf_defconfig | 1 - arch/arm64/configs/msmcortex_defconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig index 5d76e41d4fed..caf35789e2d9 100644 --- a/arch/arm64/configs/msmcortex-perf_defconfig +++ b/arch/arm64/configs/msmcortex-perf_defconfig @@ -600,7 +600,6 @@ CONFIG_CRYPTO_DEV_QCRYPTO=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y CONFIG_CRYPTO_DEV_QCEDEV=y CONFIG_CRYPTO_DEV_OTA_CRYPTO=y -CONFIG_CRYPTO_DEV_QCE=y CONFIG_CRYPTO_DEV_QCOM_ICE=y CONFIG_ARM64_CRYPTO=y CONFIG_CRYPTO_SHA1_ARM64_CE=y diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 367822dd0a94..0e6d2c59a3e4 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -666,7 +666,6 @@ CONFIG_CRYPTO_DEV_QCRYPTO=y CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y CONFIG_CRYPTO_DEV_QCEDEV=y CONFIG_CRYPTO_DEV_OTA_CRYPTO=y -CONFIG_CRYPTO_DEV_QCE=y CONFIG_CRYPTO_DEV_QCOM_ICE=y CONFIG_ARM64_CRYPTO=y CONFIG_CRYPTO_SHA1_ARM64_CE=y From 654eb19d416a9a94b5e1e8e11dbbf80dddea6577 Mon Sep 17 00:00:00 2001 From: Zhen Kong Date: Tue, 29 Nov 2016 16:01:05 -0800 Subject: [PATCH 2/2] msm: crypto: fix AEAD issues for HW crypto driver on msm-4.4 Make change to fix AEAD operation issues due to incorrect usage of new aead interface introduced into kernel msm-4.4. Change-Id: I472449c52bff40d48f7d65b05e145cc47cba9357 Signed-off-by: Zhen Kong --- drivers/crypto/msm/qce50.c | 20 ++++++++++---- drivers/crypto/msm/qcrypto.c | 53 ++++++++++++++++++++++++------------ 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c index 61f99370863d..c810021dba9c 100644 --- a/drivers/crypto/msm/qce50.c +++ b/drivers/crypto/msm/qce50.c @@ -2476,8 +2476,11 @@ static int _qce_sps_add_sg_data_off(struct qce_device *pce_dev, res_within_sg = sg_dma_len(sg_src); while (off > 0) { - if (!sg_src) + if (!sg_src) { + pr_err("broken sg list off %d nbytes %d\n", + off, nbytes); return -ENOENT; + } len = sg_dma_len(sg_src); if (off < len) { res_within_sg = len - off; @@ -2485,7 +2488,8 @@ static int _qce_sps_add_sg_data_off(struct qce_device *pce_dev, } off -= len; sg_src = sg_next(sg_src); - res_within_sg = sg_dma_len(sg_src); + if (sg_src) + res_within_sg = sg_dma_len(sg_src); } while (nbytes > 0 && sg_src) { len = min(nbytes, res_within_sg); @@ -2516,9 +2520,15 @@ static int _qce_sps_add_sg_data_off(struct qce_device *pce_dev, addr += data_cnt; len -= data_cnt; } - sg_src = sg_next(sg_src); - off = 0; - res_within_sg = sg_dma_len(sg_src); + if (nbytes) { + sg_src = sg_next(sg_src); + if (!sg_src) { + pr_err("more data bytes %d\n", nbytes); + return -ENOMEM; + } + res_within_sg = sg_dma_len(sg_src); + off = 0; + } } return 0; } diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c index faeff0b55202..a898dbcbd0ca 100644 --- a/drivers/crypto/msm/qcrypto.c +++ b/drivers/crypto/msm/qcrypto.c @@ -821,19 +821,16 @@ static struct qcrypto_alg *_qcrypto_aead_alg_alloc(struct crypto_priv *cp, return q_alg; }; -static int _qcrypto_cipher_cra_init(struct crypto_tfm *tfm) +static int _qcrypto_cipher_ctx_init(struct qcrypto_cipher_ctx *ctx, + struct qcrypto_alg *q_alg) { - struct crypto_alg *alg = tfm->__crt_alg; - struct qcrypto_alg *q_alg; - struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm); - - - q_alg = container_of(alg, struct qcrypto_alg, cipher_alg); + if (!ctx || !q_alg) { + pr_err("ctx or q_alg is NULL\n"); + return -EINVAL; + } ctx->flags = 0; - /* update context with ptr to cp */ ctx->cp = q_alg->cp; - /* random first IV */ get_random_bytes(ctx->iv, QCRYPTO_MAX_IV_LENGTH); if (_qcrypto_init_assign) { @@ -845,6 +842,16 @@ static int _qcrypto_cipher_cra_init(struct crypto_tfm *tfm) INIT_LIST_HEAD(&ctx->rsp_queue); ctx->auth_alg = QCE_HASH_LAST; return 0; +} + +static int _qcrypto_cipher_cra_init(struct crypto_tfm *tfm) +{ + struct crypto_alg *alg = tfm->__crt_alg; + struct qcrypto_alg *q_alg; + struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm); + + q_alg = container_of(alg, struct qcrypto_alg, cipher_alg); + return _qcrypto_cipher_ctx_init(ctx, q_alg); }; static int _qcrypto_ahash_cra_init(struct crypto_tfm *tfm) @@ -941,13 +948,22 @@ static int _qcrypto_cra_aes_ablkcipher_init(struct crypto_tfm *tfm) return _qcrypto_cra_ablkcipher_init(tfm); }; +static int _qcrypto_aead_cra_init(struct crypto_aead *tfm) +{ + struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); + struct aead_alg *aeadalg = crypto_aead_alg(tfm); + struct qcrypto_alg *q_alg = container_of(aeadalg, struct qcrypto_alg, + aead_alg); + return _qcrypto_cipher_ctx_init(ctx, q_alg); +}; + static int _qcrypto_cra_aead_sha1_init(struct crypto_aead *tfm) { int rc; struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); ctx->auth_alg = QCE_HASH_SHA1_HMAC; return rc; } @@ -958,7 +974,7 @@ static int _qcrypto_cra_aead_sha256_init(struct crypto_aead *tfm) struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); ctx->auth_alg = QCE_HASH_SHA256_HMAC; return rc; } @@ -969,7 +985,7 @@ static int _qcrypto_cra_aead_ccm_init(struct crypto_aead *tfm) struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); ctx->auth_alg = QCE_HASH_AES_CMAC; return rc; } @@ -980,7 +996,7 @@ static int _qcrypto_cra_aead_rfc4309_ccm_init(struct crypto_aead *tfm) struct qcrypto_cipher_ctx *ctx = crypto_aead_ctx(tfm); crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); ctx->auth_alg = QCE_HASH_AES_CMAC; return rc; } @@ -992,7 +1008,7 @@ static int _qcrypto_cra_aead_aes_sha1_init(struct crypto_aead *tfm) struct crypto_priv *cp = &qcrypto_dev; crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); if (rc) return rc; ctx->cipher_aes192_fb = NULL; @@ -1023,7 +1039,7 @@ static int _qcrypto_cra_aead_aes_sha256_init(struct crypto_aead *tfm) struct crypto_priv *cp = &qcrypto_dev; crypto_aead_set_reqsize(tfm, sizeof(struct qcrypto_cipher_req_ctx)); - rc = _qcrypto_cipher_cra_init(&tfm->base); + rc = _qcrypto_aead_cra_init(tfm); if (rc) return rc; ctx->cipher_aes192_fb = NULL; @@ -1828,7 +1844,7 @@ static void _qce_aead_complete(void *cookie, unsigned char *icv, if (rctx->dir == QCE_ENCRYPT) { /* copy the icv to dst */ scatterwalk_map_and_copy(icv, areq->dst, - areq->cryptlen, + areq->cryptlen + areq->assoclen, ctx->authsize, 1); } else { @@ -1836,8 +1852,9 @@ static void _qce_aead_complete(void *cookie, unsigned char *icv, /* compare icv from src */ scatterwalk_map_and_copy(tmp, - areq->src, areq->cryptlen - - ctx->authsize, ctx->authsize, 0); + areq->src, areq->assoclen + + areq->cryptlen - ctx->authsize, + ctx->authsize, 0); ret = memcmp(icv, tmp, ctx->authsize); if (ret != 0) ret = -EBADMSG;