`#define p 761` conflicts with Termux variant of Android NDK, preventing build for Termux
Description
https://github.com/open-quantum-safe/liboqs/blob/97f6b86b1b6d109cfd43cf276ae39c2e776aed80/src/kem/ntruprime/pqclean_sntrup761_clean/params.h#L31
Hi, I am trying to compile the latest liboqs for the Android app Termux, and regardless of whether I attempt to cross-compile using the official Android NDK (patched with Termux patches) or non-cross-compile using the Android terminal emulator Termux, I see the same error each time:
-- The C compiler identification is Clang 21.1.5
-- The ASM compiler identification is Clang with GNU-like command-line
-- Found assembler: /data/data/com.termux/files/usr/bin/aarch64-linux-android-clang
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /data/data/com.termux/files/usr/bin/aarch64-linux-android-clang - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Performing Test CC_SUPPORTS_WA_NOEXECSTACK
-- Performing Test CC_SUPPORTS_WA_NOEXECSTACK - Success
-- Performing Test LD_SUPPORTS_WL_Z_NOEXECSTACK
-- Performing Test LD_SUPPORTS_WL_Z_NOEXECSTACK - Success
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Check if compiler accepts -pthread
-- Check if compiler accepts -pthread - yes
-- Found Threads: TRUE
-- Alg enablement unchanged
-- Found OpenSSL: /data/data/com.termux/files/usr/lib/libcrypto.so (found suitable version "3.5.2", minimum required is "1.1.1")
-- Looking for aligned_alloc
-- Looking for aligned_alloc - not found
-- Looking for posix_memalign
-- Looking for posix_memalign - found
-- Looking for memalign
-- Looking for memalign - found
-- Looking for explicit_bzero
-- Looking for explicit_bzero - not found
-- Looking for explicit_memset
-- Looking for explicit_memset - not found
-- Looking for memset_s
-- Looking for memset_s - not found
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE)
-- Configuring done (8.7s)
-- Generating done (0.7s)
CMake Warning:
Manually-specified variables were not used by the project:
BUILD_TESTING
CMAKE_CXX_FLAGS
CMAKE_USE_SYSTEM_LIBRARIES
-- Build files have been written to: /data/data/com.termux/files/home/.termux-build/liboqs/build
[106/1238] Building C object src/kem/ntruprime/CMakeFiles/ntruprime_sntrup761_clean.dir/pqclean_sntrup761_clean/kem.c.o
FAILED: [code=1] src/kem/ntruprime/CMakeFiles/ntruprime_sntrup761_clean.dir/pqclean_sntrup761_clean/kem.c.o
/data/data/com.termux/files/usr/bin/aarch64-linux-android-clang -I/data/data/com.termux/files/home/.termux-build/liboqs/build/include -I/data/data/com.termux/files/home/.termux-build/liboqs/src/src/kem/ntruprime/pqclean_sntrup761_clean -I/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/pqclean_shims -fstack-protector-strong -Oz -isystem/data/data/com.termux/files/usr/include/c++/v1 -isystem/data/data/com.termux/files/usr/include -O3 -DNDEBUG -std=gnu11 -fPIC -fvisibility=hidden -march=armv8-a+crypto -Wa,--noexecstack -O3 -fomit-frame-pointer -MD -MT src/kem/ntruprime/CMakeFiles/ntruprime_sntrup761_clean.dir/pqclean_sntrup761_clean/kem.c.o -MF src/kem/ntruprime/CMakeFiles/ntruprime_sntrup761_clean.dir/pqclean_sntrup761_clean/kem.c.o.d -o src/kem/ntruprime/CMakeFiles/ntruprime_sntrup761_clean.dir/pqclean_sntrup761_clean/kem.c.o -c /data/data/com.termux/files/home/.termux-build/liboqs/src/src/kem/ntruprime/pqclean_sntrup761_clean/kem.c
In file included from /data/data/com.termux/files/home/.termux-build/liboqs/src/src/kem/ntruprime/pqclean_sntrup761_clean/kem.c:5:
In file included from /data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/pqclean_shims/randombytes.h:6:
In file included from /data/data/com.termux/files/home/.termux-build/liboqs/build/include/oqs/rand.h:15:
In file included from /data/data/com.termux/files/home/.termux-build/liboqs/build/include/oqs/common.h:13:
In file included from /data/data/com.termux/files/usr/include/c++/v1/stdio.h:108:
/data/data/com.termux/files/usr/include/stdio.h:380:17: error: expected ')'
380 | void free(void* p);
| ^
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/kem/ntruprime/pqclean_sntrup761_clean/params.h:31:11: note: expanded from macro 'p'
31 | #define p 761
| ^
/data/data/com.termux/files/usr/include/stdio.h:380:10: note: to match this '('
380 | void free(void* p);
| ^
/data/data/com.termux/files/usr/include/stdio.h:383:6: error: expected identifier or '('
383 | int p = getpid();
| ^
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/kem/ntruprime/pqclean_sntrup761_clean/params.h:31:11: note: expanded from macro 'p'
31 | #define p 761
| ^
2 errors generated.
[111/1238] Building C object src/common/sha3/xkcp_low/CMakeFiles/xkcp_low_keccakp_1600_plain64.dir/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c.o
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:200:62: warning: implicit conversion loses integer precision: 'int' to 'unsigned char' [-Wimplicit-int-conversion]
200 | ((unsigned char *)state)[lanePosition * 8 + offset + i] = ~data[i];
| ~ ^~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:384:3: warning: implicit conversion loses integer precision: 'int' to 'unsigned char' [-Wimplicit-int-conversion]
384 | COMPL(1);
| ^~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:382:70: note: expanded from macro 'COMPL'
382 | #define COMPL(lane) for(unsigned int i=0; i<8; i++) data[8*lane+i] = ~data[8*lane+i]
| ~ ^~~~~~~~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:386:4: warning: implicit conversion loses integer precision: 'int' to 'unsigned char' [-Wimplicit-int-conversion]
386 | COMPL(2);
| ^~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:382:70: note: expanded from macro 'COMPL'
382 | #define COMPL(lane) for(unsigned int i=0; i<8; i++) data[8*lane+i] = ~data[8*lane+i]
| ~ ^~~~~~~~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:388:5: warning: implicit conversion loses integer precision: 'int' to 'unsigned char' [-Wimplicit-int-conversion]
388 | COMPL(8);
| ^~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:382:70: note: expanded from macro 'COMPL'
382 | #define COMPL(lane) for(unsigned int i=0; i<8; i++) data[8*lane+i] = ~data[8*lane+i]
| ~ ^~~~~~~~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:390:6: warning: implicit conversion loses integer precision: 'int' to 'unsigned char' [-Wimplicit-int-conversion]
390 | COMPL(12);
| ^~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:382:70: note: expanded from macro 'COMPL'
382 | #define COMPL(lane) for(unsigned int i=0; i<8; i++) data[8*lane+i] = ~data[8*lane+i]
| ~ ^~~~~~~~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:392:7: warning: implicit conversion loses integer precision: 'int' to 'unsigned char' [-Wimplicit-int-conversion]
392 | COMPL(17);
| ^~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:382:70: note: expanded from macro 'COMPL'
382 | #define COMPL(lane) for(unsigned int i=0; i<8; i++) data[8*lane+i] = ~data[8*lane+i]
| ~ ^~~~~~~~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:394:8: warning: implicit conversion loses integer precision: 'int' to 'unsigned char' [-Wimplicit-int-conversion]
394 | COMPL(20);
| ^~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:382:70: note: expanded from macro 'COMPL'
382 | #define COMPL(lane) for(unsigned int i=0; i<8; i++) data[8*lane+i] = ~data[8*lane+i]
| ~ ^~~~~~~~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:459:3: warning: implicit conversion loses integer precision: 'int' to 'unsigned char' [-Wimplicit-int-conversion]
459 | COMPL(1);
| ^~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:457:59: note: expanded from macro 'COMPL'
457 | #define COMPL(lane) for(i=0; i<8; i++) output[8*lane+i] = ~output[8*lane+i]
| ~ ^~~~~~~~~~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:461:4: warning: implicit conversion loses integer precision: 'int' to 'unsigned char' [-Wimplicit-int-conversion]
461 | COMPL(2);
| ^~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:457:59: note: expanded from macro 'COMPL'
457 | #define COMPL(lane) for(i=0; i<8; i++) output[8*lane+i] = ~output[8*lane+i]
| ~ ^~~~~~~~~~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:463:5: warning: implicit conversion loses integer precision: 'int' to 'unsigned char' [-Wimplicit-int-conversion]
463 | COMPL(8);
| ^~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:457:59: note: expanded from macro 'COMPL'
457 | #define COMPL(lane) for(i=0; i<8; i++) output[8*lane+i] = ~output[8*lane+i]
| ~ ^~~~~~~~~~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:465:6: warning: implicit conversion loses integer precision: 'int' to 'unsigned char' [-Wimplicit-int-conversion]
465 | COMPL(12);
| ^~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:457:59: note: expanded from macro 'COMPL'
457 | #define COMPL(lane) for(i=0; i<8; i++) output[8*lane+i] = ~output[8*lane+i]
| ~ ^~~~~~~~~~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:467:7: warning: implicit conversion loses integer precision: 'int' to 'unsigned char' [-Wimplicit-int-conversion]
467 | COMPL(17);
| ^~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:457:59: note: expanded from macro 'COMPL'
457 | #define COMPL(lane) for(i=0; i<8; i++) output[8*lane+i] = ~output[8*lane+i]
| ~ ^~~~~~~~~~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:469:8: warning: implicit conversion loses integer precision: 'int' to 'unsigned char' [-Wimplicit-int-conversion]
469 | COMPL(20);
| ^~~~~~~~~
/data/data/com.termux/files/home/.termux-build/liboqs/src/src/common/sha3/xkcp_low/KeccakP-1600/plain-64bits/KeccakP-1600-opt64.c:457:59: note: expanded from macro 'COMPL'
457 | #define COMPL(lane) for(i=0; i<8; i++) output[8*lane+i] = ~output[8*lane+i]
| ~ ^~~~~~~~~~~~~~~~~
13 warnings generated.
ninja: build stopped: subcommand failed.
This error can be reproduced most easily using a single Android device by following these steps:
-
Install the Termux App from F-Droid https://f-droid.org/en/packages/com.termux/
-
Run this series of commands in it
pkg upgrade
pkg install git
git clone https://github.com/termux/termux-packages.git
cd termux-packages
scripts/setup-termux.sh
git apply -v << 'EOF'
diff --git a/packages/liboqs/build.sh b/packages/liboqs/build.sh
new file mode 100644
index 0000000000..d37a382022
--- /dev/null
+++ b/packages/liboqs/build.sh
@@ -0,0 +1,10 @@
+TERMUX_PKG_HOMEPAGE=https://openquantumsafe.org/
+TERMUX_PKG_DESCRIPTION="C library for prototyping and experimenting with quantum-resistant cryptography"
+TERMUX_PKG_LICENSE="MIT"
+TERMUX_PKG_MAINTAINER="@termux"
+TERMUX_PKG_VERSION="0.15.0"
+TERMUX_PKG_SRCURL="https://github.com/open-quantum-safe/liboqs/archive/refs/tags/$TERMUX_PKG_VERSION.tar.gz"
+TERMUX_PKG_SHA256=3983f7cd1247f37fb76a040e6fd684894d44a84cecdcfbdb90559b3216684b5c
+TERMUX_PKG_AUTO_UPDATE=true
+TERMUX_PKG_DEPENDS="openssl"
+
EOF
./build-package.sh -I -f liboqs
Expected behaviour
I hope that some day there can be Termux support in liboqs, which hopefully is simple to achieve, particularly for at least non-cross-compilation, by refactoring liboqs to not use a preprocessor definition with an excessively generic name
liboqs version
0.15.0
Environment
- Architecture: aarch64
- OS: Android 13 with Android NDK r28c (NDK headers patched with Termux project's patches)
- OpenSSL version 3.5.2
- Compiler version used clang 21.1.5
- Build variables used None/Any (I tried without variables, and also with several combinations of variables, and the same error occurred every time)
Use of generative AI
I never use LLMs/generative AI
Additional information
This issue is also reproducible when attempting to compile for Android the current version of SoftEther VPN, which depends on liboqs.
https://github.com/SoftEtherVPN/SoftEtherVPN
After troubleshooting this issue further, I have determined that it is not reproducible with a 100% vanilla Android NDK, which explains why the build for Android succeeds in your CI here, because the conflict is actually with a custom patch for the Android NDK headers that only exists in the Termux variant of the NDK, located here:
https://github.com/termux/termux-packages/blob/6c1b51acffd13fe109ef8f7ab046ce478fc52171/ndk-patches/28c/stdio.h.patch#L62
I have updated the issue description to accurately identify that the conflict is specifically between Termux and liboqs.
Explained basically, Termux project and liboqs project have both unfortunately chosen an overly generic variable name p, and this variable name creates a conflict when attempting to combine Termux and liboqs.
I will also ask the Termux project whether they think that it is better for liboqs to change the variable name away from p first, or if instead Termux project should change the variable name away from p first.
Thanks for this report @robertkirkman . Just looking at the define you quote at the beginning of the issue gives me the creeps and I'm utterly surprised that this didn't fly in our face before: A parameter "p" in a file "params.h" is just waiting for a wrong include chain to trigger havoc for the "uninitiated"... That said, this file is not one from liboqs but from an upstream source (pqclean), so a proper place to change this to a more defensive define, e.g., "define sntru_p 761" would imo be there. But then again, the algorithm in question is no longer maintained in PQClean, so several questions go to several people:
- Do you really need this algorithm, @robertkirkman ? If not, why not disable it to resolve the problem?
- As per https://github.com/open-quantum-safe/liboqs/pull/1328, should someone step up to the plate in
liboqsand make this code safer for everyone? Or should this algorithm now finally be dropped for good? @ryndia @bbbrumley
Thank you, actually I did not realize it was possible to turn off this algorithm, but now I see that it is. I can confirm that when I pass -DOQS_ENABLE_KEM_NTRUPRIME=OFF, the error is avoided and the build of liboqs in Termux is otherwise successful.
I am not completely sure yet whether I need this algorithm, because I need liboqs for the software SoftEtherVPN, but if nothing in that software depends specifically on this part of liboqs, then I don't need this algorithm. I will check that now, and I will let you know if -DOQS_ENABLE_KEM_NTRUPRIME=OFF is sufficient to solve my problem.
Thanks, I think that is working. I can successfully build SoftEtherVPN after making this change to it:
--- a/src/Mayaqua/3rdparty/liboqs/.CMake/alg_support.cmake
+++ b/src/Mayaqua/3rdparty/liboqs/.CMake/alg_support.cmake
@@ -105,7 +105,7 @@ cmake_dependent_option(OQS_ENABLE_KEM_frodokem_976_shake "" ON "OQS_ENABLE_KEM_F
cmake_dependent_option(OQS_ENABLE_KEM_frodokem_1344_aes "" ON "OQS_ENABLE_KEM_FRODOKEM" OFF)
cmake_dependent_option(OQS_ENABLE_KEM_frodokem_1344_shake "" ON "OQS_ENABLE_KEM_FRODOKEM" OFF)
-option(OQS_ENABLE_KEM_NTRUPRIME "Enable ntruprime algorithm family" ON)
+option(OQS_ENABLE_KEM_NTRUPRIME "Enable ntruprime algorithm family" OFF)
cmake_dependent_option(OQS_ENABLE_KEM_ntruprime_sntrup761 "" ON "OQS_ENABLE_KEM_NTRUPRIME" OFF)
if(CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin")
if(OQS_DIST_X86_64_BUILD OR (OQS_USE_AVX2_INSTRUCTIONS))
If you would like, I can close this issue now, but I can leave it open if you feel that an action is still necessary to fix the default behavior so that this error doesn't happen to others.
I can leave it open if you feel that an action is still necessary to fix the default behavior so that this error doesn't happen to others.
That would be my preference such that others can chime in whether they think a) we need to keep this as-is,, b) set the build option to OFF by default, c) yank this algorithm for good or d) change the code such that such "overloads" cannot happen again.
Thanks for the confirmation that option b) works for you.
2. should someone step up to the plate in
liboqsand make this code safer for everyone? Or should this algorithm now finally be dropped for good?
seems like PQClean deprecated sntrup761 quite a while ago, after it didn't proceed in the the PQC standardization process.
I would suggest tossing the PQClean code for sntrup761 since no one maintains it anymore, and drop in something from SUPERCOP. If that's what the project wants, I can probably contribute that myself (or delegate it).
lmk