This is not in accordance with the documentation: Function: int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m) Set x to the multiplicative inverse of a \bmod m. Return true if the inverse exists. #include <gcrypt.h> #define CF_CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; } int main(void) { gcry_mpi_t A; gcry_mpi_t B; gcry_mpi_t C; gcry_error_t err; CF_CHECK_EQ(err = gcry_mpi_scan(&A, GCRYMPI_FMT_HEX, "3", 0, NULL), 0); CF_CHECK_EQ(err = gcry_mpi_scan(&B, GCRYMPI_FMT_HEX, "66", 0, NULL), 0); CF_CHECK_EQ(err = gcry_mpi_scan(&C, GCRYMPI_FMT_HEX, "1", 0, NULL), 0); CF_CHECK_EQ(gcry_mpi_invm(C, A, B), 1); printf("Inverse exists\n"); end: return 0; } _______________________________________________ Gcrypt-devel mailing list [hidden email] http://lists.gnupg.org/mailman/listinfo/gcrypt-devel |
Hello,
Thank you for your report with a test case. It helps a lot. Guido Vranken wrote: > This is not in accordance with the documentation: > > Function: int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m) > Set x to the multiplicative inverse of a \bmod m. Return true if the > inverse exists. Indeed. It seems that API was changed to return the result (success/failure) in libgcrypt 1.3.2 in 2007. Before that, the API was void (no return value). Since the initial change, it never returns correct value. I'll fix for 1.9. -- _______________________________________________ Gcrypt-devel mailing list [hidden email] http://lists.gnupg.org/mailman/listinfo/gcrypt-devel |
I'm running my crypto library fuzzer on Google OSS-Fuzz and it keeps finding bugs in gcry_mpi_invm. jussi kivilinna receives these reports. Would you mind taking a look? On Tue, Apr 14, 2020 at 8:32 AM NIIBE Yutaka <[hidden email]> wrote: Hello, _______________________________________________ Gcrypt-devel mailing list [hidden email] http://lists.gnupg.org/mailman/listinfo/gcrypt-devel |
Hello,
On 8.5.2020 1.24, Guido Vranken via Gcrypt-devel wrote: > I'm running my crypto library fuzzer on Google OSS-Fuzz and it keeps finding bugs in gcry_mpi_invm. > > jussi kivilinna receives these reports. Would you mind taking a look? I did see "Issue 21708 in oss-fuzz: cryptofuzz:cryptofuzz-openssl: ASSERT: Botan-libgcrypt-BignumCalc-(no algorithm)-difference" 2020-04-15 and follow-up discussion and that resulted bug-report to this mailing list. I have not seen any further reports from OSS-Fuzz. If this keeps causing too much noise as repeated bug reports, cannot you disable the BigNum fuzzing of libgcrypt until this gets fixed? -Jussi > > On Tue, Apr 14, 2020 at 8:32 AM NIIBE Yutaka <[hidden email] <mailto:[hidden email]>> wrote: > > Hello, > > Thank you for your report with a test case. It helps a lot. > > Guido Vranken wrote: > > This is not in accordance with the documentation: > > > > Function: int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m) > > Set x to the multiplicative inverse of a \bmod m. Return true if the > > inverse exists. > > Indeed. It seems that API was changed to return the result > (success/failure) in libgcrypt 1.3.2 in 2007. Before that, the API was > void (no return value). Since the initial change, it never returns > correct value. > > I'll fix for 1.9. > -- > > > _______________________________________________ > Gcrypt-devel mailing list > [hidden email] > http://lists.gnupg.org/mailman/listinfo/gcrypt-devel > _______________________________________________ Gcrypt-devel mailing list [hidden email] http://lists.gnupg.org/mailman/listinfo/gcrypt-devel |
Here is a reproducer for the bugs. OOB reads and writes on i386: #include <gcrypt.h> #define CF_CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; } int main(void) { gcry_mpi_t A; gcry_mpi_t B; gcry_mpi_t C; gcry_error_t err; CF_CHECK_EQ(err = gcry_mpi_scan(&A, GCRYMPI_FMT_HEX, "2acc66c62cac3db610ce038e38e391", 0, NULL), 0); CF_CHECK_EQ(err = gcry_mpi_scan(&B, GCRYMPI_FMT_HEX, "4105f5daf47e2dee608c82bbc02a7e5f4f1e6b205e2d099643ad0101ebd11fd3f1182bda60f00000000", 0, NULL), 0); CF_CHECK_EQ(err = gcry_mpi_scan(&C, GCRYMPI_FMT_HEX, "1", 0, NULL), 0); CF_CHECK_EQ(gcry_mpi_invm(C, A, B), 1); printf("Inverse exists\n"); end: return 0; } Valgrind: ==18960== Invalid read of size 4 ==18960== at 0x1875C0: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== Address 0x4a512d4 is 0 bytes after a block of size 4 alloc'd ==18960== at 0x483021B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==18960== by 0x118755: _gcry_private_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x112692: do_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x112711: _gcry_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x112B50: _gcry_xmalloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x18E35C: _gcry_mpi_alloc_limb_space (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x18753B: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== ==18960== Invalid write of size 4 ==18960== at 0x1875E0: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== Address 0x4a512d4 is 0 bytes after a block of size 4 alloc'd ==18960== at 0x483021B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==18960== by 0x118755: _gcry_private_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x112692: do_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x112711: _gcry_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x112B50: _gcry_xmalloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x18E35C: _gcry_mpi_alloc_limb_space (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x18753B: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== ==18960== Invalid read of size 4 ==18960== at 0x187740: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== Address 0x4a51344 is 0 bytes after a block of size 4 alloc'd ==18960== at 0x483021B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==18960== by 0x118755: _gcry_private_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x112692: do_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x112711: _gcry_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x112B50: _gcry_xmalloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x18E35C: _gcry_mpi_alloc_limb_space (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x187646: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== ==18960== Invalid write of size 4 ==18960== at 0x187760: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== Address 0x4a51344 is 0 bytes after a block of size 4 alloc'd ==18960== at 0x483021B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==18960== by 0x118755: _gcry_private_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x112692: do_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x112711: _gcry_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x112B50: _gcry_xmalloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x18E35C: _gcry_mpi_alloc_limb_space (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x187646: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) ==18960== by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out) On Fri, May 8, 2020 at 6:16 PM Jussi Kivilinna <[hidden email]> wrote: Hello, _______________________________________________ Gcrypt-devel mailing list [hidden email] http://lists.gnupg.org/mailman/listinfo/gcrypt-devel |
Guido Vranken via Gcrypt-devel wrote:
> Here is a reproducer for the bugs. OOB reads and writes on i386: Thanks. It was me who embugged. It was just fixed by the commit: 69b55f87053ce2494cd4b38dc600f867bc4355be By the way, the problem in your original report was also fixed. Now, it should return correct value (if inverse exists or not). -- _______________________________________________ Gcrypt-devel mailing list [hidden email] http://lists.gnupg.org/mailman/listinfo/gcrypt-devel |
Hello,
Cryptofuzz is reporting another heap-buffer-overflow issue in _gcry_mpi_invm. I've attached reproducer, original from Guido and as patch applied to tests/basic.c. Here's AddressSanitizer output from tests/basic with reproducer, compiled with CFLAGS="-fsanitize=address -O0 -g": $ tests/basic ================================================================= ==1665037==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000000388 at pc 0x7f36999058d0 bp 0x7ffdef3a5160 sp 0x7ffdef3a5150 READ of size 8 at 0x603000000388 thread T0 #0 0x7f36999058cf in _gcry_mpi_invm ../../mpi/mpi-inv.c:530 #1 0x7f369970a270 in gcry_mpi_invm ../../src/visibility.c:472 #2 0x5608cc442631 in test_cryptofuzz ../../tests/basic.c:13901 #3 0x5608cc442ffb in main ../../tests/basic.c:14019 #4 0x7f36994d80b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) #5 0x5608cc411f4d in _start (/home/jussi/kernel/libgcrypt/build-amd64-ubsan/tests/basic+0x5bf4d) 0x603000000388 is located 0 bytes to the right of 24-byte region [0x603000000370,0x603000000388) allocated by thread T0 here: #0 0x7f3699ad0bc8 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8) #1 0x7f36997253ab in _gcry_private_malloc ../../src/stdmem.c:113 #2 0x7f36997137af in do_malloc ../../src/global.c:920 #3 0x7f369971395e in _gcry_malloc ../../src/global.c:942 #4 0x7f3699714007 in _gcry_xmalloc ../../src/global.c:1116 #5 0x7f36999142f0 in _gcry_mpi_alloc_limb_space ../../mpi/mpiutil.c:138 #6 0x7f36999057f2 in _gcry_mpi_invm ../../mpi/mpi-inv.c:523 #7 0x7f369970a270 in gcry_mpi_invm ../../src/visibility.c:472 #8 0x5608cc442631 in test_cryptofuzz ../../tests/basic.c:13901 #9 0x5608cc442ffb in main ../../tests/basic.c:14019 #10 0x7f36994d80b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2) SUMMARY: AddressSanitizer: heap-buffer-overflow ../../mpi/mpi-inv.c:530 in _gcry_mpi_invm Shadow bytes around the buggy address: 0x0c067fff8020: 00 00 00 fa fa fa 00 00 00 fa fa fa 00 00 00 fa 0x0c067fff8030: fa fa 00 00 00 fa fa fa fd fd fd fa fa fa fd fd 0x0c067fff8040: fd fa fa fa fd fd fd fa fa fa fd fd fd fa fa fa 0x0c067fff8050: 00 00 00 fa fa fa fd fd fd fa fa fa fd fd fd fa 0x0c067fff8060: fa fa fd fd fd fa fa fa 00 00 00 fa fa fa 00 00 =>0x0c067fff8070: 00[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff8080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff8090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff80a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff80b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff80c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==1665037==ABORTING I applied following change and that appears to avoid the heap-overflow, but I'm not sure if this is correct fix: diff --git a/mpi/mpi-inv.c b/mpi/mpi-inv.c index 3ff5947a..a53a195a 100644 --- a/mpi/mpi-inv.c +++ b/mpi/mpi-inv.c @@ -526,7 +526,8 @@ _gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n) else _gcry_mpih_sub_n (diffp, x1p, x2p, x1size); _gcry_mpi_free_limb_space (x1p, x1size); - for (i = k % BITS_PER_MPI_LIMB; i < BITS_PER_MPI_LIMB; i++) + for (i = k % BITS_PER_MPI_LIMB; + i < BITS_PER_MPI_LIMB && k / BITS_PER_MPI_LIMB < x1size; i++) diffp[k/BITS_PER_MPI_LIMB] &= ~(((mpi_limb_t)1) << i); hsize = x1size * 2; -Jussi On 13.5.2020 9.44, Niibe Yutaka wrote: > Guido Vranken via Gcrypt-devel wrote: >> Here is a reproducer for the bugs. OOB reads and writes on i386: > > Thanks. It was me who embugged. It was just fixed by the commit: > > 69b55f87053ce2494cd4b38dc600f867bc4355be > > By the way, the problem in your original report was also fixed. > Now, it should return correct value (if inverse exists or not). > _______________________________________________ Gcrypt-devel mailing list [hidden email] http://lists.gnupg.org/mailman/listinfo/gcrypt-devel ![]() ![]() |
Jussi Kivilinna <[hidden email]> wrote:
> Cryptofuzz is reporting another heap-buffer-overflow issue in > _gcry_mpi_invm. I've attached reproducer, original from Guido and > as patch applied to tests/basic.c. My fix of 69b55f87053ce2494cd4b38dc600f867bc4355be was not enough. I just push another change: 6f8b1d4cb798375e6d830fd6b73c71da93ee5f3f Thank you for your report. -- _______________________________________________ Gcrypt-devel mailing list [hidden email] http://lists.gnupg.org/mailman/listinfo/gcrypt-devel |
The following inputs to gcry_mpi_invm(): 36fb5bdb5daa9864113ad8a49a41722fc7003a40b02a13daca6997859c2d8534192ff6c02447 25c88352cfa171fc728503df037c355a6d5588b22e3510b08f10848ad7c0980b400 produces the number: 66CAF1A9A03478A288760C2E05E237F11432BA70BECEE56D942ACCD337470E5D77 But this is incorrect (another library reports the modular inverse does not exist). ---------- The following inputs to gcry_mpi_invm(): 12cf3a8ca3d97bea2f080362600cee355 1c3fddf62aee0be2f6dc2ef8471f1be2e produces the number: 60A6520F494E6EE6EE436283FB34B945 but it should produce: 1339462644931fd624528ea6b3fb1f985 On Mon, Jun 1, 2020 at 9:39 AM NIIBE Yutaka <[hidden email]> wrote: Jussi Kivilinna <[hidden email]> wrote: _______________________________________________ Gcrypt-devel mailing list [hidden email] http://lists.gnupg.org/mailman/listinfo/gcrypt-devel |
Reminder that invmod is still broken and has been for a long time. On Thu, Sep 3, 2020 at 2:19 PM Guido Vranken <[hidden email]> wrote:
_______________________________________________ Gcrypt-devel mailing list [hidden email] http://lists.gnupg.org/mailman/listinfo/gcrypt-devel |
Guido Vranken <[hidden email]> writes:
> Reminder that invmod is still broken and has been for a long time. Thanks a lot. I overlooked your email on September. I created the task: https://dev.gnupg.org/T5269 And push a fix commit: https://dev.gnupg.org/rCf06ff4e31c8e162f4a59986241c7ab43d5085927 -- _______________________________________________ Gcrypt-devel mailing list [hidden email] http://lists.gnupg.org/mailman/listinfo/gcrypt-devel |
Free forum by Nabble | Edit this page |