From f490ffd739f713fcf0be35b7fbbb8502dea40a0c Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sat, 3 Jun 2023 13:20:07 +0300 Subject: [PATCH] addm/subm/mulm: fix case when destination is same MPI as divider * mpi/mpi-add.c (_gcry_mpi_addm, _gcry_mpi_subm): Take copy of M when W and M are the same MPI. * mpi/mpi-mul.c (_gcry_mpi_mulm): Likewise. * tests/mpitests.c (test_addm_subm_mulm): New. (main): Run addm/subm/mulm test. -- Reported-by: Guido Vranken Signed-off-by: Jussi Kivilinna --- mpi/mpi-add.c | 22 ++++++++++++++++++++ mpi/mpi-mul.c | 11 ++++++++++ tests/mpitests.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) diff --git a/mpi/mpi-add.c b/mpi/mpi-add.c index 41dc3900..51dc71b7 100644 --- a/mpi/mpi-add.c +++ b/mpi/mpi-add.c @@ -227,13 +227,35 @@ _gcry_mpi_sub(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) void _gcry_mpi_addm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) { + gcry_mpi_t temp_m = NULL; + + if (w == m) + { + temp_m = mpi_copy (m); + m = temp_m; + } + mpi_add (w, u, v); mpi_mod (w, w, m); + + if (temp_m) + mpi_free(temp_m); } void _gcry_mpi_subm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) { + gcry_mpi_t temp_m = NULL; + + if (w == m) + { + temp_m = mpi_copy (m); + m = temp_m; + } + mpi_sub (w, u, v); mpi_mod (w, w, m); + + if (temp_m) + mpi_free(temp_m); } diff --git a/mpi/mpi-mul.c b/mpi/mpi-mul.c index 60f1ca48..e8e57475 100644 --- a/mpi/mpi-mul.c +++ b/mpi/mpi-mul.c @@ -207,6 +207,17 @@ _gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) void _gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) { + gcry_mpi_t temp_m = NULL; + + if (w == m) + { + temp_m = mpi_copy (m); + m = temp_m; + } + mpi_mul (w, u, v); _gcry_mpi_tdiv_r (w, w, m); + + if (temp_m) + mpi_free(temp_m); } diff --git a/tests/mpitests.c b/tests/mpitests.c index 48ea18b2..2ee08bd3 100644 --- a/tests/mpitests.c +++ b/tests/mpitests.c @@ -687,6 +687,58 @@ test_powm (void) } +/* What we test here is that using the same mpi for divider and result + works. */ +static int +test_addm_subm_mulm (void) +{ + int i; + + for (i = 0; i < 3; i++) + { + unsigned int expect; + const char *func; + gcry_mpi_t A; + gcry_mpi_t B; + gcry_mpi_t C; + + A = gcry_mpi_set_ui (NULL, 2); + B = gcry_mpi_set_ui (NULL, 4); + C = gcry_mpi_set_ui (NULL, 7); + + if (i == 0) + { + func = "mpi_addm"; + expect = 6; + gcry_mpi_addm(C, A, B, C); + } + else if (i == 1) + { + func = "mpi_subm"; + expect = 5; + gcry_mpi_subm(C, A, B, C); + } + else if (i == 2) + { + func = "mpi_mulm"; + expect = 1; + gcry_mpi_mulm(C, A, B, C); + } + + if (gcry_mpi_is_neg (C) || gcry_mpi_cmp_ui (C, expect)) + { + die ("test_addm_subm_mulm failed for %s at %d\n", func, __LINE__); + } + + gcry_mpi_release(A); + gcry_mpi_release(B); + gcry_mpi_release(C); + } + + return 1; +} + + int main (int argc, char* argv[]) { @@ -710,6 +762,7 @@ main (int argc, char* argv[]) test_sub (); test_mul (); test_powm (); + test_addm_subm_mulm (); return !!error_count; } -- 2.44.0