Use OpenSSL instead of bundled curve25519-donna if enabled

This change primarily increases runtime performance. The tests added together
are speed up by about 50%. Additionally, binary size decreases by about 15%.

LibreSSL can't be used because it doesn't provide a function to get
the public key for an existing private key in its openssl/curve25519.h.

Signed-off-by: Lukas Lihotzki <lukas@lihotzki.de>
This commit is contained in:
Lukas Lihotzki 2021-04-26 12:23:09 +02:00 committed by Hubert Chathi
parent 386431d831
commit dec76ddc39
2 changed files with 30 additions and 4 deletions

View file

@ -4,7 +4,7 @@ project(olm VERSION 3.2.2 LANGUAGES CXX C)
option(OLM_TESTS "Build tests" ON)
option(BUILD_SHARED_LIBS "Build as a shared library" ON)
option(OLM_USE_OPENSSL "Use OpenSSL instead of bundled crypto-algorithms" OFF)
option(OLM_USE_OPENSSL "Use OpenSSL instead of bundled crypto-algorithms and curve25519-donna" OFF)
option(OLM_USE_LIBRESSL "Use LibreSSL instead of bundled crypto-algorithms" OFF)
add_definitions(-DOLMLIB_VERSION_MAJOR=${PROJECT_VERSION_MAJOR})
@ -43,9 +43,7 @@ add_library(olm
src/megolm.c
src/olm.cpp
src/outbound_group_session.c
src/pickle_encoding.c
lib/curve25519-donna/curve25519-donna.c)
src/pickle_encoding.c)
add_library(Olm::Olm ALIAS olm)
if(OLM_USE_OPENSSL)
@ -56,8 +54,11 @@ elseif(OLM_USE_LIBRESSL)
find_package(LibreSSL REQUIRED)
target_link_libraries(olm LibreSSL::Crypto)
target_compile_definitions(olm PRIVATE OLM_USE_LIBRESSL)
target_sources(olm PRIVATE
lib/curve25519-donna/curve25519-donna.c)
else()
target_sources(olm PRIVATE
lib/curve25519-donna/curve25519-donna.c
lib/crypto-algorithms/aes.c
lib/crypto-algorithms/sha256.c)
endif()

View file

@ -131,6 +131,15 @@ void _olm_crypto_curve25519_generate_key(
uint8_t const * random_32_bytes,
struct _olm_curve25519_key_pair *key_pair
) {
#ifdef OLM_USE_OPENSSL
EVP_PKEY *pkey = checked(EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, nullptr,
random_32_bytes, 32));
size_t priv_len = CURVE25519_KEY_LENGTH;
size_t pub_len = CURVE25519_KEY_LENGTH;
checked(EVP_PKEY_get_raw_private_key(pkey, key_pair->private_key.private_key, &priv_len));
checked(EVP_PKEY_get_raw_public_key(pkey, key_pair->public_key.public_key, &pub_len));
EVP_PKEY_free(pkey);
#else
std::memcpy(
key_pair->private_key.private_key, random_32_bytes,
CURVE25519_KEY_LENGTH
@ -140,6 +149,7 @@ void _olm_crypto_curve25519_generate_key(
key_pair->private_key.private_key,
CURVE25519_BASEPOINT
);
#endif
}
@ -148,7 +158,22 @@ void _olm_crypto_curve25519_shared_secret(
const struct _olm_curve25519_public_key * their_key,
std::uint8_t * output
) {
#ifdef OLM_USE_OPENSSL
EVP_PKEY *pkey = checked(EVP_PKEY_new_raw_private_key(EVP_PKEY_X25519, nullptr,
our_key->private_key.private_key, CURVE25519_KEY_LENGTH));
EVP_PKEY *peer = checked(EVP_PKEY_new_raw_public_key(EVP_PKEY_X25519, nullptr,
their_key->public_key, CURVE25519_KEY_LENGTH));
EVP_PKEY_CTX *ctx = checked(EVP_PKEY_CTX_new(pkey, nullptr));
checked(EVP_PKEY_derive_init(ctx));
checked(EVP_PKEY_derive_set_peer(ctx, peer));
size_t shared_secret_length = CURVE25519_SHARED_SECRET_LENGTH;
checked(EVP_PKEY_derive(ctx, output, &shared_secret_length));
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(peer);
EVP_PKEY_free(pkey);
#else
::curve25519_donna(output, our_key->private_key.private_key, their_key->public_key);
#endif
}