Commit 26497e72 authored by Hadar Gat's avatar Hadar Gat Committed by Herbert Xu

crypto: ccree - fix finup

finup() operation was incorrect, padding was missing.
Fix by setting the ccree HW to enable padding.
Signed-off-by: default avatarHadar Gat <hadar.gat@arm.com>
[ gilad@benyossef.com: refactored for better code sharing ]
Signed-off-by: default avatarGilad Ben-Yossef <gilad@benyossef.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent 85d7311f
...@@ -602,66 +602,7 @@ static int cc_hash_update(struct ahash_request *req) ...@@ -602,66 +602,7 @@ static int cc_hash_update(struct ahash_request *req)
return rc; return rc;
} }
static int cc_hash_finup(struct ahash_request *req) static int cc_do_finup(struct ahash_request *req, bool update)
{
struct ahash_req_ctx *state = ahash_request_ctx(req);
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct cc_hash_ctx *ctx = crypto_ahash_ctx(tfm);
u32 digestsize = crypto_ahash_digestsize(tfm);
struct scatterlist *src = req->src;
unsigned int nbytes = req->nbytes;
u8 *result = req->result;
struct device *dev = drvdata_to_dev(ctx->drvdata);
bool is_hmac = ctx->is_hmac;
struct cc_crypto_req cc_req = {};
struct cc_hw_desc desc[CC_MAX_HASH_SEQ_LEN];
unsigned int idx = 0;
int rc;
gfp_t flags = cc_gfp_flags(&req->base);
dev_dbg(dev, "===== %s-finup (%d) ====\n", is_hmac ? "hmac" : "hash",
nbytes);
if (cc_map_req(dev, state, ctx)) {
dev_err(dev, "map_ahash_source() failed\n");
return -EINVAL;
}
if (cc_map_hash_request_final(ctx->drvdata, state, src, nbytes, 1,
flags)) {
dev_err(dev, "map_ahash_request_final() failed\n");
cc_unmap_req(dev, state, ctx);
return -ENOMEM;
}
if (cc_map_result(dev, state, digestsize)) {
dev_err(dev, "map_ahash_digest() failed\n");
cc_unmap_hash_request(dev, state, src, true);
cc_unmap_req(dev, state, ctx);
return -ENOMEM;
}
/* Setup request structure */
cc_req.user_cb = cc_hash_complete;
cc_req.user_arg = req;
idx = cc_restore_hash(desc, ctx, state, idx);
if (is_hmac)
idx = cc_fin_hmac(desc, req, idx);
idx = cc_fin_result(desc, req, idx);
rc = cc_send_request(ctx->drvdata, &cc_req, desc, idx, &req->base);
if (rc != -EINPROGRESS && rc != -EBUSY) {
dev_err(dev, "send_request() failed (rc=%d)\n", rc);
cc_unmap_hash_request(dev, state, src, true);
cc_unmap_result(dev, state, digestsize, result);
cc_unmap_req(dev, state, ctx);
}
return rc;
}
static int cc_hash_final(struct ahash_request *req)
{ {
struct ahash_req_ctx *state = ahash_request_ctx(req); struct ahash_req_ctx *state = ahash_request_ctx(req);
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
...@@ -678,21 +619,20 @@ static int cc_hash_final(struct ahash_request *req) ...@@ -678,21 +619,20 @@ static int cc_hash_final(struct ahash_request *req)
int rc; int rc;
gfp_t flags = cc_gfp_flags(&req->base); gfp_t flags = cc_gfp_flags(&req->base);
dev_dbg(dev, "===== %s-final (%d) ====\n", is_hmac ? "hmac" : "hash", dev_dbg(dev, "===== %s-%s (%d) ====\n", is_hmac ? "hmac" : "hash",
nbytes); update ? "finup" : "final", nbytes);
if (cc_map_req(dev, state, ctx)) { if (cc_map_req(dev, state, ctx)) {
dev_err(dev, "map_ahash_source() failed\n"); dev_err(dev, "map_ahash_source() failed\n");
return -EINVAL; return -EINVAL;
} }
if (cc_map_hash_request_final(ctx->drvdata, state, src, nbytes, 0, if (cc_map_hash_request_final(ctx->drvdata, state, src, nbytes, update,
flags)) { flags)) {
dev_err(dev, "map_ahash_request_final() failed\n"); dev_err(dev, "map_ahash_request_final() failed\n");
cc_unmap_req(dev, state, ctx); cc_unmap_req(dev, state, ctx);
return -ENOMEM; return -ENOMEM;
} }
if (cc_map_result(dev, state, digestsize)) { if (cc_map_result(dev, state, digestsize)) {
dev_err(dev, "map_ahash_digest() failed\n"); dev_err(dev, "map_ahash_digest() failed\n");
cc_unmap_hash_request(dev, state, src, true); cc_unmap_hash_request(dev, state, src, true);
...@@ -706,7 +646,7 @@ static int cc_hash_final(struct ahash_request *req) ...@@ -706,7 +646,7 @@ static int cc_hash_final(struct ahash_request *req)
idx = cc_restore_hash(desc, ctx, state, idx); idx = cc_restore_hash(desc, ctx, state, idx);
/* "DO-PAD" must be enabled only when writing current length to HW */ /* Pad the hash */
hw_desc_init(&desc[idx]); hw_desc_init(&desc[idx]);
set_cipher_do(&desc[idx], DO_PAD); set_cipher_do(&desc[idx], DO_PAD);
set_cipher_mode(&desc[idx], ctx->hw_mode); set_cipher_mode(&desc[idx], ctx->hw_mode);
...@@ -731,6 +671,17 @@ static int cc_hash_final(struct ahash_request *req) ...@@ -731,6 +671,17 @@ static int cc_hash_final(struct ahash_request *req)
return rc; return rc;
} }
static int cc_hash_finup(struct ahash_request *req)
{
return cc_do_finup(req, true);
}
static int cc_hash_final(struct ahash_request *req)
{
return cc_do_finup(req, false);
}
static int cc_hash_init(struct ahash_request *req) static int cc_hash_init(struct ahash_request *req)
{ {
struct ahash_req_ctx *state = ahash_request_ctx(req); struct ahash_req_ctx *state = ahash_request_ctx(req);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment