4.17-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Hadar Gat <hadar....@arm.com>

commit 26497e72a1aba4d27c50c4cbf0182db94e58a590 upstream.

finup() operation was incorrect, padding was missing.
Fix by setting the ccree HW to enable padding.

Signed-off-by: Hadar Gat <hadar....@arm.com>
[ gi...@benyossef.com: refactored for better code sharing ]
Signed-off-by: Gilad Ben-Yossef <gi...@benyossef.com>
Cc: sta...@vger.kernel.org
Signed-off-by: Herbert Xu <herb...@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 drivers/crypto/ccree/cc_hash.c |   81 ++++++++---------------------------------
 1 file changed, 16 insertions(+), 65 deletions(-)

--- a/drivers/crypto/ccree/cc_hash.c
+++ b/drivers/crypto/ccree/cc_hash.c
@@ -602,7 +602,7 @@ static int cc_hash_update(struct ahash_r
        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);
@@ -619,15 +619,15 @@ static int cc_hash_finup(struct ahash_re
        int rc;
        gfp_t flags = cc_gfp_flags(&req->base);
 
-       dev_dbg(dev, "===== %s-finup (%d) ====\n", is_hmac ? "hmac" : "hash",
-               nbytes);
+       dev_dbg(dev, "===== %s-%s (%d) ====\n", is_hmac ? "hmac" : "hash",
+               update ? "finup" : "final", 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,
+       if (cc_map_hash_request_final(ctx->drvdata, state, src, nbytes, update,
                                      flags)) {
                dev_err(dev, "map_ahash_request_final() failed\n");
                cc_unmap_req(dev, state, ctx);
@@ -646,67 +646,7 @@ static int cc_hash_finup(struct ahash_re
 
        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 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-final (%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, 0,
-                                     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);
-
-       /* "DO-PAD" must be enabled only when writing current length to HW */
+       /* Pad the hash */
        hw_desc_init(&desc[idx]);
        set_cipher_do(&desc[idx], DO_PAD);
        set_cipher_mode(&desc[idx], ctx->hw_mode);
@@ -731,6 +671,17 @@ static int cc_hash_final(struct ahash_re
        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)
 {
        struct ahash_req_ctx *state = ahash_request_ctx(req);


Reply via email to