From b989f35dafc80755c94ead5d622cd426d5715465 Mon Sep 17 00:00:00 2001 From: Lukas Lihotzki Date: Mon, 26 Apr 2021 12:23:09 +0200 Subject: [PATCH] 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 --- CMakeLists.txt | 9 +++++---- src/crypto.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10b5d6e..5dcd179 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(olm VERSION 3.2.8 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}) @@ -47,9 +47,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) @@ -60,8 +58,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() diff --git a/src/crypto.cpp b/src/crypto.cpp index 5e543c7..74a59ed 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -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 }