<div dir="ltr"><div>Here is a reproducer for the bugs. OOB reads and writes on i386:<br></div><div><br></div><div>#include <gcrypt.h></div><br>#define CF_CHECK_EQ(expr, res) if ( (expr) != (res) ) { goto end; }<br><br>int main(void)<br>{<br>    gcry_mpi_t A;<br>    gcry_mpi_t B;<br>    gcry_mpi_t C;<br>    gcry_error_t err;<br><br>    CF_CHECK_EQ(err = gcry_mpi_scan(&A, GCRYMPI_FMT_HEX, "2acc66c62cac3db610ce038e38e391", 0, NULL), 0);<br>    CF_CHECK_EQ(err = gcry_mpi_scan(&B, GCRYMPI_FMT_HEX, "4105f5daf47e2dee608c82bbc02a7e5f4f1e6b205e2d099643ad0101ebd11fd3f1182bda60f00000000", 0, NULL), 0);<br>    CF_CHECK_EQ(err = gcry_mpi_scan(&C, GCRYMPI_FMT_HEX, "1", 0, NULL), 0);<br>    CF_CHECK_EQ(gcry_mpi_invm(C, A, B), 1);<br>    printf("Inverse exists\n");<br>end:<br><br>    return 0;<br><div>}</div><div><br></div><div>Valgrind:</div><div><br></div><div>==18960== Invalid read of size 4<br>==18960==    at 0x1875C0: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==  Address 0x4a512d4 is 0 bytes after a block of size 4 alloc&apos;d<br>==18960==    at 0x483021B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)<br>==18960==    by 0x118755: _gcry_private_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x112692: do_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x112711: _gcry_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x112B50: _gcry_xmalloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x18E35C: _gcry_mpi_alloc_limb_space (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x18753B: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960== <br>==18960== Invalid write of size 4<br>==18960==    at 0x1875E0: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==  Address 0x4a512d4 is 0 bytes after a block of size 4 alloc&apos;d<br>==18960==    at 0x483021B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)<br>==18960==    by 0x118755: _gcry_private_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x112692: do_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x112711: _gcry_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x112B50: _gcry_xmalloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x18E35C: _gcry_mpi_alloc_limb_space (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x18753B: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960== <br>==18960== Invalid read of size 4<br>==18960==    at 0x187740: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==  Address 0x4a51344 is 0 bytes after a block of size 4 alloc&apos;d<br>==18960==    at 0x483021B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)<br>==18960==    by 0x118755: _gcry_private_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x112692: do_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x112711: _gcry_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x112B50: _gcry_xmalloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x18E35C: _gcry_mpi_alloc_limb_space (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x187646: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960== <br>==18960== Invalid write of size 4<br>==18960==    at 0x187760: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==  Address 0x4a51344 is 0 bytes after a block of size 4 alloc&apos;d<br>==18960==    at 0x483021B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)<br>==18960==    by 0x118755: _gcry_private_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x112692: do_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x112711: _gcry_malloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x112B50: _gcry_xmalloc (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x18E35C: _gcry_mpi_alloc_limb_space (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x187646: mpih_invm_pow2 (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x187F38: _gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10D9C4: gcry_mpi_invm (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)<br>==18960==    by 0x10CBA7: main (in /mnt/2tb/libgcrypt-tmp/libgcrypt/21875/a.out)</div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, May 8, 2020 at 6:16 PM Jussi Kivilinna <<a href="mailto:jussi.kivilinna@iki.fi">jussi.kivilinna@iki.fi</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello,<br>
<br>
On 8.5.2020 1.24, Guido Vranken via Gcrypt-devel wrote:<br>
> I'm running my crypto library fuzzer on Google OSS-Fuzz and it keeps finding bugs in gcry_mpi_invm.<br>
> <br>
> jussi kivilinna receives these reports. Would you mind taking a look?<br>
<br>
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. <br>
<br>
If this keeps causing too much noise as repeated bug reports, cannot you disable the BigNum fuzzing of libgcrypt until this gets fixed?<br>
<br>
-Jussi<br>
<br>
> <br>
> On Tue, Apr 14, 2020 at 8:32 AM NIIBE Yutaka <<a href="mailto:gniibe@fsij.org" target="_blank">gniibe@fsij.org</a> <mailto:<a href="mailto:gniibe@fsij.org" target="_blank">gniibe@fsij.org</a>>> wrote:<br>
> <br>
>     Hello,<br>
> <br>
>     Thank you for your report with a test case.  It helps a lot.<br>
> <br>
>     Guido Vranken wrote:<br>
>     > This is not in accordance with the documentation:<br>
>     ><br>
>     > Function: int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m)<br>
>     > Set x to the multiplicative inverse of a \bmod m. Return true if the<br>
>     > inverse exists.<br>
> <br>
>     Indeed.  It seems that API was changed to return the result<br>
>     (success/failure) in libgcrypt 1.3.2 in 2007.  Before that, the API was<br>
>     void (no return value).  Since the initial change, it never returns<br>
>     correct value.<br>
> <br>
>     I'll fix for 1.9.<br>
>     -- <br>
> <br>
> <br>
> _______________________________________________<br>
> Gcrypt-devel mailing list<br>
> <a href="mailto:Gcrypt-devel@gnupg.org" target="_blank">Gcrypt-devel@gnupg.org</a><br>
> <a href="http://lists.gnupg.org/mailman/listinfo/gcrypt-devel" rel="noreferrer" target="_blank">http://lists.gnupg.org/mailman/listinfo/gcrypt-devel</a><br>
> <br>
<br>
<br>
_______________________________________________<br>
Gcrypt-devel mailing list<br>
<a href="mailto:Gcrypt-devel@gnupg.org" target="_blank">Gcrypt-devel@gnupg.org</a><br>
<a href="http://lists.gnupg.org/mailman/listinfo/gcrypt-devel" rel="noreferrer" target="_blank">http://lists.gnupg.org/mailman/listinfo/gcrypt-devel</a><br>
</blockquote></div>