Add support for using OpenSSL as the cryptography backend.

Currently, libktorrent uses LibGcrypt for RC4 cipher. This commit adds support for using OpenSSL instead, which allows for removing the dependency on LibGcrypt entirely. Since libktorrent already uses QCA for SHA1 hash calculation and it internally uses OpenSSL as the backend, the dependency on OpenSSL is not new.

The cryptography backend to use can be selected at configuration time, by adding -DUSE_CRYPTO_BACKEND=<backend> to CMake command line. Three values are supported: Auto, OpenSSL and LibGcrypt. Auto is the default, and it means that CMake will search for OpenSSL and LibGcrypt (in that order) and choose the first found library. The other two options select the corresponding library unconditionally. OpenSSL 3.0.0 is the minimal supported version.

This makes OpenSSL a slightly more preferred option since it will be picked first in case if both libraries are installed. This is to prefer a configuration with least dependencies, all other considerations being equal.

Local benchmarking shows no notable difference in RC4 performance between OpenSSL 3.0.13 and LibGcrypt 1.10.3 on Kubuntu 24.04, Core i7 12700K:

$ ./rc4encryptor_perftest_gcrypt
Data size: 1024, duration: 108087 us, throughput: 90.349672 MiB/s
Data size: 4096, duration: 121609 us, throughput: 321.213890 MiB/s
Data size: 16384, duration: 491933 us, throughput: 317.624555 MiB/s
Data size: 65536, duration: 1980121 us, throughput: 315.637277 MiB/s
Data size: 131081, duration: 3940600 us, throughput: 317.232358 MiB/s
$ ./rc4encryptor_perftest_ossl
Data size: 1024, duration: 101230 us, throughput: 96.469673 MiB/s
Data size: 4096, duration: 125002 us, throughput: 312.495000 MiB/s
Data size: 16384, duration: 497592 us, throughput: 314.012283 MiB/s
Data size: 65536, duration: 2001976 us, throughput: 312.191555 MiB/s
Data size: 131081, duration: 4010009 us, throughput: 311.741403 MiB/s

(Perf test: rc4encryptor_perftest.cpp; compile with -DLIBKTORRENT_USE_OPENSSL=1 or -DLIBKTORRENT_USE_LIBGCRYPT=1.)

The existing implementation of RC4 for LibGcrypt is left unchanged with one exception. In RC4Encryptor::encrypt, which uses the static buffer for encrypted output, added a check that the input size does not exceed the size of the static buffer to guarantee there won't be a buffer overrun. This also reflects the OpenSSL backend behavior.

Edited by Andrey Semashev

Merge request reports

Loading