summaryrefslogtreecommitdiff
path: root/drivers/crypto
diff options
context:
space:
mode:
authorZhen Kong <zkong@codeaurora.org>2016-11-29 16:01:05 -0800
committerZhen Kong <zkong@codeaurora.org>2016-12-21 15:14:52 -0800
commit654eb19d416a9a94b5e1e8e11dbbf80dddea6577 (patch)
tree4ef318209da748475adfb201170ab998dff740a2 /drivers/crypto
parentf931841b3f043000a1e7a221cbeaba792e740673 (diff)
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 <zkong@codeaurora.org>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/msm/qce50.c20
-rw-r--r--drivers/crypto/msm/qcrypto.c53
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;