mirror of
https://github.com/torvalds/linux.git
synced 2026-09-13 15:40:03 +02:00
s390/crypto: Fix handling of EBUSY in PHMAC when req is pushed to crypto engine
When a request is transferred to the engine via
crypto_transfer_hash_request_to_engine() there are two return codes
signaling a successful transfer: EINPROGRESS and EBUSY. However the
correct handling of EBUSY was missing and has been added as a return
code indicating a successful transfer to the crypto engine.
Fixes: cbbc675506 ("crypto: s390 - New s390 specific protected key hash phmac")
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Cc: stable@vger.kernel.org # 6.17+
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
parent
3fec882c33
commit
3301483714
|
|
@ -62,8 +62,10 @@ static inline int hwh_prepare(struct ahash_request *req,
|
|||
*/
|
||||
static inline int hwh_advance(struct hash_walk_helper *hwh, int n)
|
||||
{
|
||||
if (n < 0)
|
||||
if (n < 0) {
|
||||
hwh->walkbytes = n;
|
||||
return crypto_hash_walk_done(&hwh->walk, n);
|
||||
}
|
||||
|
||||
hwh->walkbytes -= n;
|
||||
hwh->walkaddr += n;
|
||||
|
|
@ -606,6 +608,7 @@ static int phmac_update(struct ahash_request *req)
|
|||
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
|
||||
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
|
||||
struct hash_walk_helper *hwh = &req_ctx->hwh;
|
||||
bool cleanup = true;
|
||||
int rc;
|
||||
|
||||
/* prep the walk in the request context */
|
||||
|
|
@ -629,12 +632,15 @@ static int phmac_update(struct ahash_request *req)
|
|||
req_ctx->async_op = OP_UPDATE;
|
||||
atomic_inc(&tfm_ctx->via_engine_ctr);
|
||||
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
|
||||
if (rc != -EINPROGRESS)
|
||||
if (rc == -EINPROGRESS || rc == -EBUSY)
|
||||
cleanup = false;
|
||||
else
|
||||
atomic_dec(&tfm_ctx->via_engine_ctr);
|
||||
}
|
||||
|
||||
if (rc != -EINPROGRESS) {
|
||||
hwh_advance(hwh, rc);
|
||||
if (cleanup) {
|
||||
if (hwh->walkbytes > 0)
|
||||
hwh_advance(hwh, rc);
|
||||
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
|
||||
}
|
||||
|
||||
|
|
@ -649,6 +655,7 @@ static int phmac_final(struct ahash_request *req)
|
|||
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
|
||||
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
|
||||
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
|
||||
bool cleanup = true;
|
||||
int rc = 0;
|
||||
|
||||
/* Try synchronous operation if no active engine usage */
|
||||
|
|
@ -667,12 +674,14 @@ static int phmac_final(struct ahash_request *req)
|
|||
req_ctx->async_op = OP_FINAL;
|
||||
atomic_inc(&tfm_ctx->via_engine_ctr);
|
||||
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
|
||||
if (rc != -EINPROGRESS)
|
||||
if (rc == -EINPROGRESS || rc == -EBUSY)
|
||||
cleanup = false;
|
||||
else
|
||||
atomic_dec(&tfm_ctx->via_engine_ctr);
|
||||
}
|
||||
|
||||
out:
|
||||
if (rc != -EINPROGRESS)
|
||||
if (cleanup)
|
||||
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
|
||||
pr_debug("rc=%d\n", rc);
|
||||
return rc;
|
||||
|
|
@ -685,6 +694,7 @@ static int phmac_finup(struct ahash_request *req)
|
|||
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
|
||||
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
|
||||
struct hash_walk_helper *hwh = &req_ctx->hwh;
|
||||
bool cleanup = true;
|
||||
int rc;
|
||||
|
||||
/* prep the walk in the request context */
|
||||
|
|
@ -716,15 +726,17 @@ static int phmac_finup(struct ahash_request *req)
|
|||
/* req->async_op has been set to either OP_FINUP or OP_FINAL */
|
||||
atomic_inc(&tfm_ctx->via_engine_ctr);
|
||||
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
|
||||
if (rc != -EINPROGRESS)
|
||||
if (rc == -EINPROGRESS || rc == -EBUSY)
|
||||
cleanup = false;
|
||||
else
|
||||
atomic_dec(&tfm_ctx->via_engine_ctr);
|
||||
}
|
||||
|
||||
if (rc != -EINPROGRESS)
|
||||
if (cleanup && hwh->walkbytes > 0)
|
||||
hwh_advance(hwh, rc);
|
||||
|
||||
out:
|
||||
if (rc != -EINPROGRESS)
|
||||
if (cleanup)
|
||||
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
|
||||
pr_debug("rc=%d\n", rc);
|
||||
return rc;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user