oqsprovider on FreeBSD
Building oqsprovider
My naive approach was to simply follow the provided instructions:
$ git clone https://github.com/open-quantum-safe/oqs-provider $ cd oqs-provider $ cmake -DOPENSSL_ROOT_DIR=/usr/local -S . -B _build [... narrative output ...] -- Configuring done -- Generating done -- Build files have been written to: /home/cromwell/oqs-provider/_build $ cmake --build _build [... initial compilation steps ...]
However, this resulted in many errors about dynamic relocation:
[... earlier successful compilation steps ...] [ 64%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqs_endecoder_common.c.o [ 68%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqs_decode_der2key.c.o [ 72%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqsprov_bio.c.o [ 76%] Linking C shared library ../lib/oqsprovider.so ld: error: can't create dynamic relocation R_X86_64_32S against local symbol in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output >>> defined in ../install/lib/libqsc_key_encoder.a(encoding_qsc.c.o) >>> referenced by encoding_qsc.c >>> encoding_qsc.c.o:(qsc_encoding_by_name_oid) in archive ../install/lib/libqsc_key_encoder.a ld: error: can't create dynamic relocation R_X86_64_64 against symbol: Dilithium_R3_4x4_encodings in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output >>> defined in ../install/lib/libqsc_key_encoder.a(encoding_dilithium.c.o) >>> referenced by encoding_qsc.c >>> encoding_qsc.c.o:(qsc_encodings) in archive ../install/lib/libqsc_key_encoder.a ld: error: can't create dynamic relocation R_X86_64_64 against symbol: Dilithium_R3_6x5_encodings in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output >>> defined in ../install/lib/libqsc_key_encoder.a(encoding_dilithium.c.o) >>> referenced by encoding_qsc.c >>> encoding_qsc.c.o:(qsc_encodings) in archive ../install/lib/libqsc_key_encoder.a [... many continuing errors ...] ld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors) cc: error: linker command failed with exit code 1 (use -v to see invocation) *** Error code 1 Stop.
The output tells us to use the -fPIC
option which
creates position-independent code (hence PIC)
suitable for dynamic linking and
avoiding any limit on the size of the global offset table.
I eventually figured out that the problem came from
FreeBSD including the Clang C compiler.
In this situation with everything being invoked through
cmake
,
the suggested workarounds
were specific to the GCC compiler collection and its
gcc
and g++
.
I also had GCC installed,
but it wasn't being used by the above process.
$ which cc /usr/bin/cc $ cc --version FreeBSD clang version 16.0.6 (https://github.com/llvm/llvm-project.git llvmorg-16.0.6-0-g7cbf1a259152) Target: x86_64-unknown-freebsd14.0 Thread model: posix InstalledDir: /usr/bin $ which gcc /usr/local/bin/gcc $ gcc --version gcc (FreeBSD Ports Collection) 12.2.0
Here is what worked for me.
$ cd $ rm -r oqs-provider $ git clone https://github.com/open-quantum-safe/oqs-provider $ cd oqs-provider $ export CC=/usr/local/bin/gcc $ export CFLAGS="-fPIC" $ cmake -DOPENSSL_ROOT_DIR=/usr/local -S . -B _build -- The C compiler identification is GNU 12.2.0 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /usr/local/bin/gcc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Creating Release build -- Build will store public keys in PKCS#8 structures -- Build will include external encoding library for SPKI/PKCS#8 -- Found OpenSSL: /usr/local/lib/libcrypto.so (found suitable version "3.1.4", minimum required is "3.0") -- Building commit 0e46745 in /home/cromwell/oqs-provider CMake Warning at test/CMakeLists.txt:35 (message): OpenSSL source build directory '/home/cromwell/oqs-provider/test/../openssl' not present. Some dependent tests will be skipped. -- Configuring done -- Generating done -- Build files have been written to: /home/cromwell/oqs-provider/_build $ cmake --build _build [... many earlier compilation steps ...] [ 64%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqs_endecoder_common.c.o [ 68%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqs_decode_der2key.c.o [ 72%] Building C object oqsprov/CMakeFiles/oqsprovider.dir/oqsprov_bio.c.o [ 76%] Linking C shared library ../lib/oqsprovider.so [ 76%] Built target oqsprovider [ 80%] Building C object test/CMakeFiles/oqs_test_signatures.dir/oqs_test_signatures.c.o [ 84%] Building C object test/CMakeFiles/oqs_test_signatures.dir/test_common.c.o [ 88%] Linking C executable oqs_test_signatures [ 88%] Built target oqs_test_signatures [ 92%] Building C object test/CMakeFiles/oqs_test_kems.dir/oqs_test_kems.c.o [ 96%] Building C object test/CMakeFiles/oqs_test_kems.dir/test_common.c.o [100%] Linking C executable oqs_test_kems [100%] Built target oqs_test_kems
That finished in just about ten seconds! Now I can install it:
$ sudo cmake --install _build -- Install configuration: "" -- Installing: /usr/local/lib/oqsprovider.so.0.5.0-dev -- Installing: /usr/local/lib/oqsprovider.so.1 -- Set runtime path of "/usr/local/lib/oqsprovider.so.0.5.0-dev" to "" -- Installing: /usr/local/lib/oqsprovider.so
Notice that the oqsprovider.so
shared library is also linked to use the
libcrypto.so
shared library
created when I built OpenSSL.
$ ls -l /usr/local/lib/oqsprovider.so* lrwxr-xr-x 1 root wheel 16 Apr 2 17:27 /usr/local/lib/oqsprovider.so -> oqsprovider.so.1 -rwxr-xr-x 1 root wheel 5939096 Apr 2 17:21 /usr/local/lib/oqsprovider.so.0.5.0-dev lrwxr-xr-x 1 root wheel 24 Apr 2 17:27 /usr/local/lib/oqsprovider.so.1 -> oqsprovider.so.0.5.0-dev $ file /usr/local/lib/oqsprovider.so.0.5.0-dev /usr/local/lib/oqsprovider.so.0.5.0-dev: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, for FreeBSD 13.1, with debug_info, not stripped $ ldd /usr/local/lib/oqsprovider.so.0.5.0-dev /usr/local/lib/oqsprovider.so.0.5.0-dev: libcrypto.so.3 => /usr/local/lib/libcrypto.so.3 (0x1a4f365cb000) libc.so.7 => /lib/libc.so.7 (0x1a4f33538000) libthr.so.3 => /lib/libthr.so.3 (0x1a4f32b7f000)
Configuring OpenSSL to use oqsprovider
The openssl
program is configured by the file
/etc/ssl/openssl.cnf
.
The original file
contains this section in lines 53 through 72:
[...52 lines deleted...] [openssl_init] providers = provider_sect # List of providers to load [provider_sect] default = default_sect # The fips section name should match the section name inside the # included fipsmodule.cnf. # fips = fips_sect # If no providers are activated explicitly, the default one is activated implicitly. # See man 7 OSSL_PROVIDER-default for more details. # # If you add a section explicitly activating any other provider(s), you most # probably need to explicitly activate the default provider, otherwise it # becomes unavailable in openssl. As a consequence applications depending on # OpenSSL may not work correctly which could lead to significant system # problems including inability to remotely access the system. [default_sect] # activate = 1 [...more lines deleted...]
We need to change it as follows, with changes highlighted:
[...52 lines deleted...] [openssl_init] providers = provider_sect # List of providers to load [provider_sect] default = default_sect # The fips section name should match the section name inside the # included fipsmodule.cnf. # fips = fips_sect oqs = oqs_sect # If no providers are activated explicitly, the default one is activated implicitly. # See man 7 OSSL_PROVIDER-default for more details. # # If you add a section explicitly activating any other provider(s), you most # probably need to explicitly activate the default provider, otherwise it # becomes unavailable in openssl. As a consequence applications depending on # OpenSSL may not work correctly which could lead to significant system # problems including inability to remotely access the system. [default_sect] activate = 1 [oqs_sect] module = /usr/local/lib/oqsprovider.so activate = 1 [...more lines deleted...]
Notice that I have:
-
Added
oqs
to the list of providers, to be defined in a following[oqs_sect]
section. -
Explicitly enabled the
default
provider, as strongly suggested. -
Created a new
[oqs_sect]
section which specifies the newly builtoqsprovider.so
shared library and then activates it.
The diff
command should show you these changes:
$ diff /etc/ssl/openssl.cnf.dist /etc/ssl/openssl.cnf 61a62 > oqs = oqs_sect 72c73 < # activate = 1 --- > activate = 1 73a75,77 > [oqs_sect] > module = /usr/local/lib/oqsprovider.so > activate = 1
Now openssl
supports
the Open Quantum Safe provider!
$ openssl list -providers Providers: default name: OpenSSL Default Provider version: 3.1.1 status: active oqs name: OpenSSL OQS Provider version: 0.5.0-dev status: active $ openssl list -key-exchange-algorithms ECDH @ default { 1.3.101.110, X25519 } @ default { 1.3.101.111, X448 } @ default { 1.2.840.113549.1.3.1, DH, dhKeyAgreement } @ default TLS1-PRF @ default HKDF @ default { 1.3.6.1.4.1.11591.4.11, id-scrypt, SCRYPT } @ default $ openssl list -kem-algorithms | sort bikel1 @ oqs bikel3 @ oqs bikel5 @ oqs frodo1344aes @ oqs frodo1344shake @ oqs frodo640aes @ oqs frodo640shake @ oqs frodo976aes @ oqs frodo976shake @ oqs hqc128 @ oqs hqc192 @ oqs hqc256 @ oqs kyber1024 @ oqs kyber512 @ oqs kyber768 @ oqs kyber90s1024 @ oqs kyber90s512 @ oqs kyber90s768 @ oqs p256_bikel1 @ oqs p256_frodo640aes @ oqs p256_frodo640shake @ oqs p256_hqc128 @ oqs p256_kyber512 @ oqs p256_kyber90s512 @ oqs p384_bikel3 @ oqs p384_frodo976aes @ oqs p384_frodo976shake @ oqs p384_hqc192 @ oqs p384_kyber768 @ oqs p384_kyber90s768 @ oqs p521_bikel5 @ oqs p521_frodo1344aes @ oqs p521_frodo1344shake @ oqs p521_hqc256 @ oqs p521_kyber1024 @ oqs p521_kyber90s1024 @ oqs x25519_bikel1 @ oqs x25519_frodo640aes @ oqs x25519_frodo640shake @ oqs x25519_hqc128 @ oqs x25519_kyber512 @ oqs x25519_kyber90s512 @ oqs x448_bikel3 @ oqs x448_frodo976aes @ oqs x448_frodo976shake @ oqs x448_hqc192 @ oqs x448_kyber768 @ oqs x448_kyber90s768 @ oqs { 1.2.840.113549.1.1.1, 2.5.8.1.1, RSA, rsaEncryption } @ default