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>
This commit is contained in:
Zhen Kong 2016-11-29 16:01:05 -08:00
parent f931841b3f
commit 654eb19d41
2 changed files with 50 additions and 23 deletions

View file

@ -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;
}

View file

@ -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;