The GMP library uses asserts to crash a program at runtime when presented with data it did not anticipate. The library also ignores user requests to remove asserts using Posix's -DNDEBUG. Asserts are a debugging aide intended for developement, and using them in production software ranges from questionable to insecure. Many programs and libraries can safely use assert to crash a program at runtime. However, the prequisite is, the program cannot handle sensitive information like user passwords, user keys or sensitive documents. High integrity software, like GMP and Nettle, cannot safely use an assert to crash a program. To understand why the data flow must be examined. First, when an assert fires, abort() is called and a SIGABRT is eventually sent to the program on Unix and Linux (http://pubs.opengroup.org/onlinepubs/009695399/functions/assert.html). Second, the SIGABRT terminates the process and can write a core file. This is the first point of unwanted data egress. Sensitive information like user passwords and keys can be written to the filesystem unprotected. Third, the dump is sometimes sent to an error reporting service like Apple Crash Report, Android Crash Report, Ubuntu Apport, and Windows Error Reporting. This is the second point of unwanted data egress. The platform provider like Apple, Google, Microsoft or Ubuntu can gain access to the sensitive information, in addition to the developer. In fact, when one popular security library used in Bitcoin wallets was apprised of the situation, they responded: The standard abort() call also produces somewhat useful error messages on Windows, so I can get an idea on what’s going on when users report these. Another popular security library used for code signing remarked: Please never ever define NDEBUG. This is a severe misfeature of the assert macro. Wow, change your passwords and keys after an asert fires... Here's a small example of triggering an assert using the Nettle library. Nettle depends on GMP, and GMP is the root cause of the information leak. The result below can be reproduced on i686, x86_64, and Aarch64 using the attached script. ARM A-32 does not work at the moment due to GMP build errors. In the case below Nettle is using benign data and not maliciously crafted data. Notice GMP spilled the sensitive information during a sliding window modular exponentiation (also see https://gmplib.org/repo/gmp-6.1/file/tip/mpn/generic/sec_powm.c). # from Nettle 'make check' ... PASS: rsa-keygen PASS: rsa-sec-decrypt sec_powm.c:293: GNU MP assertion failed: enb >= windowsize ../run-tests: line 57: 24756 Aborted (core dumped) "$1" $testflags FAIL: rsa-compute-root PASS: dsa ...
#!/usr/bin/env bash CURR_DIR=$(pwd) function finish { cd "$CURR_DIR" } trap finish EXIT rm -rf /tmp/gmp-test cd /tmp wget https://ftp.gnu.org/gnu/gmp/gmp-6.1.2.tar.bz2 -O gmp-6.1.2.tar.bz2 tar -xjf gmp-6.1.2.tar.bz2 cd gmp-6.1.2 PKG_CONFIG_PATH="/tmp/gmp-test/lib/pkgconfig" \ CPPFLAGS="-I/tmp/gmp-test/include -DNDEBUG" \ CFLAGS="-g2 -O2 -march=native -fPIC" \ LDFLAGS="-L/tmp/gmp-test/lib -Wl,-R,/tmp/gmp-test/lib -Wl,--enable-new-dtags" \ ./configure --prefix=/tmp/gmp-test make make check make install cd /tmp wget https://ftp.gnu.org/gnu/nettle/nettle-3.4.1.tar.gz -O nettle-3.4.1.tar.gz tar -xzf nettle-3.4.1.tar.gz cd nettle-3.4.1 PKG_CONFIG_PATH="/tmp/gmp-test/lib/pkgconfig" \ CPPFLAGS="-I/tmp/gmp-test/include -DNDEBUG" \ CFLAGS="-g2 -O2 -march=native -fPIC" \ LDFLAGS="-L/tmp/gmp-test/lib -Wl,-R,/tmp/gmp-test/lib -Wl,--enable-new-dtags" \ ./configure --prefix=/tmp/gmp-test make make check make install