Compare commits

..
15 changed files with 378 additions and 421 deletions
+8 -6
View File
@@ -12,18 +12,20 @@ ARG REL=
WORKDIR /root WORKDIR /root
RUN set -e -x; \ RUN set -e -x; \
perl -i -pe 's/deb.debian.org/archive.debian.org/' /etc/apt/sources.list; \ if [ "$REL" = "buster" ]; then \
apt-get update; \ perl -i -pe 's/deb.debian.org/archive.debian.org/' /etc/apt/sources.list; \
apt-get -y install wget; \ apt-get update; \
wget https://vitastor.io/debian/pubkey.gpg -O /etc/apt/trusted.gpg.d/vitastor.gpg; \ apt-get -y install wget; \
echo "deb https://vitastor.io/debian $REL main" >> /etc/apt/sources.list; \ wget https://vitastor.io/debian/pubkey.gpg -O /etc/apt/trusted.gpg.d/vitastor.gpg; \
echo "deb https://vitastor.io/debian $REL main" >> /etc/apt/sources.list; \
fi; \
grep '^deb ' /etc/apt/sources.list | perl -pe 's/^deb/deb-src/' >> /etc/apt/sources.list; \ grep '^deb ' /etc/apt/sources.list | perl -pe 's/^deb/deb-src/' >> /etc/apt/sources.list; \
perl -i -pe 's/Types: deb$/Types: deb deb-src/' /etc/apt/sources.list.d/*.sources || true; \ perl -i -pe 's/Types: deb$/Types: deb deb-src/' /etc/apt/sources.list.d/*.sources || true; \
echo 'APT::Install-Recommends false;' >> /etc/apt/apt.conf; \ echo 'APT::Install-Recommends false;' >> /etc/apt/apt.conf; \
echo 'APT::Install-Suggests false;' >> /etc/apt/apt.conf echo 'APT::Install-Suggests false;' >> /etc/apt/apt.conf
RUN apt-get update && \ RUN apt-get update && \
apt-get -y install fio libgoogle-perftools-dev devscripts libjerasure-dev cmake libc-ares-dev libisal-crypto-dev \ apt-get -y install fio libgoogle-perftools-dev devscripts libjerasure-dev cmake libc-ares-dev \
libibverbs-dev librdmacm-dev libisal-dev libnl-3-dev libnl-genl-3-dev curl nodejs npm node-nan node-bindings && \ libibverbs-dev librdmacm-dev libisal-dev libnl-3-dev libnl-genl-3-dev curl nodejs npm node-nan node-bindings && \
apt-get -y build-dep fio && \ apt-get -y build-dep fio && \
apt-get --download-only source fio apt-get --download-only source fio
+4 -4
View File
@@ -25,7 +25,7 @@ Most of them can be set in /etc/vitastor/vitastor.conf and in etcd, but don't su
- [vault_timeout_ms](#vault_timeout_ms) - [vault_timeout_ms](#vault_timeout_ms)
- [vault_error_timeout_sec](#vault_error_timeout_sec) - [vault_error_timeout_sec](#vault_error_timeout_sec)
- [vault_refresh_leeway_sec](#vault_refresh_leeway_sec) - [vault_refresh_leeway_sec](#vault_refresh_leeway_sec)
- [max_cipher_pool_size](#max_cipher_pool_size) - [max_aes_xts_pool_size](#max_aes_xts_pool_size)
## etcd_client_cert ## etcd_client_cert
@@ -141,10 +141,10 @@ Time (in seconds) to wait before retrying after receiving an error from Vault.
Extra time (in seconds) before real Vault token lease_timeout to refresh it, just Extra time (in seconds) before real Vault token lease_timeout to refresh it, just
in case of system clock drift. in case of system clock drift.
## max_cipher_pool_size ## max_aes_xts_pool_size
- Type: integer - Type: integer
- Default: 256 - Default: 256
Maximum number of OpenSSL cipher contexts cached in OSD memory, counted separately Maximum number of OpenSSL encryption contexts cached in OSD memory. Probably
for each cipher and for encryption/decryption. Probably doesn't require modification. doesn't require modification.
+4 -4
View File
@@ -27,7 +27,7 @@ OSD, мониторами и клиентами.
- [vault_timeout_ms](#vault_timeout_ms) - [vault_timeout_ms](#vault_timeout_ms)
- [vault_error_timeout_sec](#vault_error_timeout_sec) - [vault_error_timeout_sec](#vault_error_timeout_sec)
- [vault_refresh_leeway_sec](#vault_refresh_leeway_sec) - [vault_refresh_leeway_sec](#vault_refresh_leeway_sec)
- [max_cipher_pool_size](#max_cipher_pool_size) - [max_aes_xts_pool_size](#max_aes_xts_pool_size)
## etcd_client_cert ## etcd_client_cert
@@ -145,10 +145,10 @@ OSD, клиенты и мониторы должны иметь разные п
Зазор времени (в секундах), чтобы обновлять токены Vault чуть раньше их реального Зазор времени (в секундах), чтобы обновлять токены Vault чуть раньше их реального
lease_timeout, на случай "ухода" системных часов. lease_timeout, на случай "ухода" системных часов.
## max_cipher_pool_size ## max_aes_xts_pool_size
- Тип: целое число - Тип: целое число
- Значение по умолчанию: 256 - Значение по умолчанию: 256
Максимальное количество кэшируемых в памяти OSD контекстов шифра OpenSSL, учитываемое Максимальное количество кэшируемых в памяти OSD контекстов шифрования OpenSSL.
отдельно для каждого шифра и для шифрования и расшифровки. Вряд ли требует изменения. Вряд ли требует изменения.
+5 -5
View File
@@ -120,12 +120,12 @@
info_ru: | info_ru: |
Зазор времени (в секундах), чтобы обновлять токены Vault чуть раньше их реального Зазор времени (в секундах), чтобы обновлять токены Vault чуть раньше их реального
lease_timeout, на случай "ухода" системных часов. lease_timeout, на случай "ухода" системных часов.
- name: max_cipher_pool_size - name: max_aes_xts_pool_size
type: int type: int
default: 256 default: 256
info: | info: |
Maximum number of OpenSSL cipher contexts cached in OSD memory, counted separately Maximum number of OpenSSL encryption contexts cached in OSD memory. Probably
for each cipher and for encryption/decryption. Probably doesn't require modification. doesn't require modification.
info_ru: | info_ru: |
Максимальное количество кэшируемых в памяти OSD контекстов шифра OpenSSL, учитываемое Максимальное количество кэшируемых в памяти OSD контекстов шифрования OpenSSL.
отдельно для каждого шифра и для шифрования и расшифровки. Вряд ли требует изменения. Вряд ли требует изменения.
+3 -5
View File
@@ -69,17 +69,15 @@ pkg_check_modules(ISAL libisal)
if (ISAL_LIBRARIES) if (ISAL_LIBRARIES)
add_definitions(-DWITH_ISAL) add_definitions(-DWITH_ISAL)
endif (ISAL_LIBRARIES) endif (ISAL_LIBRARIES)
pkg_check_modules(ISAL_CRYPTO libisal_crypto)
if (ISAL_CRYPTO_LIBRARIES)
add_definitions(-DWITH_ISAL_CRYPTO)
endif (ISAL_CRYPTO_LIBRARIES)
pkg_check_modules(RDMACM librdmacm) pkg_check_modules(RDMACM librdmacm)
if (RDMACM_LIBRARIES) if (RDMACM_LIBRARIES)
add_definitions(-DWITH_RDMACM) add_definitions(-DWITH_RDMACM)
endif (RDMACM_LIBRARIES) endif (RDMACM_LIBRARIES)
find_package(OpenSSL REQUIRED) find_package(OpenSSL REQUIRED)
add_definitions(-DWITH_OPENSSL) if (OPENSSL_FOUND)
add_definitions(-DWITH_OPENSSL)
endif (OPENSSL_FOUND)
pkg_check_modules(CARES REQUIRED libcares) pkg_check_modules(CARES REQUIRED libcares)
include_directories(${CARES_INCLUDE_DIRS}) include_directories(${CARES_INCLUDE_DIRS})
+2 -3
View File
@@ -16,7 +16,7 @@ add_library(vitastor_common STATIC
msgr_encrypt.cpp msgr_stop.cpp msgr_op.cpp msgr_send.cpp msgr_receive.cpp ../util/ringloop.cpp ../../json11/json11.cpp msgr_encrypt.cpp msgr_stop.cpp msgr_op.cpp msgr_send.cpp msgr_receive.cpp ../util/ringloop.cpp ../../json11/json11.cpp
http_client.cpp osd_ops.cpp pg_states.cpp ../util/timerfd_manager.cpp ../util/str_util.cpp ../util/json_util.cpp ${MSGR_RDMA} ${MSGR_RDMACM} http_client.cpp osd_ops.cpp pg_states.cpp ../util/timerfd_manager.cpp ../util/str_util.cpp ../util/json_util.cpp ${MSGR_RDMA} ${MSGR_RDMACM}
) )
target_link_libraries(vitastor_common pthread ${OPENSSL_LIBRARIES} ${CARES_LIBRARIES} ${ISAL_CRYPTO_LIBRARIES}) target_link_libraries(vitastor_common pthread ${OPENSSL_LIBRARIES} ${CARES_LIBRARIES})
target_compile_options(vitastor_common PUBLIC -fPIC) target_compile_options(vitastor_common PUBLIC -fPIC)
# libvitastor_client.so # libvitastor_client.so
@@ -35,7 +35,6 @@ target_link_libraries(vitastor_client
${IBVERBS_LIBRARIES} ${IBVERBS_LIBRARIES}
${RDMACM_LIBRARIES} ${RDMACM_LIBRARIES}
${OPENSSL_LIBRARIES} ${OPENSSL_LIBRARIES}
${ISAL_CRYPTO_LIBRARIES}
) )
set_target_properties(vitastor_client PROPERTIES VERSION ${VITASTOR_VERSION} SOVERSION 0) set_target_properties(vitastor_client PROPERTIES VERSION ${VITASTOR_VERSION} SOVERSION 0)
configure_file(vitastor.pc.in vitastor.pc @ONLY) configure_file(vitastor.pc.in vitastor.pc @ONLY)
@@ -104,7 +103,7 @@ add_executable(test_cluster_client
pg_states.cpp osd_ops.cpp cluster_client.cpp cluster_client_list.cpp cluster_client_wb.cpp cluster_client_icache.cpp msgr_op.cpp ../test/mock/messenger.cpp msgr_stop.cpp msgr_encrypt.cpp pg_states.cpp osd_ops.cpp cluster_client.cpp cluster_client_list.cpp cluster_client_wb.cpp cluster_client_icache.cpp msgr_op.cpp ../test/mock/messenger.cpp msgr_stop.cpp msgr_encrypt.cpp
etcd_state_client.cpp ../util/timerfd_manager.cpp ../util/addr_util.cpp ../util/str_util.cpp ../util/json_util.cpp ../util/xxh_x86dispatch.c ../../json11/json11.cpp etcd_state_client.cpp ../util/timerfd_manager.cpp ../util/addr_util.cpp ../util/str_util.cpp ../util/json_util.cpp ../util/xxh_x86dispatch.c ../../json11/json11.cpp
) )
target_link_libraries(test_cluster_client ${OPENSSL_LIBRARIES} ${ISAL_CRYPTO_LIBRARIES}) target_link_libraries(test_cluster_client ${OPENSSL_LIBRARIES})
target_compile_definitions(test_cluster_client PUBLIC -D__MOCK__) target_compile_definitions(test_cluster_client PUBLIC -D__MOCK__)
target_include_directories(test_cluster_client BEFORE PUBLIC ${CMAKE_SOURCE_DIR}/src/test/mock) target_include_directories(test_cluster_client BEFORE PUBLIC ${CMAKE_SOURCE_DIR}/src/test/mock)
add_dependencies(build_tests test_cluster_client) add_dependencies(build_tests test_cluster_client)
+32 -31
View File
@@ -16,10 +16,12 @@
#include "msgr_rdma.h" #include "msgr_rdma.h"
#endif #endif
#include "http_client.h" #include "http_client.h"
#ifdef WITH_OPENSSL
#include <openssl/bio.h> #include <openssl/bio.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#endif
#include <sys/poll.h> #include <sys/poll.h>
@@ -126,6 +128,11 @@ void osd_messenger_t::init()
if (!tls_cert.empty() || !tls_key.empty() || !osd_tls_ca.empty() || !client_tls_ca.empty()) if (!tls_cert.empty() || !tls_key.empty() || !osd_tls_ca.empty() || !client_tls_ca.empty())
{ {
// Initialize TLS context // Initialize TLS context
// FIXME: require OpenSSL
#ifndef WITH_OPENSSL
fprintf(stderr, "Vitastor is built without OpenSSL support\n");
exit(1);
#else
if (tls_cert.empty() || tls_key.empty() || osd_tls_ca.empty() || osd_num && client_tls_ca.empty()) if (tls_cert.empty() || tls_key.empty() || osd_tls_ca.empty() || osd_num && client_tls_ca.empty())
{ {
if (osd_num) if (osd_num)
@@ -160,6 +167,7 @@ init_err:
goto init_err; goto init_err;
} }
} }
#endif
} }
#ifdef WITH_RDMACM #ifdef WITH_RDMACM
if (use_rdmacm) if (use_rdmacm)
@@ -339,38 +347,21 @@ osd_messenger_t::~osd_messenger_t()
rdmacm_evch = NULL; rdmacm_evch = NULL;
} }
#endif #endif
for (auto encrypt_ctx: encrypt_xts_pool) for (auto encrypt_ctx: encrypt_ctx_pool)
{ {
destroy_aes_xts_encrypt(encrypt_ctx); destroy_aes_xts_encrypt(encrypt_ctx);
} }
for (auto decrypt_ctx: decrypt_xts_pool) for (auto decrypt_ctx: decrypt_ctx_pool)
{ {
destroy_aes_xts_decrypt(decrypt_ctx); destroy_aes_xts_decrypt(decrypt_ctx);
} }
#ifdef WITH_ISAL_CRYPTO #ifdef WITH_OPENSSL
for (isal_gcm_context_data *ctx: encrypt_gcm_pool)
{
free(ctx);
}
for (isal_gcm_context_data *ctx: decrypt_gcm_pool)
{
free(ctx);
}
#else
for (EVP_CIPHER_CTX *ctx: encrypt_gcm_pool)
{
EVP_CIPHER_CTX_free(ctx);
}
for (EVP_CIPHER_CTX *ctx: decrypt_gcm_pool)
{
EVP_CIPHER_CTX_free(ctx);
}
#endif
if (ssl_ctx) if (ssl_ctx)
{ {
SSL_CTX_free(ssl_ctx); SSL_CTX_free(ssl_ctx);
ssl_ctx = NULL; ssl_ctx = NULL;
} }
#endif
} }
void osd_messenger_t::parse_config(const json11::Json & config) void osd_messenger_t::parse_config(const json11::Json & config)
@@ -405,9 +396,9 @@ void osd_messenger_t::parse_config(const json11::Json & config)
if (!this->rdma_max_msg || this->rdma_max_msg > 128*1024*1024) if (!this->rdma_max_msg || this->rdma_max_msg > 128*1024*1024)
this->rdma_max_msg = 129*1024; this->rdma_max_msg = 129*1024;
#endif #endif
this->max_cipher_pool_size = config["max_cipher_pool_size"].uint64_value(); this->max_aes_xts_pool_size = config["max_aes_xts_pool_size"].uint64_value();
if (!this->max_cipher_pool_size) if (!this->max_aes_xts_pool_size)
this->max_cipher_pool_size = 256; this->max_aes_xts_pool_size = 256;
if (config["proto_checksums"].is_null()) if (config["proto_checksums"].is_null())
this->use_proto_checksums = MSGR_CSUM_PAYLOAD; this->use_proto_checksums = MSGR_CSUM_PAYLOAD;
else if (config["proto_checksums"].is_bool()) else if (config["proto_checksums"].is_bool())
@@ -432,12 +423,6 @@ void osd_messenger_t::parse_config(const json11::Json & config)
test_osd_aes_key.resize(32); test_osd_aes_key.resize(32);
if (fromhexstr(config["test_osd_aes_key"].string_value(), 32, (uint8_t*)test_osd_aes_key.data()) != 32) if (fromhexstr(config["test_osd_aes_key"].string_value(), 32, (uint8_t*)test_osd_aes_key.data()) != 32)
test_osd_aes_key.clear(); test_osd_aes_key.clear();
else
{
#ifdef WITH_ISAL_CRYPTO
isal_aes_gcm_pre_256(test_osd_aes_key.data(), &test_osd_aes_key_isal);
#endif
}
if (!osd_num) if (!osd_num)
this->iothread_count = (uint32_t)config["client_iothread_count"].uint64_value(); this->iothread_count = (uint32_t)config["client_iothread_count"].uint64_value();
else else
@@ -951,7 +936,23 @@ void osd_messenger_t::ssl_init(osd_client_t *cl, bool server_mode)
} }
else if (!test_osd_aes_key.empty()) else if (!test_osd_aes_key.empty())
{ {
cl->gcm_enabled = true; int r;
cl->enc_ctx = EVP_CIPHER_CTX_new();
assert(cl->enc_ctx);
r = EVP_EncryptInit_ex(cl->enc_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
assert(r == 1);
r = EVP_CIPHER_CTX_set_padding(cl->enc_ctx, 0);
assert(r == 1);
r = EVP_CIPHER_CTX_ctrl(cl->enc_ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL);
assert(r == 1);
cl->dec_ctx = EVP_CIPHER_CTX_new();
assert(cl->dec_ctx);
r = EVP_DecryptInit_ex(cl->dec_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
assert(r == 1);
r = EVP_CIPHER_CTX_set_padding(cl->dec_ctx, 0);
assert(r == 1);
r = EVP_CIPHER_CTX_ctrl(cl->dec_ctx, EVP_CTRL_GCM_SET_IVLEN, 12, NULL);
assert(r == 1);
} }
} }
+16 -26
View File
@@ -12,10 +12,8 @@
#include <deque> #include <deque>
#include <vector> #include <vector>
#ifdef WITH_OPENSSL
#include <openssl/types.h> #include <openssl/types.h>
#ifdef WITH_ISAL_CRYPTO
#include <isa-l_crypto/aes_gcm.h>
#endif #endif
#include "../util/xxh_x86dispatch.h" #include "../util/xxh_x86dispatch.h"
@@ -92,6 +90,7 @@ struct osd_client_t
msgr_rdma_connection_t *rdma_conn = NULL; msgr_rdma_connection_t *rdma_conn = NULL;
#endif #endif
#ifdef WITH_OPENSSL
SSL *ssl_cli = NULL; SSL *ssl_cli = NULL;
BIO *write_to_ssl = NULL; BIO *write_to_ssl = NULL;
// FIXME: use custom bio to avoid 1 more memory copy? // FIXME: use custom bio to avoid 1 more memory copy?
@@ -103,18 +102,17 @@ struct osd_client_t
size_t ssl_read_header_size = 0; size_t ssl_read_header_size = 0;
bool ssl_more_to_buffer = false; bool ssl_more_to_buffer = false;
bool gcm_enabled = false;
#ifdef WITH_ISAL_CRYPTO
isal_gcm_context_data *enc_ctx = NULL;
isal_gcm_context_data *dec_ctx = NULL;
#else
EVP_CIPHER_CTX *enc_ctx = NULL; EVP_CIPHER_CTX *enc_ctx = NULL;
EVP_CIPHER_CTX *dec_ctx = NULL;
#endif
uint8_t enc_tag[16]; uint8_t enc_tag[16];
size_t enc_tag_size = 0; size_t enc_tag_size = 0;
bool enc_batch = false;
EVP_CIPHER_CTX *dec_ctx = NULL;
uint8_t dec_tag[16]; uint8_t dec_tag[16];
size_t dec_tag_size = 0; size_t dec_tag_size = 0;
uint32_t dec_batch_size = 0;
size_t dec_batch_size_size = 0;
std::vector<osd_op_t*> unverified_ops;
#endif
// Read state // Read state
bool io_error = false; bool io_error = false;
@@ -129,7 +127,7 @@ struct osd_client_t
uint64_t read_op_id = 1; uint64_t read_op_id = 1;
bool check_sequencing = false; bool check_sequencing = false;
bool enable_pg_locks = false; bool enable_pg_locks = false;
op_aes_xts_decrypt_t *xts_dec_ctx = NULL; op_aes_xts_decrypt_t *decrypt_ctx = NULL;
size_t read_op_inline_decrypt_pos = 0; size_t read_op_inline_decrypt_pos = 0;
size_t read_op_inline_decrypt_in = 0; size_t read_op_inline_decrypt_in = 0;
int proto_csum_status = 0; int proto_csum_status = 0;
@@ -155,7 +153,7 @@ struct osd_client_t
size_t send_list_size = 0; size_t send_list_size = 0;
std::deque<osd_op_t*> send_free_ops; std::deque<osd_op_t*> send_free_ops;
std::vector<osd_op_t*> zc_free_list; std::vector<osd_op_t*> zc_free_list;
op_aes_xts_encrypt_t *xts_enc_ctx = NULL; op_aes_xts_encrypt_t *encrypt_ctx = NULL;
XXH3_state_t* write_csum_state = NULL; XXH3_state_t* write_csum_state = NULL;
~osd_client_t(); ~osd_client_t();
@@ -260,16 +258,13 @@ protected:
bool use_sync_send_recv = false; bool use_sync_send_recv = false;
int min_zerocopy_send_size = DEFAULT_MIN_ZEROCOPY_SEND_SIZE; int min_zerocopy_send_size = DEFAULT_MIN_ZEROCOPY_SEND_SIZE;
int iothread_count = 0; int iothread_count = 0;
int max_cipher_pool_size = 256; int max_aes_xts_pool_size = 256;
std::string tls_cert; std::string tls_cert;
std::string tls_key; std::string tls_key;
std::string osd_tls_ca; std::string osd_tls_ca;
std::string client_tls_ca; std::string client_tls_ca;
std::string test_osd_aes_key; // FIXME Insecure, only for PoC tests std::string test_osd_aes_key; // FIXME Insecure, only for PoC tests
#ifdef WITH_ISAL_CRYPTO
isal_gcm_key_data test_osd_aes_key_isal;
#endif
#ifdef WITH_RDMA #ifdef WITH_RDMA
bool use_rdma = true; bool use_rdma = true;
@@ -287,11 +282,13 @@ protected:
robin_hood::unordered_flat_map<rdma_cm_id*, rdmacm_connecting_t*> rdmacm_connecting; robin_hood::unordered_flat_map<rdma_cm_id*, rdmacm_connecting_t*> rdmacm_connecting;
#endif #endif
#ifdef WITH_OPENSSL
SSL_CTX *ssl_ctx = NULL; SSL_CTX *ssl_ctx = NULL;
std::string tls_cn; std::string tls_cn;
void ssl_init(osd_client_t *cl, bool server_mode); void ssl_init(osd_client_t *cl, bool server_mode);
bool ssl_do_handshake(osd_client_t *cl); bool ssl_do_handshake(osd_client_t *cl);
#endif
std::vector<msgr_iothread_t*> iothreads; std::vector<msgr_iothread_t*> iothreads;
std::vector<uint64_t> read_ready_clients; std::vector<uint64_t> read_ready_clients;
@@ -299,16 +296,8 @@ protected:
// We don't use ringloop->set_immediate here because we may have no ringloop in client :) // We don't use ringloop->set_immediate here because we may have no ringloop in client :)
std::deque<osd_op_t*> set_immediate_ops; std::deque<osd_op_t*> set_immediate_ops;
std::vector<op_aes_xts_encrypt_t*> encrypt_xts_pool; std::vector<op_aes_xts_encrypt_t*> encrypt_ctx_pool;
std::vector<op_aes_xts_decrypt_t*> decrypt_xts_pool; std::vector<op_aes_xts_decrypt_t*> decrypt_ctx_pool;
#ifdef WITH_ISAL_CRYPTO
std::vector<isal_gcm_context_data*> encrypt_gcm_pool;
std::vector<isal_gcm_context_data*> decrypt_gcm_pool;
#else
std::vector<EVP_CIPHER_CTX*> encrypt_gcm_pool;
std::vector<EVP_CIPHER_CTX*> decrypt_gcm_pool;
#endif
public: public:
timerfd_manager_t *tfd = NULL; timerfd_manager_t *tfd = NULL;
@@ -392,6 +381,7 @@ protected:
bool allocate_reply_buffers(osd_client_t *cl, osd_op_t *op); bool allocate_reply_buffers(osd_client_t *cl, osd_op_t *op);
bool op_read_from(osd_client_t *cl, msgr_op_reader_t & rdr); bool op_read_from(osd_client_t *cl, msgr_op_reader_t & rdr);
bool handle_finished_op(osd_client_t *cl); bool handle_finished_op(osd_client_t *cl);
void execute_verified_op(osd_client_t *cl, osd_op_t *op);
void handle_immediate_ops(); void handle_immediate_ops();
void op_encrypted_copy_buf(osd_client_t *cl, uint8_t *enc_buf, size_t enc_len, uint8_t *plain, size_t plain_len, size_t & done_plain, size_t & done_enc); void op_encrypted_copy_buf(osd_client_t *cl, uint8_t *enc_buf, size_t enc_len, uint8_t *plain, size_t plain_len, size_t & done_plain, size_t & done_enc);
+53 -67
View File
@@ -3,17 +3,13 @@
#include <assert.h> #include <assert.h>
#ifdef WITH_ISAL_CRYPTO
#include <isa-l_crypto/isal_crypto_api.h>
#endif
#include "etcd_state_client.h" #include "etcd_state_client.h"
#include "messenger.h" #include "messenger.h"
#include "msgr_encrypt.h" #include "msgr_encrypt.h"
op_aes_xts_encrypt_t::op_aes_xts_encrypt_t() op_aes_xts_encrypt_t::op_aes_xts_encrypt_t()
{ {
#ifndef WITH_ISAL_CRYPTO #ifdef WITH_OPENSSL
if (!(ctx = EVP_CIPHER_CTX_new())) if (!(ctx = EVP_CIPHER_CTX_new()))
{ {
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
@@ -25,13 +21,16 @@ op_aes_xts_encrypt_t::op_aes_xts_encrypt_t()
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
abort(); abort();
} }
#else
fprintf(stderr, "Error: Vitastor is built without encryption support\n");
abort();
#endif #endif
} }
op_aes_xts_encrypt_t::~op_aes_xts_encrypt_t() op_aes_xts_encrypt_t::~op_aes_xts_encrypt_t()
{ {
assert(!encrypted); assert(!encrypted);
#ifndef WITH_ISAL_CRYPTO #ifdef WITH_OPENSSL
EVP_CIPHER_CTX_free(ctx); EVP_CIPHER_CTX_free(ctx);
#endif #endif
if (tmp) if (tmp)
@@ -53,7 +52,7 @@ void op_aes_xts_encrypt_t::start(uint8_t *key, uint64_t start_offset, size_t blo
tmp = NULL; tmp = NULL;
tmp_size = 0; tmp_size = 0;
} }
#ifndef WITH_ISAL_CRYPTO #ifdef WITH_OPENSSL
if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL) != 1) if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, NULL) != 1)
{ {
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
@@ -64,12 +63,9 @@ void op_aes_xts_encrypt_t::start(uint8_t *key, uint64_t start_offset, size_t blo
void op_aes_xts_encrypt_t::encrypt_block(uint8_t *in, uint8_t *out) void op_aes_xts_encrypt_t::encrypt_block(uint8_t *in, uint8_t *out)
{ {
#ifdef WITH_OPENSSL
uint8_t iv[16] = { 0 }; uint8_t iv[16] = { 0 };
*((uint64_t*)iv) = start_offset + offset - offset%block_size; *((uint64_t*)iv) = start_offset + offset - offset%block_size;
#ifdef WITH_ISAL_CRYPTO
int r = isal_aes_xts_enc_256(key+32, key, iv, block_size, in, out);
assert(r == 0 || r == ISAL_CRYPTO_ERR_XTS_SAME_KEYS);
#else
if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) != 1) if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) != 1)
{ {
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
@@ -102,10 +98,7 @@ void op_aes_xts_encrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size
done_out += max_out; done_out += max_out;
tmp_pos += max_out; tmp_pos += max_out;
if (tmp_pos >= block_size) if (tmp_pos >= block_size)
{
encrypted = false; encrypted = false;
done_in += 1;
}
} }
else if (max_in < block_size - offset%block_size) else if (max_in < block_size - offset%block_size)
{ {
@@ -133,7 +126,7 @@ void op_aes_xts_encrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size
encrypted = true; encrypted = true;
memcpy(out, tmp, max_out); memcpy(out, tmp, max_out);
tmp_pos = max_out; tmp_pos = max_out;
done_in += max_in-1; done_in += max_in;
offset += max_in; offset += max_in;
done_out += max_out; done_out += max_out;
} }
@@ -165,7 +158,7 @@ void destroy_aes_xts_encrypt(op_aes_xts_encrypt_t *encrypt_ctx)
op_aes_xts_decrypt_t::op_aes_xts_decrypt_t() op_aes_xts_decrypt_t::op_aes_xts_decrypt_t()
{ {
#ifndef WITH_ISAL_CRYPTO #ifdef WITH_OPENSSL
if (!(ctx = EVP_CIPHER_CTX_new())) if (!(ctx = EVP_CIPHER_CTX_new()))
{ {
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
@@ -177,13 +170,16 @@ op_aes_xts_decrypt_t::op_aes_xts_decrypt_t()
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
abort(); abort();
} }
#else
fprintf(stderr, "Error: Vitastor is built without encryption support\n");
abort();
#endif #endif
} }
op_aes_xts_decrypt_t::~op_aes_xts_decrypt_t() op_aes_xts_decrypt_t::~op_aes_xts_decrypt_t()
{ {
assert(!decrypted); assert(!decrypted);
#ifndef WITH_ISAL_CRYPTO #ifdef WITH_OPENSSL
EVP_CIPHER_CTX_free(ctx); EVP_CIPHER_CTX_free(ctx);
#endif #endif
if (tmp) if (tmp)
@@ -194,9 +190,9 @@ void op_aes_xts_decrypt_t::start(uint8_t **key_chain, size_t chain_size, void *k
{ {
assert(!decrypted); assert(!decrypted);
this->start_offset = start_offset; this->start_offset = start_offset;
this->key_chain = key_chain; this->key_chain = chain_size > 1 ? key_chain : 0;
this->chain_size = chain_size; this->chain_size = chain_size > 1 ? chain_size : 0;
this->key_indexes = key_indexes; this->key_indexes = chain_size > 1 ? key_indexes : NULL;
this->key_index_bytes = osd_op_rw_t::chain_info_bytes(chain_size); this->key_index_bytes = osd_op_rw_t::chain_info_bytes(chain_size);
assert(chain_size <= 1 || key_indexes != NULL); assert(chain_size <= 1 || key_indexes != NULL);
this->block_size = block_size; this->block_size = block_size;
@@ -208,7 +204,7 @@ void op_aes_xts_decrypt_t::start(uint8_t **key_chain, size_t chain_size, void *k
tmp = NULL; tmp = NULL;
tmp_size = 0; tmp_size = 0;
} }
#ifndef WITH_ISAL_CRYPTO #ifdef WITH_OPENSSL
if (chain_size == 1 && key_chain[0] && EVP_DecryptInit_ex(ctx, NULL, NULL, key_chain[0], NULL) != 1) if (chain_size == 1 && key_chain[0] && EVP_DecryptInit_ex(ctx, NULL, NULL, key_chain[0], NULL) != 1)
{ {
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
@@ -220,7 +216,7 @@ void op_aes_xts_decrypt_t::start(uint8_t **key_chain, size_t chain_size, void *k
void op_aes_xts_decrypt_t::decrypt_block(uint8_t *in, uint8_t *out) void op_aes_xts_decrypt_t::decrypt_block(uint8_t *in, uint8_t *out)
{ {
uint8_t *key = NULL; uint8_t *key = NULL;
if (chain_size > 1) if (chain_size)
{ {
uint32_t key_index = key_index_bytes == 1 uint32_t key_index = key_index_bytes == 1
? ((uint8_t*)key_indexes)[offset/block_size] ? ((uint8_t*)key_indexes)[offset/block_size]
@@ -231,24 +227,17 @@ void op_aes_xts_decrypt_t::decrypt_block(uint8_t *in, uint8_t *out)
: UINT32_MAX)); : UINT32_MAX));
assert(key_index < chain_size); assert(key_index < chain_size);
key = key_chain[key_index]; key = key_chain[key_index];
if (!key)
{
if (in != out)
memcpy(out, in, block_size);
return;
}
} }
else #ifdef WITH_OPENSSL
{
key = key_chain[0];
}
if (!key)
{
if (in != out)
memcpy(out, in, block_size);
return;
}
uint8_t iv[16] = { 0 }; uint8_t iv[16] = { 0 };
*((uint64_t*)iv) = start_offset + offset - offset%block_size; *((uint64_t*)iv) = start_offset + offset - offset%block_size;
#ifdef WITH_ISAL_CRYPTO if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv) != 1)
int r = isal_aes_xts_dec_256(key+32, key, iv, block_size, in, out);
assert(r == 0 || r == ISAL_CRYPTO_ERR_XTS_SAME_KEYS);
#else
if (EVP_DecryptInit_ex(ctx, NULL, NULL, chain_size == 1 ? NULL : key, iv) != 1)
{ {
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
abort(); abort();
@@ -283,10 +272,7 @@ void op_aes_xts_decrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size
done_out += max_out; done_out += max_out;
tmp_pos += max_out; tmp_pos += max_out;
if (tmp_pos >= block_size) if (tmp_pos >= block_size)
{
decrypted = false; decrypted = false;
done_in += 1;
}
} }
else if (max_in < block_size - offset%block_size) else if (max_in < block_size - offset%block_size)
{ {
@@ -315,7 +301,7 @@ void op_aes_xts_decrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size
if (out) if (out)
memcpy(out, tmp, max_out); memcpy(out, tmp, max_out);
tmp_pos = max_out; tmp_pos = max_out;
done_in += max_in-1; done_in += max_in;
offset += max_in; offset += max_in;
done_out += max_out; done_out += max_out;
} }
@@ -349,23 +335,23 @@ void destroy_aes_xts_decrypt(op_aes_xts_decrypt_t *decrypt_ctx)
void osd_messenger_t::op_encrypted_copy_buf(osd_client_t *cl, uint8_t *enc_buf, size_t enc_len, uint8_t *plain, size_t plain_len, size_t & done_plain, size_t & done_enc) void osd_messenger_t::op_encrypted_copy_buf(osd_client_t *cl, uint8_t *enc_buf, size_t enc_len, uint8_t *plain, size_t plain_len, size_t & done_plain, size_t & done_enc)
{ {
if (!cl->xts_enc_ctx) if (!cl->encrypt_ctx)
{ {
if (encrypt_xts_pool.size()) if (encrypt_ctx_pool.size())
{ {
cl->xts_enc_ctx = encrypt_xts_pool.back(); cl->encrypt_ctx = encrypt_ctx_pool.back();
encrypt_xts_pool.pop_back(); encrypt_ctx_pool.pop_back();
} }
else else
cl->xts_enc_ctx = new op_aes_xts_encrypt_t(); cl->encrypt_ctx = new op_aes_xts_encrypt_t();
assert(cl->write_op->enc->key_chain[0]); assert(cl->write_op->enc->key_chain[0]);
cl->xts_enc_ctx->start(cl->write_op->enc->key_chain[0], cl->write_op->req.rw.offset, cl->write_op->enc->bitmap_granularity); cl->encrypt_ctx->start(cl->write_op->enc->key_chain[0], cl->write_op->req.rw.offset, cl->write_op->enc->bitmap_granularity);
} }
while (done_plain < plain_len && done_enc < enc_len) while (done_enc < enc_len && (done_plain < plain_len || cl->encrypt_ctx->has_buffered()))
{ {
size_t done_in = 0; size_t done_in = 0;
size_t done_out = 0; size_t done_out = 0;
cl->xts_enc_ctx->update(plain+done_plain, plain_len-done_plain, enc_buf+done_enc, enc_len-done_enc, done_in, done_out); cl->encrypt_ctx->update(plain+done_plain, plain_len-done_plain, enc_buf+done_enc, enc_len-done_enc, done_in, done_out);
if (cl->write_csum_state && done_out > 0) if (cl->write_csum_state && done_out > 0)
XXH3_64bits_update(cl->write_csum_state, enc_buf+done_enc, done_out); XXH3_64bits_update(cl->write_csum_state, enc_buf+done_enc, done_out);
done_enc += done_out; done_enc += done_out;
@@ -382,7 +368,7 @@ void osd_messenger_t::op_decrypted_copy_buf(osd_client_t *cl, uint8_t *enc_buf,
size_t done_in = 0; size_t done_in = 0;
size_t done_out = 0; size_t done_out = 0;
// plain == NULL means skip output // plain == NULL means skip output
cl->xts_dec_ctx->update(enc_buf+done_enc, enc_len-done_enc, plain ? plain+done_plain : NULL, plain_len-done_plain, done_in, done_out); cl->decrypt_ctx->update(enc_buf+done_enc, enc_len-done_enc, plain ? plain+done_plain : NULL, plain_len-done_plain, done_in, done_out);
if (cl->read_csum_state && done_in > 0) if (cl->read_csum_state && done_in > 0)
XXH3_64bits_update(cl->read_csum_state, enc_buf+done_enc, done_in); XXH3_64bits_update(cl->read_csum_state, enc_buf+done_enc, done_in);
done_enc += done_in; done_enc += done_in;
@@ -394,18 +380,18 @@ void osd_messenger_t::op_decrypted_copy_buf(osd_client_t *cl, uint8_t *enc_buf,
void osd_messenger_t::op_decrypt_start(osd_client_t* cl) void osd_messenger_t::op_decrypt_start(osd_client_t* cl)
{ {
if (!cl->xts_dec_ctx) if (!cl->decrypt_ctx)
{ {
if (decrypt_xts_pool.size()) if (decrypt_ctx_pool.size())
{ {
cl->xts_dec_ctx = decrypt_xts_pool.back(); cl->decrypt_ctx = decrypt_ctx_pool.back();
decrypt_xts_pool.pop_back(); decrypt_ctx_pool.pop_back();
} }
else else
cl->xts_dec_ctx = new op_aes_xts_decrypt_t(); cl->decrypt_ctx = new op_aes_xts_decrypt_t();
auto & enc = cl->read_op->enc; auto & enc = cl->read_op->enc;
assert(cl->read_op->req.hdr.opcode == OSD_OP_READ); assert(cl->read_op->req.hdr.opcode == OSD_OP_READ);
cl->xts_dec_ctx->start(enc->key_chain, enc->chain_size, cl->decrypt_ctx->start(enc->key_chain, enc->chain_size,
(cl->read_op->req.rw.flags & OSD_OP_RETURN_CHAIN) ? (uint8_t*)cl->read_op->bitmap + enc->read_chain_bitmap_pos : 0, (cl->read_op->req.rw.flags & OSD_OP_RETURN_CHAIN) ? (uint8_t*)cl->read_op->bitmap + enc->read_chain_bitmap_pos : 0,
cl->read_op->req.rw.offset, enc->bitmap_granularity); cl->read_op->req.rw.offset, enc->bitmap_granularity);
} }
@@ -437,7 +423,7 @@ void osd_messenger_t::op_decrypt_inline(osd_client_t* cl)
size_t out_len = op->iov.buf[j].iov_len - from_out; size_t out_len = op->iov.buf[j].iov_len - from_out;
size_t done_in = 0; size_t done_in = 0;
size_t done_out = 0; size_t done_out = 0;
cl->xts_dec_ctx->update(in, in_len, out, out_len, done_in, done_out); cl->decrypt_ctx->update(in, in_len, out, out_len, done_in, done_out);
if (done_in >= in_len) if (done_in >= in_len)
{ {
i++; i++;
@@ -458,24 +444,24 @@ void osd_messenger_t::op_decrypt_inline(osd_client_t* cl)
void osd_messenger_t::op_decrypt_free(osd_client_t* cl) void osd_messenger_t::op_decrypt_free(osd_client_t* cl)
{ {
if (cl->xts_dec_ctx) if (cl->decrypt_ctx)
{ {
if (decrypt_xts_pool.size() > max_cipher_pool_size) if (decrypt_ctx_pool.size() > max_aes_xts_pool_size)
delete cl->xts_dec_ctx; delete cl->decrypt_ctx;
else else
decrypt_xts_pool.push_back(cl->xts_dec_ctx); decrypt_ctx_pool.push_back(cl->decrypt_ctx);
cl->xts_dec_ctx = NULL; cl->decrypt_ctx = NULL;
} }
} }
void osd_messenger_t::op_encrypt_free(osd_client_t* cl) void osd_messenger_t::op_encrypt_free(osd_client_t* cl)
{ {
if (cl->xts_enc_ctx) if (cl->encrypt_ctx)
{ {
if (encrypt_xts_pool.size() > max_cipher_pool_size) if (encrypt_ctx_pool.size() > max_aes_xts_pool_size)
delete cl->xts_enc_ctx; delete cl->encrypt_ctx;
else else
encrypt_xts_pool.push_back(cl->xts_enc_ctx); encrypt_ctx_pool.push_back(cl->encrypt_ctx);
cl->xts_enc_ctx = NULL; cl->encrypt_ctx = NULL;
} }
} }
+7 -6
View File
@@ -3,18 +3,17 @@
#include <stdint.h> #include <stdint.h>
#ifdef WITH_ISAL_CRYPTO
#include <isa-l_crypto/aes_xts.h>
#endif
#include "../util/xxh_x86dispatch.h" #include "../util/xxh_x86dispatch.h"
// WITH_OPENSSL is left to possibly support other crypto libraries
#ifdef WITH_OPENSSL
#include <openssl/conf.h> #include <openssl/conf.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/err.h> #include <openssl/err.h>
#endif
class op_aes_xts_encrypt_t class op_aes_xts_encrypt_t
{ {
#ifndef WITH_ISAL_CRYPTO #ifdef WITH_OPENSSL
EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *ctx = NULL;
#endif #endif
uint64_t start_offset = 0; uint64_t start_offset = 0;
@@ -32,6 +31,7 @@ public:
op_aes_xts_encrypt_t(); op_aes_xts_encrypt_t();
~op_aes_xts_encrypt_t(); ~op_aes_xts_encrypt_t();
inline bool has_buffered() { return encrypted; };
void start(uint8_t *key, uint64_t start_offset, size_t block_size); void start(uint8_t *key, uint64_t start_offset, size_t block_size);
void update(uint8_t *in, size_t max_in, uint8_t *out, size_t max_out, size_t & done_in, size_t & done_out); void update(uint8_t *in, size_t max_in, uint8_t *out, size_t max_out, size_t & done_in, size_t & done_out);
}; };
@@ -40,7 +40,7 @@ void destroy_aes_xts_encrypt(op_aes_xts_encrypt_t *encrypt_ctx);
class op_aes_xts_decrypt_t class op_aes_xts_decrypt_t
{ {
#ifndef WITH_ISAL_CRYPTO #ifdef WITH_OPENSSL
EVP_CIPHER_CTX *ctx = NULL; EVP_CIPHER_CTX *ctx = NULL;
#endif #endif
uint64_t start_offset = 0; uint64_t start_offset = 0;
@@ -61,6 +61,7 @@ public:
op_aes_xts_decrypt_t(); op_aes_xts_decrypt_t();
~op_aes_xts_decrypt_t(); ~op_aes_xts_decrypt_t();
inline bool has_buffered() { return decrypted; };
void start(uint8_t **key_chain, size_t chain_size, void *key_indexes, uint64_t start_offset, size_t block_size); void start(uint8_t **key_chain, size_t chain_size, void *key_indexes, uint64_t start_offset, size_t block_size);
void update(uint8_t *in, size_t max_in, uint8_t *out, size_t max_out, size_t & done_in, size_t & done_out); void update(uint8_t *in, size_t max_in, uint8_t *out, size_t max_out, size_t & done_in, size_t & done_out);
}; };
+80 -92
View File
@@ -5,10 +5,12 @@
#include <limits.h> #include <limits.h>
#include "messenger.h" #include "messenger.h"
#ifdef WITH_OPENSSL
#include <openssl/bio.h> #include <openssl/bio.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#endif
#define RDR_TLS 1 #define RDR_TLS 1
#define RDR_XTS 2 #define RDR_XTS 2
@@ -285,47 +287,6 @@ public:
void reset() void reset()
{ {
from = cl->read_op_pos; from = cl->read_op_pos;
if (!cl->dec_ctx)
{
if (msgr->decrypt_gcm_pool.size())
{
cl->dec_ctx = msgr->decrypt_gcm_pool.back();
msgr->decrypt_gcm_pool.pop_back();
}
else
{
#ifdef WITH_ISAL_CRYPTO
cl->dec_ctx = (isal_gcm_context_data*)malloc_or_die(sizeof(isal_gcm_context_data));
#else
cl->dec_ctx = EVP_CIPHER_CTX_new();
assert(cl->dec_ctx);
int r = EVP_DecryptInit_ex(cl->dec_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
if (r != 1)
{
fprintf(stderr, "DecryptInit error: ");
ERR_print_errors_fp(stderr);
abort();
}
#endif
}
}
uint8_t iv[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
#ifdef WITH_ISAL_CRYPTO
int r = isal_aes_gcm_init_256(&msgr->test_osd_aes_key_isal, cl->dec_ctx, iv, NULL, 0);
if (r != 0)
{
fprintf(stderr, "isal_aes_gcm_init_256 error %d\n", r);
abort();
}
#else
int r = EVP_DecryptInit_ex(cl->dec_ctx, NULL, NULL, (uint8_t*)msgr->test_osd_aes_key.data(), iv);
if (r != 1)
{
fprintf(stderr, "DecryptInit error: ");
ERR_print_errors_fp(stderr);
abort();
}
#endif
} }
bool read(uint8_t *dst, size_t dst_len, int flags) override bool read(uint8_t *dst, size_t dst_len, int flags) override
@@ -371,13 +332,34 @@ public:
{ {
// Here, dst == NULL is not allowed // Here, dst == NULL is not allowed
assert(dst != NULL); assert(dst != NULL);
if (cl->dec_batch_size_size < 4)
{
size_t n = 4-cl->dec_batch_size_size;
if (n > bufsize-done)
n = bufsize-done;
memcpy(&cl->dec_batch_size, curbuf+done, n);
cl->dec_batch_size_size += n;
done += n;
if (cl->dec_batch_size_size < 4)
return false;
if (!cl->dec_batch_size)
{
fprintf(stderr, "Client %ju - empty batch received, disconnecting\n", cl->client_id);
cl->io_error = true;
return false;
}
uint8_t iv[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
int r = EVP_DecryptInit_ex(cl->dec_ctx, NULL, NULL, (uint8_t*)msgr->test_osd_aes_key.data(), iv);
if (r != 1)
{
fprintf(stderr, "DecryptInit error: ");
ERR_print_errors_fp(stderr);
abort();
}
}
size_t n = dst_len-from; size_t n = dst_len-from;
if (n > bufsize-done) if (n > bufsize-done)
n = bufsize-done; n = bufsize-done;
#ifdef WITH_ISAL_CRYPTO
int r = isal_aes_gcm_dec_256_update(&msgr->test_osd_aes_key_isal, cl->dec_ctx, dst+from, curbuf+done, n);
assert(!r);
#else
int actual_out; int actual_out;
if (EVP_DecryptUpdate(cl->dec_ctx, dst+from, &actual_out, curbuf+done, n) != 1) if (EVP_DecryptUpdate(cl->dec_ctx, dst+from, &actual_out, curbuf+done, n) != 1)
{ {
@@ -386,7 +368,6 @@ public:
abort(); abort();
} }
assert(actual_out == n); assert(actual_out == n);
#endif
if (cl->read_csum_state && !(flags & RDR_NO_CSUM)) if (cl->read_csum_state && !(flags & RDR_NO_CSUM))
{ {
XXH3_64bits_update(cl->read_csum_state, dst+from, n); XXH3_64bits_update(cl->read_csum_state, dst+from, n);
@@ -405,6 +386,12 @@ public:
bool finish() override bool finish() override
{ {
if (cl->dec_batch_size > 1)
{
// No tag yet
cl->dec_batch_size--;
return true;
}
if (cl->dec_tag_size+bufsize-done < 16) if (cl->dec_tag_size+bufsize-done < 16)
{ {
// Buffer part of the tag // Buffer part of the tag
@@ -413,62 +400,33 @@ public:
done = bufsize; done = bufsize;
return false; return false;
} }
#ifdef WITH_ISAL_CRYPTO
uint8_t calc_tag[16];
int r = isal_aes_gcm_dec_256_finalize(&msgr->test_osd_aes_key_isal, cl->dec_ctx, calc_tag, 16);
assert(r == 0);
if (cl->dec_tag_size > 0)
{
// Tag is partially buffered, append to it and compare
memcpy(cl->dec_tag+cl->dec_tag_size, curbuf+done, 16-cl->dec_tag_size);
done += 16-cl->dec_tag_size;
r = !memcmp(calc_tag, cl->dec_tag, 16);
}
else
{
// Compare the full tag directly from the source buffer
r = !memcmp(calc_tag, curbuf+done, 16);
done += 16;
}
#else
int r; int r;
if (cl->dec_tag_size > 0) if (cl->dec_tag_size > 0)
{ {
// Tag is partially buffered, append to it and use it from there // Tag is partially buffered, append to it and use it from there
memcpy(cl->dec_tag+cl->dec_tag_size, curbuf+done, 16-cl->dec_tag_size); memcpy(cl->dec_tag+cl->dec_tag_size, curbuf+done, 16-cl->dec_tag_size);
r = EVP_CIPHER_CTX_ctrl(cl->dec_ctx, EVP_CTRL_GCM_SET_TAG, 16, cl->dec_tag);
assert(r == 1);
done += 16-cl->dec_tag_size; done += 16-cl->dec_tag_size;
r = EVP_CIPHER_CTX_ctrl(cl->dec_ctx, EVP_CTRL_GCM_SET_TAG, 16, cl->dec_tag);
} }
else else
{ {
// Take full tag directly from the source buffer // Take full tag directly from the source buffer
r = EVP_CIPHER_CTX_ctrl(cl->dec_ctx, EVP_CTRL_GCM_SET_TAG, 16, curbuf+done); r = EVP_CIPHER_CTX_ctrl(cl->dec_ctx, EVP_CTRL_GCM_SET_TAG, 16, curbuf+done);
assert(r == 1);
done += 16; done += 16;
} }
assert(r == 1);
int len = 0; int len = 0;
r = EVP_DecryptFinal_ex(cl->dec_ctx, NULL, &len); r = EVP_DecryptFinal_ex(cl->dec_ctx, NULL, &len);
assert(len == 0);
#endif
if (r != 1) if (r != 1)
{ {
fprintf(stderr, "Client %ju AES-GCM decryption failed\n", cl->client_id); fprintf(stderr, "Client %ju AES-GCM decryption failed\n", cl->client_id);
cl->io_error = true; cl->io_error = true;
return false; return false;
} }
if (msgr->decrypt_gcm_pool.size() < msgr->max_cipher_pool_size)
msgr->decrypt_gcm_pool.push_back(cl->dec_ctx);
else
{
#ifdef WITH_ISAL_CRYPTO
free(cl->dec_ctx);
#else
EVP_CIPHER_CTX_free(cl->dec_ctx);
#endif
}
cl->dec_ctx = NULL;
cl->dec_tag_size = 0; cl->dec_tag_size = 0;
assert(len == 0);
cl->dec_batch_size = 0;
cl->dec_batch_size_size = 0;
return true; return true;
} }
@@ -528,7 +486,7 @@ public:
bool read(uint8_t *dst, size_t dst_len, int flags) override bool read(uint8_t *dst, size_t dst_len, int flags) override
{ {
if (cl->gcm_enabled) if (cl->dec_ctx)
return false; // FIXME Only for tests, use copy-only with AES return false; // FIXME Only for tests, use copy-only with AES
if (from >= dst_len) if (from >= dst_len)
{ {
@@ -562,7 +520,7 @@ public:
bool finish() override bool finish() override
{ {
if (cl->gcm_enabled) if (cl->dec_ctx)
return false; return false;
return true; return true;
} }
@@ -718,6 +676,8 @@ out_wakeup:
{ {
goto out_wakeup; goto out_wakeup;
} }
execute_verified_op(cl, cl->read_op);
cl->read_op = NULL;
} }
} }
cl->read_msg.msg_iovlen = 0; cl->read_msg.msg_iovlen = 0;
@@ -758,7 +718,7 @@ void osd_messenger_t::handle_immediate_ops()
bool osd_messenger_t::handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size_t bufsize) bool osd_messenger_t::handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size_t bufsize)
{ {
if (cl->gcm_enabled) if (cl->dec_ctx)
{ {
return handle_buffer_with<gcm_op_reader_t>(cl, curbuf, bufsize); return handle_buffer_with<gcm_op_reader_t>(cl, curbuf, bufsize);
} }
@@ -801,6 +761,28 @@ bool osd_messenger_t::handle_buffer_with(osd_client_t *cl, uint8_t *curbuf, size
} }
break; break;
} }
if constexpr (std::is_same_v<T, gcm_op_reader_t>)
{
if (cl->dec_batch_size_size)
{
// Operation is not verified yet
cl->unverified_ops.push_back(cl->read_op);
}
else
{
for (auto & op: cl->unverified_ops)
{
execute_verified_op(cl, op);
}
cl->unverified_ops.clear();
execute_verified_op(cl, cl->read_op);
}
}
else
{
execute_verified_op(cl, cl->read_op);
}
cl->read_op = NULL;
} }
assert(rdr.get_done() == bufsize); assert(rdr.get_done() == bufsize);
return true; return true;
@@ -1106,12 +1088,7 @@ bool osd_messenger_t::handle_finished_op(osd_client_t *cl)
return false; return false;
} }
} }
if (op->op_type == OSD_OP_IN) if (op->op_type == OSD_OP_OUT)
{
// Operation is ready
cl->received_ops.push_back(op);
}
else
{ {
// Inline decryption // Inline decryption
if (cl->read_op_inline_decrypt_pos != (size_t)-1) if (cl->read_op_inline_decrypt_pos != (size_t)-1)
@@ -1119,6 +1096,20 @@ bool osd_messenger_t::handle_finished_op(osd_client_t *cl)
op_decrypt_inline(cl); op_decrypt_inline(cl);
cl->read_op_inline_decrypt_pos = (size_t)-1; cl->read_op_inline_decrypt_pos = (size_t)-1;
} }
}
op_decrypt_free(cl);
return true;
}
void osd_messenger_t::execute_verified_op(osd_client_t *cl, osd_op_t *op)
{
if (op->op_type == OSD_OP_IN)
{
// Operation is ready
cl->received_ops.push_back(op);
}
else
{
// Measure subop (outbound op) latency // Measure subop (outbound op) latency
timespec tv_end; timespec tv_end;
clock_gettime(CLOCK_REALTIME, &tv_end); clock_gettime(CLOCK_REALTIME, &tv_end);
@@ -1133,8 +1124,5 @@ bool osd_messenger_t::handle_finished_op(osd_client_t *cl)
(tv_end.tv_nsec - op->tv_begin.tv_nsec)/1000 (tv_end.tv_nsec - op->tv_begin.tv_nsec)/1000
); );
} }
op_decrypt_free(cl);
set_immediate_ops.push_back(op); set_immediate_ops.push_back(op);
cl->read_op = NULL;
return true;
} }
+134 -154
View File
@@ -7,10 +7,12 @@
#include "messenger.h" #include "messenger.h"
#ifdef WITH_OPENSSL
#include <openssl/bio.h> #include <openssl/bio.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#endif
#define WR_TLS 1 #define WR_TLS 1
#define WR_XTS 2 #define WR_XTS 2
@@ -234,77 +236,17 @@ class gcm_op_writer_t: public msgr_op_writer_t
uint8_t *curbuf; uint8_t *curbuf;
size_t bufsize; size_t bufsize;
size_t done; size_t done;
uint32_t *batch_size_ptr;
public: public:
gcm_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize): gcm_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t *curbuf, size_t bufsize):
msgr(msgr), cl(cl), from(cl->write_op_pos), curbuf(curbuf), bufsize(bufsize), done(0) msgr(msgr), cl(cl), from(cl->write_op_pos), curbuf(curbuf), bufsize(bufsize), done(0), batch_size_ptr(NULL)
{ {
} }
void reset() void reset()
{ {
from = cl->write_op_pos; from = cl->write_op_pos;
init_ctx(msgr, cl);
}
static void init_ctx(osd_messenger_t* msgr, osd_client_t *cl)
{
if (!cl->enc_ctx)
{
if (msgr->encrypt_gcm_pool.size())
{
cl->enc_ctx = msgr->encrypt_gcm_pool.back();
msgr->encrypt_gcm_pool.pop_back();
}
else
{
#ifdef WITH_ISAL_CRYPTO
cl->enc_ctx = (isal_gcm_context_data*)malloc_or_die(sizeof(isal_gcm_context_data));
#else
cl->enc_ctx = EVP_CIPHER_CTX_new();
assert(cl->enc_ctx);
int r = EVP_EncryptInit_ex(cl->enc_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
if (r != 1)
{
fprintf(stderr, "EncryptInit error: ");
ERR_print_errors_fp(stderr);
abort();
}
#endif
}
}
uint8_t iv[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
#ifdef WITH_ISAL_CRYPTO
int r = isal_aes_gcm_init_256(&msgr->test_osd_aes_key_isal, cl->enc_ctx, iv, NULL, 0);
if (r != 0)
{
fprintf(stderr, "isal_aes_gcm_init_256 error %d\n", r);
abort();
}
#else
int r = EVP_EncryptInit_ex(cl->enc_ctx, NULL, NULL, (uint8_t*)msgr->test_osd_aes_key.data(), iv);
if (r != 1)
{
fprintf(stderr, "EncryptInit error: ");
ERR_print_errors_fp(stderr);
abort();
}
#endif
}
static void free_ctx(osd_messenger_t* msgr, osd_client_t *cl)
{
if (msgr->encrypt_gcm_pool.size() < msgr->max_cipher_pool_size)
msgr->encrypt_gcm_pool.push_back(cl->enc_ctx);
else
{
#ifdef WITH_ISAL_CRYPTO
free(cl->enc_ctx);
#else
EVP_CIPHER_CTX_free(cl->enc_ctx);
#endif
}
cl->enc_ctx = NULL;
} }
bool write(uint8_t *src, size_t src_len, int flags) override bool write(uint8_t *src, size_t src_len, int flags) override
@@ -337,15 +279,37 @@ public:
} }
else else
{ {
if (!cl->write_op_pos)
{
if (batch_size_ptr)
{
if (bufsize-done < 1)
return false;
(*batch_size_ptr)++;
}
else
{
if (bufsize-done < 5)
return false;
batch_size_ptr = (uint32_t*)(curbuf+done);
*batch_size_ptr = 1; // FIXME like header, but now for tests
done += 4;
cl->enc_batch = true;
uint8_t iv[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
int r = EVP_EncryptInit_ex(cl->enc_ctx, NULL, NULL, (uint8_t*)msgr->test_osd_aes_key.data(), iv);
if (r != 1)
{
fprintf(stderr, "EncryptInit error: ");
ERR_print_errors_fp(stderr);
abort();
}
}
}
size_t n = src_len-from; size_t n = src_len-from;
if (n > bufsize-done) if (n > bufsize-done)
n = bufsize-done; n = bufsize-done;
if (!n) if (!n)
return false; return false;
#ifdef WITH_ISAL_CRYPTO
int r = isal_aes_gcm_enc_256_update(&msgr->test_osd_aes_key_isal, cl->enc_ctx, curbuf+done, src+from, n);
assert(!r);
#else
int actual_out; int actual_out;
if (EVP_EncryptUpdate(cl->enc_ctx, curbuf+done, &actual_out, src+from, n) != 1) if (EVP_EncryptUpdate(cl->enc_ctx, curbuf+done, &actual_out, src+from, n) != 1)
{ {
@@ -354,7 +318,6 @@ public:
abort(); abort();
} }
assert(actual_out == n); assert(actual_out == n);
#endif
if (cl->write_csum_state && !(flags & WR_NO_CSUM)) if (cl->write_csum_state && !(flags & WR_NO_CSUM))
XXH3_64bits_update(cl->write_csum_state, src+from, n); XXH3_64bits_update(cl->write_csum_state, src+from, n);
done += n; done += n;
@@ -367,12 +330,8 @@ public:
return true; return true;
} }
static void write_tag_to(osd_messenger_t *msgr, osd_client_t *cl, uint8_t *dst) static void write_tag_to(osd_client_t *cl, uint8_t *dst)
{ {
#ifdef WITH_ISAL_CRYPTO
int r = isal_aes_gcm_enc_256_finalize(&msgr->test_osd_aes_key_isal, cl->enc_ctx, dst, 16);
assert(!r);
#else
int actual_out = 0; int actual_out = 0;
int r = EVP_EncryptFinal_ex(cl->enc_ctx, NULL, &actual_out); int r = EVP_EncryptFinal_ex(cl->enc_ctx, NULL, &actual_out);
if (r != 1) if (r != 1)
@@ -384,38 +343,26 @@ public:
assert(actual_out == 0); assert(actual_out == 0);
r = EVP_CIPHER_CTX_ctrl(cl->enc_ctx, EVP_CTRL_GCM_GET_TAG, 16, dst); r = EVP_CIPHER_CTX_ctrl(cl->enc_ctx, EVP_CTRL_GCM_GET_TAG, 16, dst);
assert(r == 1); assert(r == 1);
#endif
} }
bool finish() override bool finish() override
{ {
if (bufsize-done >= OSD_PACKET_SIZE+16 && batch_size_ptr && cl->write_ops.size())
{
// More operations may fit, so don't finish the batch yet
return true;
}
// Tag is 16 bytes // Tag is 16 bytes
if (done >= bufsize) if (bufsize-done < 16)
{
// No space for the tag
return false; return false;
if (bufsize-done < 16 || cl->enc_tag_size)
{
// No space for the full tag, but msgr_rdma expects us to always fill the whole buffer
if (!cl->enc_tag_size)
{
write_tag_to(msgr, cl, cl->enc_tag);
cl->enc_tag_size = 16;
}
size_t n = bufsize-done;
if (n > cl->enc_tag_size)
n = cl->enc_tag_size;
memcpy(curbuf+done, cl->enc_tag+16-cl->enc_tag_size, n);
done += n;
cl->enc_tag_size -= n;
if (cl->enc_tag_size > 0)
return false;
} }
else write_tag_to(cl, curbuf+done);
{ done += 16;
// The whole tag fits at once // Batch is completed
write_tag_to(msgr, cl, curbuf+done); cl->enc_batch = false;
done += 16; batch_size_ptr = NULL;
}
free_ctx(msgr, cl);
return true; return true;
} }
@@ -434,6 +381,10 @@ class get_op_writer_t: public msgr_op_writer_t
size_t enc_size; size_t enc_size;
size_t done_enc; size_t done_enc;
bool have_batch;
size_t batch_size_offset;
size_t batch_bytes;
void ssl_extend_buf(size_t more = 0) void ssl_extend_buf(size_t more = 0)
{ {
size_t min_cap = cl->ssl_out_buf_size*2; size_t min_cap = cl->ssl_out_buf_size*2;
@@ -443,18 +394,62 @@ class get_op_writer_t: public msgr_op_writer_t
min_cap = 16384; min_cap = 16384;
if (cl->ssl_out_buf_cap < min_cap) if (cl->ssl_out_buf_cap < min_cap)
{ {
uintptr_t old_buf = (uintptr_t)cl->ssl_out_buf; uint8_t *old_buf = cl->ssl_out_buf;
uintptr_t old_end = old_buf + cl->ssl_out_buf_cap; uint8_t *old_end = old_buf + cl->ssl_out_buf_cap;
cl->ssl_out_buf = (uint8_t*)realloc_or_die(cl->ssl_out_buf, min_cap); cl->ssl_out_buf = (uint8_t*)realloc_or_die(cl->ssl_out_buf, min_cap);
cl->ssl_out_buf_cap = min_cap; cl->ssl_out_buf_cap = min_cap;
for (auto & iov: cl->send_list) for (auto & iov: cl->send_list)
{ {
if ((uintptr_t)iov.iov_base >= old_buf && (uintptr_t)iov.iov_base < old_end) if (iov.iov_base >= old_buf && iov.iov_base < old_end)
iov.iov_base = cl->ssl_out_buf + ((uintptr_t)iov.iov_base - old_buf); iov.iov_base = cl->ssl_out_buf + ((uint8_t*)iov.iov_base - old_buf);
} }
} }
} }
void copy_ssl()
{
size_t prev_size = cl->ssl_out_buf_size;
do
{
ssl_extend_buf();
int r = BIO_read(cl->read_from_ssl, cl->ssl_out_buf+cl->ssl_out_buf_size, cl->ssl_out_buf_cap-cl->ssl_out_buf_size);
if (r > 0)
cl->ssl_out_buf_size += r;
} while (cl->ssl_out_buf_size >= cl->ssl_out_buf_cap);
if (cl->ssl_out_buf_size > prev_size)
{
cl->send_list.push_back((iovec){ .iov_base = cl->ssl_out_buf+prev_size, .iov_len = cl->ssl_out_buf_size-prev_size });
}
}
public:
get_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl):
msgr(msgr), cl(cl), from(cl->write_op_pos), enc_size(0), done_enc(0),
have_batch(false), batch_size_offset(0), batch_bytes(0)
{
}
void reset()
{
from = cl->write_op_pos;
enc_size = 0;
done_enc = 0;
}
void flush_ssl()
{
if (!cl->ssl_handshake_done)
{
if (!msgr->ssl_do_handshake(cl))
return;
}
if (cl->send_list.size() >= IOV_MAX)
{
return;
}
copy_ssl();
}
void send_out_buf(size_t n) void send_out_buf(size_t n)
{ {
if (cl->send_list.size() > 0) if (cl->send_list.size() > 0)
@@ -471,51 +466,6 @@ class get_op_writer_t: public msgr_op_writer_t
cl->ssl_out_buf_size += n; cl->ssl_out_buf_size += n;
} }
void copy_ssl()
{
size_t n = 0;
do
{
ssl_extend_buf();
int r = BIO_read(cl->read_from_ssl, cl->ssl_out_buf+cl->ssl_out_buf_size, cl->ssl_out_buf_cap-cl->ssl_out_buf_size);
if (r > 0)
n += r;
} while (cl->ssl_out_buf_size+n >= cl->ssl_out_buf_cap);
if (n > 0)
send_out_buf(n);
}
public:
get_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl):
msgr(msgr), cl(cl), from(cl->write_op_pos), enc_size(0), done_enc(0)
{
}
void reset()
{
from = cl->write_op_pos;
enc_size = 0;
done_enc = 0;
if (cl->gcm_enabled)
{
gcm_op_writer_t::init_ctx(msgr, cl);
}
}
void flush_ssl()
{
if (!cl->ssl_handshake_done)
{
if (!msgr->ssl_do_handshake(cl))
return;
}
if (cl->send_list.size() >= IOV_MAX)
{
return;
}
copy_ssl();
}
bool write(uint8_t *src, size_t src_len, int flags) override bool write(uint8_t *src, size_t src_len, int flags) override
{ {
if (from >= src_len) if (from >= src_len)
@@ -552,12 +502,32 @@ public:
else if (cl->enc_ctx) else if (cl->enc_ctx)
{ {
// Encrypt data to client's temporary output buffer (all at once) // Encrypt data to client's temporary output buffer (all at once)
if (!cl->write_op_pos)
{
if (have_batch)
{
(*(uint32_t*)(cl->ssl_out_buf+batch_size_offset))++;
}
else
{
ssl_extend_buf(4);
have_batch = true;
batch_size_offset = cl->ssl_out_buf_size;
(*(uint32_t*)(cl->ssl_out_buf+batch_size_offset)) = 1;
send_out_buf(4);
cl->enc_batch = true;
uint8_t iv[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
int r = EVP_EncryptInit_ex(cl->enc_ctx, NULL, NULL, (uint8_t*)msgr->test_osd_aes_key.data(), iv);
if (r != 1)
{
fprintf(stderr, "EncryptInit error: ");
ERR_print_errors_fp(stderr);
abort();
}
}
}
size_t n = src_len-from; size_t n = src_len-from;
ssl_extend_buf(n); ssl_extend_buf(n);
#ifdef WITH_ISAL_CRYPTO
int r = isal_aes_gcm_enc_256_update(&msgr->test_osd_aes_key_isal, cl->enc_ctx, cl->ssl_out_buf+cl->ssl_out_buf_size, src+from, n);
assert(!r);
#else
int actual_out; int actual_out;
if (EVP_EncryptUpdate(cl->enc_ctx, cl->ssl_out_buf+cl->ssl_out_buf_size, &actual_out, src+from, n) != 1) if (EVP_EncryptUpdate(cl->enc_ctx, cl->ssl_out_buf+cl->ssl_out_buf_size, &actual_out, src+from, n) != 1)
{ {
@@ -566,10 +536,10 @@ public:
abort(); abort();
} }
assert(actual_out == n); assert(actual_out == n);
#endif
if (cl->write_csum_state && !(flags & WR_NO_CSUM)) if (cl->write_csum_state && !(flags & WR_NO_CSUM))
XXH3_64bits_update(cl->write_csum_state, src+from, n); XXH3_64bits_update(cl->write_csum_state, src+from, n);
send_out_buf(n); send_out_buf(n);
batch_bytes += n;
cl->write_op_pos += n; cl->write_op_pos += n;
from += n; from += n;
if (from < src_len) if (from < src_len)
@@ -595,8 +565,10 @@ public:
cl->send_list.push_back((iovec){ .iov_base = cl->write_op->enc_buf, .iov_len = enc_size }); cl->send_list.push_back((iovec){ .iov_base = cl->write_op->enc_buf, .iov_len = enc_size });
} }
assert(enc_size > 0); assert(enc_size > 0);
size_t old_from = from;
msgr->op_encrypted_copy_buf(cl, cl->write_op->enc_buf, enc_size, src, src_len, from, done_enc); msgr->op_encrypted_copy_buf(cl, cl->write_op->enc_buf, enc_size, src, src_len, from, done_enc);
assert(from == src_len); assert(from == src_len);
batch_bytes += src_len-old_from;
} }
else else
{ {
@@ -604,6 +576,7 @@ public:
XXH3_64bits_update(cl->write_csum_state, src+from, src_len-from); XXH3_64bits_update(cl->write_csum_state, src+from, src_len-from);
cl->send_list.push_back((iovec){ src+from, src_len-from }); cl->send_list.push_back((iovec){ src+from, src_len-from });
cl->write_op_pos += src_len-from; cl->write_op_pos += src_len-from;
batch_bytes += src_len-from;
} }
from = 0; from = 0;
return true; return true;
@@ -621,11 +594,18 @@ public:
{ {
if (cl->send_list.size() >= IOV_MAX) if (cl->send_list.size() >= IOV_MAX)
return false; return false;
if (batch_bytes < 131072 && have_batch && cl->write_ops.size())
{
// More operations may fit, so don't finish the batch yet
return true;
}
// Tag is 16 bytes // Tag is 16 bytes
ssl_extend_buf(16); ssl_extend_buf(16);
gcm_op_writer_t::write_tag_to(msgr, cl, cl->ssl_out_buf+cl->ssl_out_buf_size); gcm_op_writer_t::write_tag_to(cl, cl->ssl_out_buf+cl->ssl_out_buf_size);
send_out_buf(16); send_out_buf(16);
gcm_op_writer_t::free_ctx(msgr, cl); cl->enc_batch = false;
have_batch = false;
batch_bytes = 0;
} }
return true; return true;
} }
@@ -866,7 +846,7 @@ bool osd_messenger_t::try_send(osd_client_t *cl)
size_t osd_messenger_t::copy_ops_to(osd_client_t *cl, uint8_t *dst, size_t dst_len) size_t osd_messenger_t::copy_ops_to(osd_client_t *cl, uint8_t *dst, size_t dst_len)
{ {
if (cl->gcm_enabled) if (cl->enc_ctx)
{ {
return copy_ops_to_with<gcm_op_writer_t>(cl, dst, dst_len); return copy_ops_to_with<gcm_op_writer_t>(cl, dst, dst_len);
} }
+20 -18
View File
@@ -9,10 +9,12 @@
#ifdef WITH_RDMA #ifdef WITH_RDMA
#include "msgr_rdma.h" #include "msgr_rdma.h"
#endif #endif
#ifdef WITH_OPENSSL
#include <openssl/bio.h> #include <openssl/bio.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#endif
void osd_client_t::cancel_ops() void osd_client_t::cancel_ops()
{ {
@@ -84,21 +86,21 @@ void osd_messenger_t::stop_client(uint64_t client_id, bool force_delete)
fprintf(stderr, "[OSD %ju] Stopping client %ju (regular client)\n", osd_num, client_id); fprintf(stderr, "[OSD %ju] Stopping client %ju (regular client)\n", osd_num, client_id);
} }
} }
if (cl->xts_enc_ctx) if (cl->encrypt_ctx)
{ {
if (encrypt_xts_pool.size() > max_cipher_pool_size) if (encrypt_ctx_pool.size() > max_aes_xts_pool_size)
destroy_aes_xts_encrypt(cl->xts_enc_ctx); destroy_aes_xts_encrypt(cl->encrypt_ctx);
else else
encrypt_xts_pool.push_back(cl->xts_enc_ctx); encrypt_ctx_pool.push_back(cl->encrypt_ctx);
cl->xts_enc_ctx = NULL; cl->encrypt_ctx = NULL;
} }
if (cl->xts_dec_ctx) if (cl->decrypt_ctx)
{ {
if (decrypt_xts_pool.size() > max_cipher_pool_size) if (decrypt_ctx_pool.size() > max_aes_xts_pool_size)
destroy_aes_xts_decrypt(cl->xts_dec_ctx); destroy_aes_xts_decrypt(cl->decrypt_ctx);
else else
decrypt_xts_pool.push_back(cl->xts_dec_ctx); decrypt_ctx_pool.push_back(cl->decrypt_ctx);
cl->xts_dec_ctx = NULL; cl->decrypt_ctx = NULL;
} }
// First set state to STOPPED so another stop_client() call doesn't try to free it again // First set state to STOPPED so another stop_client() call doesn't try to free it again
cl->refs++; cl->refs++;
@@ -208,6 +210,12 @@ osd_client_t::~osd_client_t()
read_op->cancel(); read_op->cancel();
read_op = NULL; read_op = NULL;
} }
while (unverified_ops.size())
{
auto op = unverified_ops.back();
unverified_ops.pop_back();
op->cancel();
}
// Cancel outbound ops // Cancel outbound ops
cancel_ops(); cancel_ops();
for (osd_op_t *op: send_free_ops) for (osd_op_t *op: send_free_ops)
@@ -246,22 +254,15 @@ osd_client_t::~osd_client_t()
XXH3_freeState(write_csum_state); XXH3_freeState(write_csum_state);
write_csum_state = NULL; write_csum_state = NULL;
} }
#ifdef WITH_OPENSSL
if (enc_ctx) if (enc_ctx)
{ {
#ifdef WITH_ISAL_CRYPTO
free(enc_ctx);
#else
EVP_CIPHER_CTX_free(enc_ctx); EVP_CIPHER_CTX_free(enc_ctx);
#endif
enc_ctx = NULL; enc_ctx = NULL;
} }
if (dec_ctx) if (dec_ctx)
{ {
#ifdef WITH_ISAL_CRYPTO
free(dec_ctx);
#else
EVP_CIPHER_CTX_free(dec_ctx); EVP_CIPHER_CTX_free(dec_ctx);
#endif
dec_ctx = NULL; dec_ctx = NULL;
} }
if (ssl_cli) if (ssl_cli)
@@ -276,4 +277,5 @@ osd_client_t::~osd_client_t()
free(ssl_out_buf); free(ssl_out_buf);
ssl_out_buf = NULL; ssl_out_buf = NULL;
} }
#endif
} }
+4
View File
@@ -1,7 +1,9 @@
// Copyright (c) Vitaliy Filippov, 2019+ // Copyright (c) Vitaliy Filippov, 2019+
// License: VNPL-1.1 (see README.md for details) // License: VNPL-1.1 (see README.md for details)
#ifdef WITH_OPENSSL
#include <openssl/rand.h> #include <openssl/rand.h>
#endif
#include <ctype.h> #include <ctype.h>
#include "cli.h" #include "cli.h"
@@ -626,12 +628,14 @@ std::function<bool(cli_result_t &)> cli_tool_t::start_create(json11::Json cfg)
if (!cfg["enc_key"].is_null()) if (!cfg["enc_key"].is_null())
{ {
image_creator->set_key = true; image_creator->set_key = true;
#ifdef WITH_OPENSSL
if (image_creator->enc_key == "random") if (image_creator->enc_key == "random")
{ {
uint8_t newkey[64]; uint8_t newkey[64];
RAND_bytes(newkey, 64); RAND_bytes(newkey, 64);
image_creator->enc_key = tohexstr(newkey, 64); image_creator->enc_key = tohexstr(newkey, 64);
} }
#endif
else else
{ {
image_creator->enc_key = cfg["enc_key"].string_value(); image_creator->enc_key = cfg["enc_key"].string_value();
+6
View File
@@ -1,7 +1,9 @@
// Copyright (c) Vitaliy Filippov, 2019+ // Copyright (c) Vitaliy Filippov, 2019+
// License: VNPL-1.1 (see README.md for details) // License: VNPL-1.1 (see README.md for details)
#ifdef WITH_OPENSSL
#include <openssl/rand.h> #include <openssl/rand.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -554,6 +556,7 @@ void test_writeback_merge()
printf("[ok] writeback merge test\n"); printf("[ok] writeback merge test\n");
} }
#ifdef WITH_OPENSSL
void test_msgr_encrypt() void test_msgr_encrypt()
{ {
const size_t sz = 1048576; const size_t sz = 1048576;
@@ -722,6 +725,7 @@ void test_msgr_decrypt_chain()
free(src); free(src);
printf("[ok] msgr aes-xts chained decrypt\n"); printf("[ok] msgr aes-xts chained decrypt\n");
} }
#endif
void test_vault() void test_vault()
{ {
@@ -790,8 +794,10 @@ int main(int narg, char *args[])
test2(); test2();
test_writeback(); test_writeback();
test_writeback_merge(); test_writeback_merge();
#ifdef WITH_OPENSSL
test_msgr_encrypt(); test_msgr_encrypt();
test_msgr_decrypt_chain(); test_msgr_decrypt_chain();
#endif
test_vault(); test_vault();
return 0; return 0;
} }