Skip to content

Commit

Permalink
crypto: ecc - Prevent ecc_digits_from_bytes from reading too many bytes
Browse files Browse the repository at this point in the history
Prevent ecc_digits_from_bytes from reading too many bytes from the input
byte array in case an insufficient number of bytes is provided to fill the
output digit array of ndigits. Therefore, initialize the most significant
digits with 0 to avoid trying to read too many bytes later on. Convert the
function into a regular function since it is getting too big for an inline
function.

If too many bytes are provided on the input byte array the extra bytes
are ignored since the input variable 'ndigits' limits the number of digits
that will be filled.

Fixes: d67c96f ("crypto: ecdsa - Convert byte arrays with key coordinates to digits")
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
  • Loading branch information
stefanberger authored and herbertx committed May 17, 2024
1 parent d3b17c6 commit c6ab5c9
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 13 deletions.
22 changes: 22 additions & 0 deletions crypto/ecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
15 changes: 2 additions & 13 deletions include/crypto/internal/ecc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c6ab5c9

Please sign in to comment.