summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Berger <stefanb@linux.ibm.com>2024-05-09 21:59:21 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2024-05-17 18:55:07 +0800
commit196eca8607cf9dc44c8b17d0c66619afa0a841cd (patch)
treeb462f9da8752ae4a9b22fa73db46c2d3efbc41ae
parentf8449cd38c515395ea44f0347750113fc002717d (diff)
downloadlinux-crypto-196eca8607cf9dc44c8b17d0c66619afa0a841cd.tar.gz
linux-crypto-196eca8607cf9dc44c8b17d0c66619afa0a841cd.zip
crypto: ecc - Prevent ecc_digits_from_bytes from reading too many bytes
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: c95f28e4efbe ("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>
-rw-r--r--crypto/ecc.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/crypto/ecc.c b/crypto/ecc.c
index c1d2e884..fe761256 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);