aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org> 2024-05-20 08:47:54 -0700
committerGravatar Linus Torvalds <torvalds@linux-foundation.org> 2024-05-20 08:47:54 -0700
commit568c98a0f6eff6d44accfe56d0c58008bf0d498e (patch)
tree1a63e4f278c0917745861dd0bcd85ae84dd3d659
parentMerge tag 'mm-nonmm-stable-2024-05-19-11-56' of git://git.kernel.org/pub/scm/... (diff)
parentcrypto: ecc - Prevent ecc_digits_from_bytes from reading too many bytes (diff)
downloadlinux-568c98a0f6eff6d44accfe56d0c58008bf0d498e.tar.gz
linux-568c98a0f6eff6d44accfe56d0c58008bf0d498e.tar.bz2
linux-568c98a0f6eff6d44accfe56d0c58008bf0d498e.zip
Merge tag 'v6.10-p2' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto fixes from Herbert Xu: "Fix a bug in the new ecc P521 code as well as a buggy fix in qat" * tag 'v6.10-p2' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: crypto: ecc - Prevent ecc_digits_from_bytes from reading too many bytes crypto: qat - Fix ADF_DEV_RESET_SYNC memory leak
-rw-r--r--crypto/ecc.c22
-rw-r--r--drivers/crypto/intel/qat/qat_common/adf_aer.c19
-rw-r--r--include/crypto/internal/ecc.h15
3 files changed, 29 insertions, 27 deletions
diff --git a/crypto/ecc.c b/crypto/ecc.c
index c1d2e884be1e..fe761256e335 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -68,6 +68,28 @@ const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
}
EXPORT_SYMBOL(ecc_get_curve);
+void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
+ u64 *out, unsigned int ndigits)
+{
+ int diff = ndigits - DIV_ROUND_UP(nbytes, sizeof(u64));
+ unsigned int o = nbytes & 7;
+ __be64 msd = 0;
+
+ /* diff > 0: not enough input bytes: set most significant digits to 0 */
+ if (diff > 0) {
+ ndigits -= diff;
+ memset(&out[ndigits - 1], 0, diff * sizeof(u64));
+ }
+
+ if (o) {
+ memcpy((u8 *)&msd + sizeof(msd) - o, in, o);
+ out[--ndigits] = be64_to_cpu(msd);
+ in += o;
+ }
+ ecc_swap_digits(in, out, ndigits);
+}
+EXPORT_SYMBOL(ecc_digits_from_bytes);
+
static u64 *ecc_alloc_digits_space(unsigned int ndigits)
{
size_t len = ndigits * sizeof(u64);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_aer.c b/drivers/crypto/intel/qat/qat_common/adf_aer.c
index 9da2278bd5b7..04260f61d042 100644
--- a/drivers/crypto/intel/qat/qat_common/adf_aer.c
+++ b/drivers/crypto/intel/qat/qat_common/adf_aer.c
@@ -130,8 +130,7 @@ static void adf_device_reset_worker(struct work_struct *work)
if (adf_dev_restart(accel_dev)) {
/* The device hanged and we can't restart it so stop here */
dev_err(&GET_DEV(accel_dev), "Restart device failed\n");
- if (reset_data->mode == ADF_DEV_RESET_ASYNC ||
- completion_done(&reset_data->compl))
+ if (reset_data->mode == ADF_DEV_RESET_ASYNC)
kfree(reset_data);
WARN(1, "QAT: device restart failed. Device is unusable\n");
return;
@@ -147,16 +146,8 @@ static void adf_device_reset_worker(struct work_struct *work)
adf_dev_restarted_notify(accel_dev);
clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
- /*
- * The dev is back alive. Notify the caller if in sync mode
- *
- * If device restart will take a more time than expected,
- * the schedule_reset() function can timeout and exit. This can be
- * detected by calling the completion_done() function. In this case
- * the reset_data structure needs to be freed here.
- */
- if (reset_data->mode == ADF_DEV_RESET_ASYNC ||
- completion_done(&reset_data->compl))
+ /* The dev is back alive. Notify the caller if in sync mode */
+ if (reset_data->mode == ADF_DEV_RESET_ASYNC)
kfree(reset_data);
else
complete(&reset_data->compl);
@@ -191,10 +182,10 @@ static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev,
if (!timeout) {
dev_err(&GET_DEV(accel_dev),
"Reset device timeout expired\n");
+ cancel_work_sync(&reset_data->reset_work);
ret = -EFAULT;
- } else {
- kfree(reset_data);
}
+ kfree(reset_data);
return ret;
}
return 0;
diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h
index 7ca1f463d1ec..f7e75e1e71f3 100644
--- a/include/crypto/internal/ecc.h
+++ b/include/crypto/internal/ecc.h
@@ -64,19 +64,8 @@ static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigit
* @out Output digits array
* @ndigits: Number of digits to create from byte array
*/
-static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
- u64 *out, unsigned int ndigits)
-{
- unsigned int o = nbytes & 7;
- __be64 msd = 0;
-
- if (o) {
- memcpy((u8 *)&msd + sizeof(msd) - o, in, o);
- out[--ndigits] = be64_to_cpu(msd);
- in += o;
- }
- ecc_swap_digits(in, out, ndigits);
-}
+void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
+ u64 *out, unsigned int ndigits);
/**
* ecc_is_key_valid() - Validate a given ECDH private key