Skip to content

Commit 55779f2

Browse files
stefanbergergregkh
authored andcommitted
crypto: ecc - Prevent ecc_digits_from_bytes from reading too many bytes
[ Upstream commit c6ab5c9 ] 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 <[email protected]> Signed-off-by: Stefan Berger <[email protected]> Signed-off-by: Herbert Xu <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 9457d78 commit 55779f2

File tree

2 files changed

+24
-13
lines changed

2 files changed

+24
-13
lines changed

crypto/ecc.c

+22
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,28 @@ const struct ecc_curve *ecc_get_curve(unsigned int curve_id)
6666
}
6767
EXPORT_SYMBOL(ecc_get_curve);
6868

69+
void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
70+
u64 *out, unsigned int ndigits)
71+
{
72+
int diff = ndigits - DIV_ROUND_UP(nbytes, sizeof(u64));
73+
unsigned int o = nbytes & 7;
74+
__be64 msd = 0;
75+
76+
/* diff > 0: not enough input bytes: set most significant digits to 0 */
77+
if (diff > 0) {
78+
ndigits -= diff;
79+
memset(&out[ndigits - 1], 0, diff * sizeof(u64));
80+
}
81+
82+
if (o) {
83+
memcpy((u8 *)&msd + sizeof(msd) - o, in, o);
84+
out[--ndigits] = be64_to_cpu(msd);
85+
in += o;
86+
}
87+
ecc_swap_digits(in, out, ndigits);
88+
}
89+
EXPORT_SYMBOL(ecc_digits_from_bytes);
90+
6991
static u64 *ecc_alloc_digits_space(unsigned int ndigits)
7092
{
7193
size_t len = ndigits * sizeof(u64);

include/crypto/internal/ecc.h

+2-13
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,8 @@ static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigit
6363
* @out Output digits array
6464
* @ndigits: Number of digits to create from byte array
6565
*/
66-
static inline void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
67-
u64 *out, unsigned int ndigits)
68-
{
69-
unsigned int o = nbytes & 7;
70-
__be64 msd = 0;
71-
72-
if (o) {
73-
memcpy((u8 *)&msd + sizeof(msd) - o, in, o);
74-
out[--ndigits] = be64_to_cpu(msd);
75-
in += o;
76-
}
77-
ecc_swap_digits(in, out, ndigits);
78-
}
66+
void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
67+
u64 *out, unsigned int ndigits);
7968

8069
/**
8170
* ecc_is_key_valid() - Validate a given ECDH private key

0 commit comments

Comments
 (0)