summaryrefslogtreecommitdiff
path: root/drivers/crypto
diff options
context:
space:
mode:
authorRadu Solea <radu.solea@nxp.com>2017-04-13 15:22:41 +0300
committerAnson Huang <Anson.Huang@nxp.com>2017-06-09 22:19:26 +0800
commit79a6483b4b417ae95e18d353a0a4fe6a38cd0981 (patch)
tree8ddba341bec849ab7bfe5e57971a9b13dac154ea /drivers/crypto
parent5e556796d2b95d2d307b48b1057865681e56252e (diff)
MLK-14611 Fix CBC mode support by returning a correct IV
Current CBC mode does not return the last cyphertext block as IV for operation chaining. CTS fails because of incorrect IV. Signed-off-by: Radu Solea <radu.solea@nxp.com>
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/caam/caamalg.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 65ddeef8ddc8..dbf28717ba6f 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -2041,10 +2041,13 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
{
struct ablkcipher_request *req = context;
struct ablkcipher_edesc *edesc;
-#ifdef DEBUG
struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
+ struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
+ int bsize = crypto_ablkcipher_blocksize(ablkcipher);
int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
+ size_t ivcopy = min_t(size_t, bsize, ivsize);
+#ifdef DEBUG
dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
#endif
@@ -2066,6 +2069,12 @@ static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
ablkcipher_unmap(jrdev, edesc, req);
kfree(edesc);
+ /* Pass IV along for cbc */
+ if ((ctx->class1_alg_type & OP_ALG_AAI_MASK) == OP_ALG_AAI_CBC) {
+ scatterwalk_map_and_copy(req->info, req->dst,
+ req->nbytes - bsize, ivcopy, 0);
+ }
+
ablkcipher_request_complete(req, err);
}