Commit 568c98a0 authored by Linus Torvalds's avatar Linus Torvalds

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
parents eb6a9339 c6ab5c91
...@@ -68,6 +68,28 @@ const struct ecc_curve *ecc_get_curve(unsigned int curve_id) ...@@ -68,6 +68,28 @@ const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
} }
EXPORT_SYMBOL(ecc_get_curve); 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) static u64 *ecc_alloc_digits_space(unsigned int ndigits)
{ {
size_t len = ndigits * sizeof(u64); size_t len = ndigits * sizeof(u64);
......
...@@ -130,8 +130,7 @@ static void adf_device_reset_worker(struct work_struct *work) ...@@ -130,8 +130,7 @@ static void adf_device_reset_worker(struct work_struct *work)
if (adf_dev_restart(accel_dev)) { if (adf_dev_restart(accel_dev)) {
/* The device hanged and we can't restart it so stop here */ /* The device hanged and we can't restart it so stop here */
dev_err(&GET_DEV(accel_dev), "Restart device failed\n"); dev_err(&GET_DEV(accel_dev), "Restart device failed\n");
if (reset_data->mode == ADF_DEV_RESET_ASYNC || if (reset_data->mode == ADF_DEV_RESET_ASYNC)
completion_done(&reset_data->compl))
kfree(reset_data); kfree(reset_data);
WARN(1, "QAT: device restart failed. Device is unusable\n"); WARN(1, "QAT: device restart failed. Device is unusable\n");
return; return;
...@@ -147,16 +146,8 @@ static void adf_device_reset_worker(struct work_struct *work) ...@@ -147,16 +146,8 @@ static void adf_device_reset_worker(struct work_struct *work)
adf_dev_restarted_notify(accel_dev); adf_dev_restarted_notify(accel_dev);
clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status); clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
/* /* The dev is back alive. Notify the caller if in sync mode */
* The dev is back alive. Notify the caller if in sync mode if (reset_data->mode == ADF_DEV_RESET_ASYNC)
*
* 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))
kfree(reset_data); kfree(reset_data);
else else
complete(&reset_data->compl); complete(&reset_data->compl);
...@@ -191,10 +182,10 @@ static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev, ...@@ -191,10 +182,10 @@ static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev,
if (!timeout) { if (!timeout) {
dev_err(&GET_DEV(accel_dev), dev_err(&GET_DEV(accel_dev),
"Reset device timeout expired\n"); "Reset device timeout expired\n");
cancel_work_sync(&reset_data->reset_work);
ret = -EFAULT; ret = -EFAULT;
} else {
kfree(reset_data);
} }
kfree(reset_data);
return ret; return ret;
} }
return 0; return 0;
......
...@@ -64,19 +64,8 @@ static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigit ...@@ -64,19 +64,8 @@ static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigit
* @out Output digits array * @out Output digits array
* @ndigits: Number of digits to create from byte array * @ndigits: Number of digits to create from byte array
*/ */
static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
u64 *out, unsigned int ndigits) 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);
}
/** /**
* ecc_is_key_valid() - Validate a given ECDH private key * ecc_is_key_valid() - Validate a given ECDH private key
......
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