From 216c5e7b71317b04731f9a0acd8451dc106d86c0 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 21 May 2021 06:57:41 -0700 Subject: mpi: incorrect unsigned integer extraction. * mpi/mpi.c (mp_get_uintptr, mp_get_double_uintptr): Fix loops which shift and mask the bignum digits together in the wrong way. The post-iteration shift is also wrong. We are fine in mp_get_uintptr because the affected code is in an #if that doesn't actually occur: bignum digits are pointer-sized. mp_get_double_uintptr affects the conversion of bignums to 64 bits on 32 bit platforms. --- mpi/mpi.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mpi/mpi.c b/mpi/mpi.c index b49b93dc..dfe4e138 100644 --- a/mpi/mpi.c +++ b/mpi/mpi.c @@ -433,9 +433,10 @@ mp_err mp_get_uintptr(mp_int *mp, uint_ptr_t *z) #if MP_DIGIT_SIZE < SIZEOF_PTR mp_size ix; - mp_size nd = USED(mp); - for (ix = 0; ix < nd; ix++, out <<= MP_DIGIT_BIT) + for (ix = USED(mp) - 1; ix < MP_SIZE_MAX; ix--) { + out <<= MP_DIGIT_BIT; out |= DIGIT(mp, ix); + } #else out = DIGIT(mp, 0); #endif @@ -548,9 +549,10 @@ mp_err mp_get_double_uintptr(mp_int *mp, double_uintptr_t *z) { double_uintptr_t out = 0; mp_size ix; - mp_size nd = USED(mp); - for (ix = 0; ix < nd; ix++, out <<= MP_DIGIT_BIT) + for (ix = USED(mp) - 1; ix < MP_SIZE_MAX; ix--) { + out <<= MP_DIGIT_BIT; out |= DIGIT(mp, ix); + } *z = (SIGN(mp) == MP_NEG) ? -out : out; return MP_OKAY; -- cgit v1.2.3