Add support for full AES-GCM including double encryption of AES-XTS :D
This commit is contained in:
@@ -792,6 +792,24 @@ jobs:
|
|||||||
echo ""
|
echo ""
|
||||||
done
|
done
|
||||||
|
|
||||||
|
test_snapshot_chain_enc_gcm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
|
container: ${{env.TEST_IMAGE}}:${{github.sha}}
|
||||||
|
steps:
|
||||||
|
- name: Run test
|
||||||
|
id: test
|
||||||
|
timeout-minutes: 3
|
||||||
|
run: TEST_NAME=enc_gcm ENCRYPTED=1 VITASTOR_CFG=',"proto_checksums":"gcm"' /root/vitastor/tests/test_snapshot_chain.sh
|
||||||
|
- name: Print logs
|
||||||
|
if: always() && steps.test.outcome == 'failure'
|
||||||
|
run: |
|
||||||
|
for i in /root/vitastor/testdata/*.log /root/vitastor/testdata/*.txt; do
|
||||||
|
echo "-------- $i --------"
|
||||||
|
cat $i
|
||||||
|
echo ""
|
||||||
|
done
|
||||||
|
|
||||||
test_old_snapshot_chain:
|
test_old_snapshot_chain:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: build
|
needs: build
|
||||||
|
|||||||
+40
-16
@@ -197,19 +197,34 @@ osd_messenger_t::~osd_messenger_t()
|
|||||||
destroy_tls();
|
destroy_tls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_proto_checksums(const json11::Json & val, int default_value)
|
||||||
|
{
|
||||||
|
if (val.is_string())
|
||||||
|
{
|
||||||
|
const auto & str = val.string_value();
|
||||||
|
if (str == "full")
|
||||||
|
return MSGR_CSUM_FULL;
|
||||||
|
else if (str == "payload")
|
||||||
|
return MSGR_CSUM_PAYLOAD;
|
||||||
|
else if (str == "gcm")
|
||||||
|
return MSGR_CSUM_GCM;
|
||||||
|
else if (str == "none")
|
||||||
|
return 0;
|
||||||
|
else if (str == "")
|
||||||
|
return default_value;
|
||||||
|
}
|
||||||
|
else if (val.is_null())
|
||||||
|
return default_value;
|
||||||
|
fprintf(stderr, "proto_checksums should be \"full\", \"payload\", \"gcm\", \"none\""
|
||||||
|
", \"\" or null (default), but it is: %s\n", val.dump().c_str());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
void osd_messenger_t::parse_config(const json11::Json & config, bool init)
|
void osd_messenger_t::parse_config(const json11::Json & config, bool init)
|
||||||
{
|
{
|
||||||
this->max_cipher_pool_size = config["max_cipher_pool_size"].uint64_value();
|
this->max_cipher_pool_size = config["max_cipher_pool_size"].uint64_value();
|
||||||
if (!this->max_cipher_pool_size)
|
if (!this->max_cipher_pool_size)
|
||||||
this->max_cipher_pool_size = 256;
|
this->max_cipher_pool_size = 256;
|
||||||
if (config["proto_checksums"].is_null())
|
|
||||||
this->use_proto_checksums = MSGR_CSUM_PAYLOAD;
|
|
||||||
else if (config["proto_checksums"].is_bool())
|
|
||||||
this->use_proto_checksums = config["proto_checksums"].bool_value() ? MSGR_CSUM_FULL : 0;
|
|
||||||
else if (config["proto_checksums"].string_value() != "")
|
|
||||||
this->use_proto_checksums = config["proto_checksums"].string_value() == "full" ? MSGR_CSUM_FULL : MSGR_CSUM_PAYLOAD;
|
|
||||||
else
|
|
||||||
this->use_proto_checksums = 0;
|
|
||||||
this->receive_buffer_size = (uint32_t)config["tcp_header_buffer_size"].uint64_value();
|
this->receive_buffer_size = (uint32_t)config["tcp_header_buffer_size"].uint64_value();
|
||||||
if (!this->receive_buffer_size || this->receive_buffer_size > 1024*1024*1024)
|
if (!this->receive_buffer_size || this->receive_buffer_size > 1024*1024*1024)
|
||||||
this->receive_buffer_size = 65536;
|
this->receive_buffer_size = 65536;
|
||||||
@@ -275,6 +290,8 @@ void osd_messenger_t::parse_config(const json11::Json & config, bool init)
|
|||||||
osd_tls_ca = config["osd_ca"].string_value();
|
osd_tls_ca = config["osd_ca"].string_value();
|
||||||
client_tls_ca = config["client_ca"].string_value();
|
client_tls_ca = config["client_ca"].string_value();
|
||||||
}
|
}
|
||||||
|
this->use_proto_checksums = parse_proto_checksums(config["proto_checksums"], MSGR_CSUM_PAYLOAD);
|
||||||
|
this->force_proto_checksums = parse_proto_checksums(config["force_proto_checksums"], tls_cert != "" ? MSGR_CSUM_PAYLOAD : 0);
|
||||||
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
|
||||||
@@ -653,6 +670,21 @@ void osd_messenger_t::check_peer_config(osd_client_t *cl)
|
|||||||
err = !check_config_hook(cl, config);
|
err = !check_config_hook(cl, config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!err && use_proto_checksums)
|
||||||
|
{
|
||||||
|
auto peer_csums = config["features"]["proto_checksums"].uint64_value();
|
||||||
|
if (peer_csums == MSGR_CSUM_GCM && use_proto_checksums == MSGR_CSUM_GCM && cl->gcm_enabled)
|
||||||
|
cl->proto_csum_status = MSGR_CSUM_GCM;
|
||||||
|
else if (peer_csums == MSGR_CSUM_FULL && use_proto_checksums == MSGR_CSUM_FULL)
|
||||||
|
cl->proto_csum_status = MSGR_CSUM_FULL;
|
||||||
|
else if (peer_csums && use_proto_checksums)
|
||||||
|
cl->proto_csum_status = MSGR_CSUM_PAYLOAD;
|
||||||
|
if (cl->proto_csum_status < force_proto_checksums)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: OSD %ju use_proto_checksums security level is lower than force_proto_checksums\n", cl->osd_num);
|
||||||
|
err = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
osd_num_t peer_osd = cl->osd_num;
|
osd_num_t peer_osd = cl->osd_num;
|
||||||
@@ -661,14 +693,6 @@ void osd_messenger_t::check_peer_config(osd_client_t *cl)
|
|||||||
delete op;
|
delete op;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (use_proto_checksums)
|
|
||||||
{
|
|
||||||
auto peer_csums = config["features"]["proto_checksums"].uint64_value();
|
|
||||||
if (peer_csums == MSGR_CSUM_FULL && use_proto_checksums == MSGR_CSUM_FULL)
|
|
||||||
cl->proto_csum_status = MSGR_CSUM_FULL;
|
|
||||||
else if (peer_csums && use_proto_checksums)
|
|
||||||
cl->proto_csum_status = MSGR_CSUM_PAYLOAD;
|
|
||||||
}
|
|
||||||
#ifdef WITH_RDMA
|
#ifdef WITH_RDMA
|
||||||
if (!use_rdmacm && cl->rdma_conn && config["rdma_address"].is_string())
|
if (!use_rdmacm && cl->rdma_conn && config["rdma_address"].is_string())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -41,7 +41,8 @@
|
|||||||
|
|
||||||
#define MSGR_CSUM_PAYLOAD 1
|
#define MSGR_CSUM_PAYLOAD 1
|
||||||
#define MSGR_CSUM_FULL 2
|
#define MSGR_CSUM_FULL 2
|
||||||
#define MSGR_CSUM_NEG 4
|
#define MSGR_CSUM_GCM 4
|
||||||
|
#define MSGR_CSUM_NEG 8
|
||||||
|
|
||||||
#define VITASTOR_CONFIG_PATH "/etc/vitastor/vitastor.conf"
|
#define VITASTOR_CONFIG_PATH "/etc/vitastor/vitastor.conf"
|
||||||
|
|
||||||
@@ -92,9 +93,6 @@ struct osd_client_t
|
|||||||
msgr_rdma_connection_t *rdma_conn = NULL;
|
msgr_rdma_connection_t *rdma_conn = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t *ssl_out_buf = NULL;
|
|
||||||
size_t ssl_out_buf_size = 0, ssl_out_buf_cap = 0;
|
|
||||||
|
|
||||||
bool gcm_enabled = false;
|
bool gcm_enabled = false;
|
||||||
msgr_handshake_i *hs = NULL;
|
msgr_handshake_i *hs = NULL;
|
||||||
msgr_handshake_result_t hs_result;
|
msgr_handshake_result_t hs_result;
|
||||||
@@ -290,6 +288,7 @@ public:
|
|||||||
std::vector<std::string> all_osd_networks;
|
std::vector<std::string> all_osd_networks;
|
||||||
std::vector<addr_mask_t> all_osd_network_masks;
|
std::vector<addr_mask_t> all_osd_network_masks;
|
||||||
int use_proto_checksums = 0;
|
int use_proto_checksums = 0;
|
||||||
|
int force_proto_checksums = 0;
|
||||||
// op statistics
|
// op statistics
|
||||||
osd_op_stats_t stats, recovery_stats;
|
osd_op_stats_t stats, recovery_stats;
|
||||||
|
|
||||||
|
|||||||
@@ -44,9 +44,10 @@ op_aes_xts_encrypt_t::~op_aes_xts_encrypt_t()
|
|||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_aes_xts_encrypt_t::start(uint8_t *key, uint64_t start_offset, size_t block_size)
|
void op_aes_xts_encrypt_t::start(osd_client_t *cl, uint8_t *key, uint64_t start_offset, size_t block_size)
|
||||||
{
|
{
|
||||||
assert(!encrypted);
|
assert(!encrypted);
|
||||||
|
this->cl = cl;
|
||||||
this->start_offset = start_offset;
|
this->start_offset = start_offset;
|
||||||
this->key = key;
|
this->key = key;
|
||||||
this->block_size = block_size;
|
this->block_size = block_size;
|
||||||
@@ -91,6 +92,28 @@ void op_aes_xts_encrypt_t::encrypt_block(uint8_t *in, uint8_t *out)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void copy_or_gcm(osd_client_t *cl, uint8_t *out, uint8_t *in, size_t n)
|
||||||
|
{
|
||||||
|
if (cl->proto_csum_status != MSGR_CSUM_GCM)
|
||||||
|
memcpy(out, in, n);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
|
int r = isal_aes_gcm_enc_256_update(&cl->my_key_isal, cl->enc_ctx, out, in, n);
|
||||||
|
assert(!r);
|
||||||
|
#else
|
||||||
|
int actual_out;
|
||||||
|
if (EVP_EncryptUpdate(cl->enc_ctx, out, &actual_out, in, n) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "EncryptUpdate error: ");
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
assert(actual_out == n);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void op_aes_xts_encrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size_t max_out, size_t & done_in, size_t & done_out)
|
void op_aes_xts_encrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size_t max_out, size_t & done_in, size_t & done_out)
|
||||||
{
|
{
|
||||||
// Fucking AES-XTS implementations (all of them) don't have streaming support,
|
// Fucking AES-XTS implementations (all of them) don't have streaming support,
|
||||||
@@ -104,7 +127,7 @@ void op_aes_xts_encrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size
|
|||||||
assert(tmp);
|
assert(tmp);
|
||||||
if (max_out > block_size - tmp_pos)
|
if (max_out > block_size - tmp_pos)
|
||||||
max_out = block_size - tmp_pos;
|
max_out = block_size - tmp_pos;
|
||||||
memcpy(out, tmp + tmp_pos, max_out);
|
copy_or_gcm(cl, out, tmp + tmp_pos, max_out);
|
||||||
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)
|
||||||
@@ -137,7 +160,7 @@ void op_aes_xts_encrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size
|
|||||||
memcpy(tmp + offset%block_size, in, max_in);
|
memcpy(tmp + offset%block_size, in, max_in);
|
||||||
encrypt_block(tmp, tmp);
|
encrypt_block(tmp, tmp);
|
||||||
encrypted = true;
|
encrypted = true;
|
||||||
memcpy(out, tmp, max_out);
|
copy_or_gcm(cl, out, tmp, max_out);
|
||||||
tmp_pos = max_out;
|
tmp_pos = max_out;
|
||||||
done_in += max_in-1;
|
done_in += max_in-1;
|
||||||
offset += max_in;
|
offset += max_in;
|
||||||
@@ -147,6 +170,8 @@ void op_aes_xts_encrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size
|
|||||||
{
|
{
|
||||||
// Full block - simplest case
|
// Full block - simplest case
|
||||||
encrypt_block(in, out);
|
encrypt_block(in, out);
|
||||||
|
if (cl->proto_csum_status == MSGR_CSUM_GCM)
|
||||||
|
copy_or_gcm(cl, out, out, block_size);
|
||||||
done_in += block_size;
|
done_in += block_size;
|
||||||
offset += block_size;
|
offset += block_size;
|
||||||
done_out += block_size;
|
done_out += block_size;
|
||||||
@@ -158,6 +183,8 @@ void op_aes_xts_encrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size
|
|||||||
max_in = block_size - offset%block_size;
|
max_in = block_size - offset%block_size;
|
||||||
memcpy(tmp + offset%block_size, in, max_in);
|
memcpy(tmp + offset%block_size, in, max_in);
|
||||||
encrypt_block(tmp, out);
|
encrypt_block(tmp, out);
|
||||||
|
if (cl->proto_csum_status == MSGR_CSUM_GCM)
|
||||||
|
copy_or_gcm(cl, out, out, block_size);
|
||||||
done_in += max_in;
|
done_in += max_in;
|
||||||
offset += max_in;
|
offset += max_in;
|
||||||
done_out += block_size;
|
done_out += block_size;
|
||||||
@@ -196,9 +223,10 @@ op_aes_xts_decrypt_t::~op_aes_xts_decrypt_t()
|
|||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_aes_xts_decrypt_t::start(uint8_t **key_chain, size_t chain_size, void *key_indexes, uint64_t start_offset, size_t block_size)
|
void op_aes_xts_decrypt_t::start(osd_client_t *cl, uint8_t **key_chain, size_t chain_size, void *key_indexes, uint64_t start_offset, size_t block_size)
|
||||||
{
|
{
|
||||||
assert(!decrypted);
|
assert(!decrypted);
|
||||||
|
this->cl = cl;
|
||||||
this->start_offset = start_offset;
|
this->start_offset = start_offset;
|
||||||
this->key_chain = key_chain;
|
this->key_chain = key_chain;
|
||||||
this->chain_size = chain_size;
|
this->chain_size = chain_size;
|
||||||
@@ -269,6 +297,23 @@ void op_aes_xts_decrypt_t::decrypt_block(uint8_t *in, uint8_t *out)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void gcm_dec(osd_client_t *cl, uint8_t *out, uint8_t *in, size_t n)
|
||||||
|
{
|
||||||
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
|
int r = isal_aes_gcm_dec_256_update(&cl->peer_key_isal, cl->dec_ctx, out, in, n);
|
||||||
|
assert(!r);
|
||||||
|
#else
|
||||||
|
int actual_out;
|
||||||
|
if (EVP_DecryptUpdate(cl->dec_ctx, out, &actual_out, in, n) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "DecryptUpdate error: ");
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
assert(actual_out == n);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// out may be NULL, in this case all input is still decrypted to calculate checksums,
|
// out may be NULL, in this case all input is still decrypted to calculate checksums,
|
||||||
// but part of it is skipped and not copied to out
|
// but part of it is skipped and not copied to out
|
||||||
void op_aes_xts_decrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size_t max_out, size_t & done_in, size_t & done_out)
|
void op_aes_xts_decrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size_t max_out, size_t & done_in, size_t & done_out)
|
||||||
@@ -316,6 +361,8 @@ void op_aes_xts_decrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size
|
|||||||
}
|
}
|
||||||
max_in = block_size - offset%block_size;
|
max_in = block_size - offset%block_size;
|
||||||
memcpy(tmp + offset%block_size, in, max_in);
|
memcpy(tmp + offset%block_size, in, max_in);
|
||||||
|
if (cl->proto_csum_status == MSGR_CSUM_GCM)
|
||||||
|
gcm_dec(cl, tmp, tmp, block_size);
|
||||||
decrypt_block(tmp, tmp);
|
decrypt_block(tmp, tmp);
|
||||||
decrypted = true;
|
decrypted = true;
|
||||||
if (out)
|
if (out)
|
||||||
@@ -328,7 +375,18 @@ void op_aes_xts_decrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size
|
|||||||
else if (!(offset%block_size))
|
else if (!(offset%block_size))
|
||||||
{
|
{
|
||||||
// Full block - simplest case
|
// Full block - simplest case
|
||||||
if (out)
|
if (cl->proto_csum_status == MSGR_CSUM_GCM)
|
||||||
|
{
|
||||||
|
if (!tmp)
|
||||||
|
{
|
||||||
|
tmp = (uint8_t*)malloc_or_die(block_size);
|
||||||
|
tmp_size = block_size;
|
||||||
|
}
|
||||||
|
gcm_dec(cl, tmp, in, block_size);
|
||||||
|
if (out)
|
||||||
|
decrypt_block(tmp, out);
|
||||||
|
}
|
||||||
|
else
|
||||||
decrypt_block(in, out);
|
decrypt_block(in, out);
|
||||||
done_in += block_size;
|
done_in += block_size;
|
||||||
offset += block_size;
|
offset += block_size;
|
||||||
@@ -341,6 +399,8 @@ void op_aes_xts_decrypt_t::update(uint8_t *in, size_t max_in, uint8_t *out, size
|
|||||||
max_in = block_size - offset%block_size;
|
max_in = block_size - offset%block_size;
|
||||||
memcpy(tmp + offset%block_size, in, max_in);
|
memcpy(tmp + offset%block_size, in, max_in);
|
||||||
assert(out);
|
assert(out);
|
||||||
|
if (cl->proto_csum_status == MSGR_CSUM_GCM)
|
||||||
|
gcm_dec(cl, tmp, tmp, block_size);
|
||||||
decrypt_block(tmp, out);
|
decrypt_block(tmp, out);
|
||||||
done_in += max_in;
|
done_in += max_in;
|
||||||
offset += max_in;
|
offset += max_in;
|
||||||
@@ -365,7 +425,7 @@ void osd_messenger_t::op_encrypted_copy_buf(osd_client_t *cl, uint8_t *enc_buf,
|
|||||||
else
|
else
|
||||||
cl->xts_enc_ctx = new op_aes_xts_encrypt_t();
|
cl->xts_enc_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->xts_enc_ctx->start(cl, 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_plain < plain_len && done_enc < enc_len)
|
||||||
{
|
{
|
||||||
@@ -411,7 +471,7 @@ void osd_messenger_t::op_decrypt_start(osd_client_t* cl)
|
|||||||
cl->xts_dec_ctx = new op_aes_xts_decrypt_t();
|
cl->xts_dec_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->xts_dec_ctx->start(cl, 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);
|
||||||
}
|
}
|
||||||
@@ -561,7 +621,7 @@ void osd_messenger_t::init_tls_client(osd_client_t *cl)
|
|||||||
cl->gcm_enabled = true;
|
cl->gcm_enabled = true;
|
||||||
cl->hs = hs_ctx->create();
|
cl->hs = hs_ctx->create();
|
||||||
cl->hs->init(cl->is_incoming);
|
cl->hs->init(cl->is_incoming);
|
||||||
if (cl->hs->get_out().size())
|
if (cl->hs->out_size())
|
||||||
{
|
{
|
||||||
if (cl->write_state == 0)
|
if (cl->write_state == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,11 +12,14 @@
|
|||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
struct osd_client_t;
|
||||||
|
|
||||||
class op_aes_xts_encrypt_t
|
class op_aes_xts_encrypt_t
|
||||||
{
|
{
|
||||||
#ifndef WITH_ISAL_CRYPTO
|
#ifndef WITH_ISAL_CRYPTO
|
||||||
EVP_CIPHER_CTX *ctx = NULL;
|
EVP_CIPHER_CTX *ctx = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
osd_client_t *cl = NULL;
|
||||||
uint64_t start_offset = 0;
|
uint64_t start_offset = 0;
|
||||||
uint8_t *key = NULL;
|
uint8_t *key = NULL;
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
@@ -32,7 +35,7 @@ public:
|
|||||||
op_aes_xts_encrypt_t();
|
op_aes_xts_encrypt_t();
|
||||||
~op_aes_xts_encrypt_t();
|
~op_aes_xts_encrypt_t();
|
||||||
|
|
||||||
void start(uint8_t *key, uint64_t start_offset, size_t block_size);
|
void start(osd_client_t *cl, 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);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -43,6 +46,7 @@ class op_aes_xts_decrypt_t
|
|||||||
#ifndef WITH_ISAL_CRYPTO
|
#ifndef WITH_ISAL_CRYPTO
|
||||||
EVP_CIPHER_CTX *ctx = NULL;
|
EVP_CIPHER_CTX *ctx = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
osd_client_t *cl = NULL;
|
||||||
uint64_t start_offset = 0;
|
uint64_t start_offset = 0;
|
||||||
uint8_t **key_chain = NULL;
|
uint8_t **key_chain = NULL;
|
||||||
size_t chain_size = 0;
|
size_t chain_size = 0;
|
||||||
@@ -61,7 +65,7 @@ public:
|
|||||||
op_aes_xts_decrypt_t();
|
op_aes_xts_decrypt_t();
|
||||||
~op_aes_xts_decrypt_t();
|
~op_aes_xts_decrypt_t();
|
||||||
|
|
||||||
void start(uint8_t **key_chain, size_t chain_size, void *key_indexes, uint64_t start_offset, size_t block_size);
|
void start(osd_client_t *cl, 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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
|
||||||
#include "msgr_handshake.h"
|
#include "msgr_handshake.h"
|
||||||
|
#include "malloc_or_die.h"
|
||||||
#include "openssl_util.h"
|
#include "openssl_util.h"
|
||||||
#include "str_util.h"
|
#include "str_util.h"
|
||||||
|
|
||||||
@@ -84,7 +85,8 @@ class msgr_handshake_t: public msgr_handshake_i
|
|||||||
|
|
||||||
std::vector<uint8_t> full_handshake;
|
std::vector<uint8_t> full_handshake;
|
||||||
std::vector<uint8_t> in_buf;
|
std::vector<uint8_t> in_buf;
|
||||||
std::vector<uint8_t> out_buf;
|
uint8_t *out_buf = NULL;
|
||||||
|
size_t out_buf_size = 0;
|
||||||
std::string error;
|
std::string error;
|
||||||
|
|
||||||
int state = 0;
|
int state = 0;
|
||||||
@@ -125,7 +127,10 @@ public:
|
|||||||
bool init(bool server_mode) override;
|
bool init(bool server_mode) override;
|
||||||
ssize_t handle(uint8_t* in_buf, size_t in_size) override;
|
ssize_t handle(uint8_t* in_buf, size_t in_size) override;
|
||||||
bool done() override;
|
bool done() override;
|
||||||
std::vector<uint8_t>& get_out() override;
|
uint8_t *get_out() override;
|
||||||
|
size_t out_size() override;
|
||||||
|
void eat_out(size_t n) override;
|
||||||
|
void reset_out() override;
|
||||||
msgr_handshake_result_t get_result() override;
|
msgr_handshake_result_t get_result() override;
|
||||||
std::string get_error() override;
|
std::string get_error() override;
|
||||||
};
|
};
|
||||||
@@ -247,6 +252,8 @@ bool msgr_handshake_ctx_t::derive_kdf(const uint8_t* insecret, size_t insecret_l
|
|||||||
|
|
||||||
msgr_handshake_t::~msgr_handshake_t()
|
msgr_handshake_t::~msgr_handshake_t()
|
||||||
{
|
{
|
||||||
|
if (out_buf)
|
||||||
|
free(out_buf);
|
||||||
if (peer_cert)
|
if (peer_cert)
|
||||||
X509_free(peer_cert);
|
X509_free(peer_cert);
|
||||||
if (ec_key)
|
if (ec_key)
|
||||||
@@ -288,6 +295,12 @@ static void copy_to(std::vector<uint8_t> & buf, const void* src, uint32_t len)
|
|||||||
memcpy(buf.data() + old_size, src, len);
|
memcpy(buf.data() + old_size, src, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void copy_to_raw(uint8_t* & buf, const void* src, size_t len)
|
||||||
|
{
|
||||||
|
memcpy(buf, src, len);
|
||||||
|
buf += len;
|
||||||
|
}
|
||||||
|
|
||||||
static void copy_to_with_len(std::vector<uint8_t> & buf, const void* src, uint32_t len)
|
static void copy_to_with_len(std::vector<uint8_t> & buf, const void* src, uint32_t len)
|
||||||
{
|
{
|
||||||
copy_to(buf, &len, sizeof(len));
|
copy_to(buf, &len, sizeof(len));
|
||||||
@@ -442,9 +455,10 @@ bool msgr_handshake_t::make_client_init()
|
|||||||
size_t key_len = EVP_PKEY_get1_encoded_public_key(ec_key, &key);
|
size_t key_len = EVP_PKEY_get1_encoded_public_key(ec_key, &key);
|
||||||
if (!key_len)
|
if (!key_len)
|
||||||
return on_error("EVP_PKEY_get1_encoded_public_key: ");
|
return on_error("EVP_PKEY_get1_encoded_public_key: ");
|
||||||
const size_t old_len = out_buf.size();
|
const size_t old_out_size = out_buf_size;
|
||||||
out_buf.resize(out_buf.size() + key_len + sizeof(msgr_handshake_hdr_t));
|
out_buf_size += key_len + sizeof(msgr_handshake_hdr_t);
|
||||||
uint8_t *buf = out_buf.data() + old_len;
|
out_buf = (uint8_t*)realloc_or_die(out_buf, out_buf_size);
|
||||||
|
uint8_t *buf = out_buf + old_out_size;
|
||||||
msgr_handshake_hdr_t *hdr = (msgr_handshake_hdr_t *)buf;
|
msgr_handshake_hdr_t *hdr = (msgr_handshake_hdr_t *)buf;
|
||||||
hdr->msg_len = key_len + sizeof(msgr_handshake_hdr_t);
|
hdr->msg_len = key_len + sizeof(msgr_handshake_hdr_t);
|
||||||
hdr->magic = MSGR_HS_MAGIC;
|
hdr->magic = MSGR_HS_MAGIC;
|
||||||
@@ -485,9 +499,12 @@ bool msgr_handshake_t::make_server_reply()
|
|||||||
}
|
}
|
||||||
// Construct message
|
// Construct message
|
||||||
hdr.msg_len = sizeof(msgr_handshake_hdr_t) + 4 + key_len + encrypt_data.size();
|
hdr.msg_len = sizeof(msgr_handshake_hdr_t) + 4 + key_len + encrypt_data.size();
|
||||||
copy_to(out_buf, &hdr, sizeof(hdr));
|
out_buf = (uint8_t*)realloc_or_die(out_buf, (out_buf_size += hdr.msg_len));
|
||||||
copy_to_with_len(out_buf, key, key_len);
|
uint8_t *cur = out_buf + out_buf_size - hdr.msg_len;
|
||||||
copy_to(out_buf, encrypt_data.data(), encrypt_data.size());
|
copy_to_raw(cur, &hdr, sizeof(hdr));
|
||||||
|
copy_to_raw(cur, &key_len, 4);
|
||||||
|
copy_to_raw(cur, key, key_len);
|
||||||
|
copy_to_raw(cur, encrypt_data.data(), encrypt_data.size());
|
||||||
OPENSSL_free(key);
|
OPENSSL_free(key);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -510,8 +527,10 @@ bool msgr_handshake_t::make_client_reply()
|
|||||||
return false;
|
return false;
|
||||||
// Construct message
|
// Construct message
|
||||||
hdr.msg_len = sizeof(msgr_handshake_hdr_t) + encrypt_data.size();
|
hdr.msg_len = sizeof(msgr_handshake_hdr_t) + encrypt_data.size();
|
||||||
copy_to(out_buf, &hdr, sizeof(hdr));
|
out_buf = (uint8_t*)realloc_or_die(out_buf, (out_buf_size += hdr.msg_len));
|
||||||
copy_to(out_buf, encrypt_data.data(), encrypt_data.size());
|
uint8_t *cur = out_buf + out_buf_size - hdr.msg_len;
|
||||||
|
copy_to_raw(cur, &hdr, sizeof(hdr));
|
||||||
|
copy_to_raw(cur, encrypt_data.data(), encrypt_data.size());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -742,11 +761,37 @@ bool msgr_handshake_t::done()
|
|||||||
return (state == MSGR_HS_DONE);
|
return (state == MSGR_HS_DONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t>& msgr_handshake_t::get_out()
|
uint8_t *msgr_handshake_t::get_out()
|
||||||
{
|
{
|
||||||
return out_buf;
|
return out_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t msgr_handshake_t::out_size()
|
||||||
|
{
|
||||||
|
return out_buf_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void msgr_handshake_t::eat_out(size_t n)
|
||||||
|
{
|
||||||
|
if (n >= out_buf_size)
|
||||||
|
{
|
||||||
|
free(out_buf);
|
||||||
|
out_buf = NULL;
|
||||||
|
out_buf_size = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memmove(out_buf, out_buf + n, out_buf_size - n);
|
||||||
|
out_buf_size -= n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void msgr_handshake_t::reset_out()
|
||||||
|
{
|
||||||
|
out_buf = NULL;
|
||||||
|
out_buf_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
msgr_handshake_result_t msgr_handshake_t::get_result()
|
msgr_handshake_result_t msgr_handshake_t::get_result()
|
||||||
{
|
{
|
||||||
if (state != MSGR_HS_DONE)
|
if (state != MSGR_HS_DONE)
|
||||||
|
|||||||
@@ -35,7 +35,10 @@ public:
|
|||||||
virtual bool init(bool server_mode) = 0;
|
virtual bool init(bool server_mode) = 0;
|
||||||
virtual ssize_t handle(uint8_t* in_buf, size_t in_size) = 0;
|
virtual ssize_t handle(uint8_t* in_buf, size_t in_size) = 0;
|
||||||
virtual bool done() = 0;
|
virtual bool done() = 0;
|
||||||
virtual std::vector<uint8_t> & get_out() = 0;
|
virtual uint8_t *get_out() = 0;
|
||||||
|
virtual size_t out_size() = 0;
|
||||||
|
virtual void eat_out(size_t n) = 0;
|
||||||
|
virtual void reset_out() = 0;
|
||||||
virtual msgr_handshake_result_t get_result() = 0;
|
virtual msgr_handshake_result_t get_result() = 0;
|
||||||
virtual std::string get_error() = 0;
|
virtual std::string get_error() = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,10 +24,6 @@ osd_op_t::~osd_op_t()
|
|||||||
// So we don't reuse it, but free it every time
|
// So we don't reuse it, but free it every time
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
if (enc_buf)
|
|
||||||
{
|
|
||||||
free(enc_buf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool osd_op_t::is_recovery_related()
|
bool osd_op_t::is_recovery_related()
|
||||||
|
|||||||
@@ -186,7 +186,6 @@ struct __attribute__((visibility("default"))) osd_op_t
|
|||||||
uint8_t *bitmap_buf = NULL;
|
uint8_t *bitmap_buf = NULL;
|
||||||
void *rmw_buf = NULL;
|
void *rmw_buf = NULL;
|
||||||
std::shared_ptr<osd_op_enc_t> enc;
|
std::shared_ptr<osd_op_enc_t> enc;
|
||||||
uint8_t *enc_buf = NULL;
|
|
||||||
uint64_t csum = 0; // network layer checksum
|
uint64_t csum = 0; // network layer checksum
|
||||||
osd_primary_op_data_t* op_data = NULL;
|
osd_primary_op_data_t* op_data = NULL;
|
||||||
std::function<void(osd_op_t*)> callback;
|
std::function<void(osd_op_t*)> callback;
|
||||||
|
|||||||
@@ -735,9 +735,12 @@ void osd_messenger_t::handle_rdma_events(msgr_rdma_context_t *rdma_context)
|
|||||||
if (rc->send_done_pos == rc->send_out_size)
|
if (rc->send_done_pos == rc->send_out_size)
|
||||||
rc->send_done_pos = 0;
|
rc->send_done_pos = 0;
|
||||||
assert(rc->send_done_pos < rc->send_out_size);
|
assert(rc->send_done_pos < rc->send_out_size);
|
||||||
while (cl->send_free_ops.front())
|
while (osd_op_t *op = cl->send_free_ops.front())
|
||||||
{
|
{
|
||||||
delete cl->send_free_ops.front();
|
if (!((size_t)op & 7))
|
||||||
|
delete op;
|
||||||
|
else
|
||||||
|
free((void*)((size_t)op & ~(size_t)7));
|
||||||
cl->send_free_ops.pop_front();
|
cl->send_free_ops.pop_front();
|
||||||
}
|
}
|
||||||
cl->send_free_ops.pop_front();
|
cl->send_free_ops.pop_front();
|
||||||
|
|||||||
+28
-40
@@ -170,41 +170,17 @@ public:
|
|||||||
if (done >= bufsize)
|
if (done >= bufsize)
|
||||||
return false;
|
return false;
|
||||||
size_t n = dst_len-from;
|
size_t n = dst_len-from;
|
||||||
if (!(flags & RDR_GCM))
|
if (n > bufsize-done)
|
||||||
|
n = bufsize-done;
|
||||||
|
if (flags & RDR_XTS)
|
||||||
{
|
{
|
||||||
if (n > bufsize-done)
|
msgr->op_decrypted_copy_buf(cl, curbuf, bufsize, dst, dst_len, from, done);
|
||||||
n = bufsize-done;
|
n = 0;
|
||||||
if (flags & RDR_XTS)
|
|
||||||
{
|
|
||||||
msgr->op_decrypted_copy_buf(cl, curbuf, bufsize, dst, dst_len, from, done);
|
|
||||||
n = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (cl->read_csum_state && !(flags & RDR_NO_CSUM))
|
|
||||||
{
|
|
||||||
// data may be skipped if dst == NULL but checksum is still calculated
|
|
||||||
XXH3_64bits_update(cl->read_csum_state, curbuf+done, n);
|
|
||||||
}
|
|
||||||
// Here, dst == NULL is allowed
|
|
||||||
if (dst != NULL)
|
|
||||||
memcpy(dst+from, curbuf+done, n);
|
|
||||||
done += n;
|
|
||||||
}
|
|
||||||
cl->read_op_pos += n;
|
|
||||||
from += n;
|
|
||||||
if (from < dst_len)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else if (flags & RDR_GCM)
|
||||||
{
|
{
|
||||||
// Here, dst == NULL is not allowed
|
// Here, dst == NULL is not allowed
|
||||||
assert(dst != NULL);
|
assert(dst != NULL);
|
||||||
size_t n = dst_len-from;
|
|
||||||
if (n > bufsize-done)
|
|
||||||
n = bufsize-done;
|
|
||||||
#ifdef WITH_ISAL_CRYPTO
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
int r = isal_aes_gcm_dec_256_update(&cl->peer_key_isal, cl->dec_ctx, dst+from, curbuf+done, n);
|
int r = isal_aes_gcm_dec_256_update(&cl->peer_key_isal, cl->dec_ctx, dst+from, curbuf+done, n);
|
||||||
assert(!r);
|
assert(!r);
|
||||||
@@ -223,12 +199,24 @@ public:
|
|||||||
XXH3_64bits_update(cl->read_csum_state, dst+from, n);
|
XXH3_64bits_update(cl->read_csum_state, dst+from, n);
|
||||||
}
|
}
|
||||||
done += n;
|
done += n;
|
||||||
from += n;
|
}
|
||||||
cl->read_op_pos += n;
|
else
|
||||||
if (from < dst_len)
|
{
|
||||||
|
if (cl->read_csum_state && !(flags & RDR_NO_CSUM))
|
||||||
{
|
{
|
||||||
return false;
|
// data may be skipped if dst == NULL but checksum is still calculated
|
||||||
|
XXH3_64bits_update(cl->read_csum_state, curbuf+done, n);
|
||||||
}
|
}
|
||||||
|
// Here, dst == NULL is allowed
|
||||||
|
if (dst != NULL)
|
||||||
|
memcpy(dst+from, curbuf+done, n);
|
||||||
|
done += n;
|
||||||
|
}
|
||||||
|
cl->read_op_pos += n;
|
||||||
|
from += n;
|
||||||
|
if (from < dst_len)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
from = 0;
|
from = 0;
|
||||||
return true;
|
return true;
|
||||||
@@ -605,7 +593,7 @@ bool osd_messenger_t::handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size
|
|||||||
}
|
}
|
||||||
curbuf += done;
|
curbuf += done;
|
||||||
bufsize -= done;
|
bufsize -= done;
|
||||||
if (cl->hs->get_out().size())
|
if (cl->hs->out_size())
|
||||||
{
|
{
|
||||||
if (cl->write_state == 0)
|
if (cl->write_state == 0)
|
||||||
{
|
{
|
||||||
@@ -613,7 +601,7 @@ bool osd_messenger_t::handle_read_buffer(osd_client_t *cl, uint8_t *curbuf, size
|
|||||||
write_ready_clients.push_back(cl->client_id);
|
write_ready_clients.push_back(cl->client_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cl->hs->done() && !cl->hs->get_out().size())
|
if (cl->hs->done() && !cl->hs->out_size())
|
||||||
{
|
{
|
||||||
// Delete hs when done and nothing to send
|
// Delete hs when done and nothing to send
|
||||||
delete cl->hs;
|
delete cl->hs;
|
||||||
@@ -933,7 +921,7 @@ bool osd_messenger_t::op_read_from(osd_client_t *cl, msgr_op_reader_t & rdr)
|
|||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->bitmap, op->req.sec_rw.attr_len, RDR_GCM))
|
if (!rdr.read((uint8_t*)op->bitmap, op->req.sec_rw.attr_len, RDR_GCM))
|
||||||
return false;
|
return false;
|
||||||
if (!rdr.read((uint8_t*)op->buf, op->req.sec_rw.len, 0))
|
if (!rdr.read((uint8_t*)op->buf, op->req.sec_rw.len, cl->proto_csum_status == MSGR_CSUM_GCM ? RDR_GCM : 0))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_SEC_STABILIZE ||
|
else if (op->req.hdr.opcode == OSD_OP_SEC_STABILIZE ||
|
||||||
@@ -949,7 +937,7 @@ bool osd_messenger_t::op_read_from(osd_client_t *cl, msgr_op_reader_t & rdr)
|
|||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_WRITE)
|
else if (op->req.hdr.opcode == OSD_OP_WRITE)
|
||||||
{
|
{
|
||||||
if (!rdr.read((uint8_t*)op->buf, op->req.rw.len, 0))
|
if (!rdr.read((uint8_t*)op->buf, op->req.rw.len, cl->proto_csum_status == MSGR_CSUM_GCM ? RDR_GCM : 0))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (op->req.hdr.opcode == OSD_OP_SHOW_CONFIG)
|
else if (op->req.hdr.opcode == OSD_OP_SHOW_CONFIG)
|
||||||
@@ -973,7 +961,7 @@ switched_type:
|
|||||||
if (op->reply.hdr.retval > 0)
|
if (op->reply.hdr.retval > 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < op->iov.count; i++)
|
for (int i = 0; i < op->iov.count; i++)
|
||||||
if (!rdr.read((uint8_t*)op->iov.buf[i].iov_base, op->iov.buf[i].iov_len, 0))
|
if (!rdr.read((uint8_t*)op->iov.buf[i].iov_base, op->iov.buf[i].iov_len, (cl->proto_csum_status == MSGR_CSUM_GCM ? RDR_GCM : 0)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -987,7 +975,7 @@ switched_type:
|
|||||||
if (op->reply.hdr.retval > 0)
|
if (op->reply.hdr.retval > 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < op->iov.count; i++)
|
for (int i = 0; i < op->iov.count; i++)
|
||||||
if (!rdr.read((uint8_t*)op->iov.buf[i].iov_base, op->iov.buf[i].iov_len, (op->enc ? RDR_XTS : 0)))
|
if (!rdr.read((uint8_t*)op->iov.buf[i].iov_base, op->iov.buf[i].iov_len, (op->enc ? RDR_XTS : 0) | (cl->proto_csum_status == MSGR_CSUM_GCM ? RDR_GCM : 0)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+102
-138
@@ -15,6 +15,8 @@
|
|||||||
#define WR_XTS 2
|
#define WR_XTS 2
|
||||||
#define WR_NO_CSUM 4
|
#define WR_NO_CSUM 4
|
||||||
|
|
||||||
|
#define GCM_TMP_BUF_SIZE 4096
|
||||||
|
|
||||||
class msgr_op_writer_t
|
class msgr_op_writer_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -180,28 +182,11 @@ public:
|
|||||||
from -= src_len;
|
from -= src_len;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(flags & WR_GCM))
|
if (flags & WR_XTS)
|
||||||
{
|
{
|
||||||
if (flags & WR_XTS)
|
msgr->op_encrypted_copy_buf(cl, curbuf, bufsize, src, src_len, from, done);
|
||||||
{
|
|
||||||
msgr->op_encrypted_copy_buf(cl, curbuf, bufsize, src, src_len, from, done);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t n = src_len-from;
|
|
||||||
if (n > bufsize-done)
|
|
||||||
n = bufsize-done;
|
|
||||||
if (!n)
|
|
||||||
return false;
|
|
||||||
if (cl->write_csum_state && !(flags & WR_NO_CSUM))
|
|
||||||
XXH3_64bits_update(cl->write_csum_state, src+from, n);
|
|
||||||
memcpy(curbuf+done, src+from, n);
|
|
||||||
done += n;
|
|
||||||
cl->write_op_pos += n;
|
|
||||||
from += n;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else if (flags & WR_GCM)
|
||||||
{
|
{
|
||||||
size_t n = src_len-from;
|
size_t n = src_len-from;
|
||||||
if (n > bufsize-done)
|
if (n > bufsize-done)
|
||||||
@@ -227,6 +212,20 @@ public:
|
|||||||
cl->write_op_pos += n;
|
cl->write_op_pos += n;
|
||||||
from += n;
|
from += n;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t n = src_len-from;
|
||||||
|
if (n > bufsize-done)
|
||||||
|
n = bufsize-done;
|
||||||
|
if (!n)
|
||||||
|
return false;
|
||||||
|
if (cl->write_csum_state && !(flags & WR_NO_CSUM))
|
||||||
|
XXH3_64bits_update(cl->write_csum_state, src+from, n);
|
||||||
|
memcpy(curbuf+done, src+from, n);
|
||||||
|
done += n;
|
||||||
|
cl->write_op_pos += n;
|
||||||
|
from += n;
|
||||||
|
}
|
||||||
if (from < src_len)
|
if (from < src_len)
|
||||||
return false;
|
return false;
|
||||||
from = 0;
|
from = 0;
|
||||||
@@ -297,63 +296,49 @@ class get_op_writer_t: public msgr_op_writer_t
|
|||||||
osd_client_t* cl;
|
osd_client_t* cl;
|
||||||
size_t from;
|
size_t from;
|
||||||
size_t done;
|
size_t done;
|
||||||
|
size_t op_enc;
|
||||||
size_t enc_size;
|
size_t enc_size;
|
||||||
size_t done_enc;
|
size_t done_enc;
|
||||||
|
uint8_t *enc_buf;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
get_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t*, size_t):
|
get_op_writer_t(osd_messenger_t* msgr, osd_client_t* cl, uint8_t*, size_t):
|
||||||
msgr(msgr), cl(cl), from(cl->write_op_pos), done(0), enc_size(0), done_enc(0)
|
msgr(msgr), cl(cl), from(cl->write_op_pos), done(0), enc_size(0), done_enc(0), enc_buf(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ssl_extend_buf(osd_client_t *cl, size_t more = 0)
|
|
||||||
{
|
|
||||||
size_t min_cap = cl->ssl_out_buf_size*2;
|
|
||||||
if (min_cap < cl->ssl_out_buf_size+more)
|
|
||||||
min_cap = cl->ssl_out_buf_size+more;
|
|
||||||
if (min_cap < 16384)
|
|
||||||
min_cap = 16384;
|
|
||||||
if (cl->ssl_out_buf_cap < min_cap)
|
|
||||||
{
|
|
||||||
uintptr_t old_buf = (uintptr_t)cl->ssl_out_buf;
|
|
||||||
uintptr_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_cap = min_cap;
|
|
||||||
for (auto & iov: cl->send_list)
|
|
||||||
{
|
|
||||||
if ((uintptr_t)iov.iov_base >= old_buf && (uintptr_t)iov.iov_base < old_end)
|
|
||||||
iov.iov_base = cl->ssl_out_buf + ((uintptr_t)iov.iov_base - old_buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void send_out_buf(osd_client_t *cl, size_t n)
|
|
||||||
{
|
|
||||||
if (cl->send_list.size() > 0)
|
|
||||||
{
|
|
||||||
iovec& last = cl->send_list.back();
|
|
||||||
if (last.iov_base+last.iov_len == cl->ssl_out_buf+cl->ssl_out_buf_size)
|
|
||||||
{
|
|
||||||
last.iov_len += n;
|
|
||||||
cl->ssl_out_buf_size += n;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cl->send_list.push_back((iovec){ .iov_base = cl->ssl_out_buf+cl->ssl_out_buf_size, .iov_len = n });
|
|
||||||
cl->ssl_out_buf_size += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
|
op_enc = 0;
|
||||||
from = cl->write_op_pos;
|
from = cl->write_op_pos;
|
||||||
enc_size = 0;
|
|
||||||
done_enc = 0;
|
|
||||||
if (cl->gcm_enabled)
|
if (cl->gcm_enabled)
|
||||||
{
|
{
|
||||||
gcm_op_writer_t::init_ctx(msgr, cl);
|
gcm_op_writer_t::init_ctx(msgr, cl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void extend_tmp(size_t n)
|
||||||
|
{
|
||||||
|
if (!enc_buf || done_enc + n > enc_size)
|
||||||
|
{
|
||||||
|
enc_size = n < GCM_TMP_BUF_SIZE ? GCM_TMP_BUF_SIZE : n;
|
||||||
|
enc_buf = (uint8_t*)malloc_or_die(enc_size);
|
||||||
|
done_enc = 0;
|
||||||
|
assert(!((size_t)enc_buf & 7));
|
||||||
|
cl->send_free_ops.push_back((osd_op_t*)((size_t)enc_buf | 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_tmp(size_t n)
|
||||||
|
{
|
||||||
|
if (cl->send_list.size() && cl->send_list.back().iov_base == (enc_buf + done_enc))
|
||||||
|
cl->send_list.back().iov_len += n;
|
||||||
|
else
|
||||||
|
cl->send_list.push_back((iovec){ .iov_base = enc_buf + done_enc, .iov_len = n });
|
||||||
|
done += n;
|
||||||
|
done_enc += n;
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
@@ -362,63 +347,54 @@ public:
|
|||||||
from -= src_len;
|
from -= src_len;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (cl->send_list.size() >= IOV_MAX)
|
if (cl->send_list.size() >= IOV_MAX-1)
|
||||||
{
|
{
|
||||||
|
// Make sure tag always fits
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (flags & WR_GCM)
|
|
||||||
{
|
|
||||||
if (cl->gcm_enabled)
|
|
||||||
{
|
|
||||||
// Encrypt data to client's temporary output buffer (all at once)
|
|
||||||
size_t n = src_len-from;
|
|
||||||
ssl_extend_buf(cl, n);
|
|
||||||
#ifdef WITH_ISAL_CRYPTO
|
|
||||||
int r = isal_aes_gcm_enc_256_update(&cl->my_key_isal, cl->enc_ctx, cl->ssl_out_buf+cl->ssl_out_buf_size, src+from, n);
|
|
||||||
assert(!r);
|
|
||||||
#else
|
|
||||||
int actual_out;
|
|
||||||
if (EVP_EncryptUpdate(cl->enc_ctx, cl->ssl_out_buf+cl->ssl_out_buf_size, &actual_out, src+from, n) != 1)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "EncryptUpdate error: ");
|
|
||||||
ERR_print_errors_fp(stderr);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
assert(actual_out == n);
|
|
||||||
#endif
|
|
||||||
if (cl->write_csum_state && !(flags & WR_NO_CSUM))
|
|
||||||
XXH3_64bits_update(cl->write_csum_state, src+from, n);
|
|
||||||
send_out_buf(cl, n);
|
|
||||||
done += n;
|
|
||||||
cl->write_op_pos += n;
|
|
||||||
from += n;
|
|
||||||
if (from < src_len)
|
|
||||||
return false;
|
|
||||||
from = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (flags & WR_XTS)
|
if (flags & WR_XTS)
|
||||||
{
|
{
|
||||||
if (!cl->write_op->enc_buf)
|
// Allocate a temporary buffer and encrypt data to it
|
||||||
|
if (!op_enc)
|
||||||
{
|
{
|
||||||
if (cl->send_list.size() >= IOV_MAX-1)
|
|
||||||
{
|
|
||||||
// Make sure that 1 encrypted buffer and 1 checksum fits
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// No way except than to allocate a temporary buffer and encrypt data to it
|
|
||||||
assert(cl->write_op->req.hdr.opcode == OSD_OP_WRITE);
|
assert(cl->write_op->req.hdr.opcode == OSD_OP_WRITE);
|
||||||
enc_size = cl->write_op->req.rw.len - from + (from % 16);
|
op_enc = cl->write_op->req.rw.len - from + (from % 16);
|
||||||
assert(enc_size > 0);
|
assert(op_enc > 0);
|
||||||
cl->write_op->enc_buf = (uint8_t*)malloc_or_die(enc_size);
|
extend_tmp(op_enc);
|
||||||
cl->send_list.push_back((iovec){ .iov_base = cl->write_op->enc_buf, .iov_len = enc_size });
|
|
||||||
done += enc_size;
|
|
||||||
}
|
}
|
||||||
assert(enc_size > 0);
|
size_t new_done = done_enc;
|
||||||
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, enc_buf, enc_size, src, src_len, from, new_done);
|
||||||
|
send_tmp(new_done-done_enc);
|
||||||
assert(from == src_len);
|
assert(from == src_len);
|
||||||
}
|
}
|
||||||
|
else if ((flags & WR_GCM) && cl->gcm_enabled)
|
||||||
|
{
|
||||||
|
// Allocate a temporary buffer and encrypt data to it
|
||||||
|
size_t n = src_len-from;
|
||||||
|
extend_tmp(n);
|
||||||
|
#ifdef WITH_ISAL_CRYPTO
|
||||||
|
int r = isal_aes_gcm_enc_256_update(&cl->my_key_isal, cl->enc_ctx, enc_buf+done_enc, src+from, n);
|
||||||
|
assert(!r);
|
||||||
|
#else
|
||||||
|
int actual_out;
|
||||||
|
if (EVP_EncryptUpdate(cl->enc_ctx, enc_buf+done_enc, &actual_out, src+from, n) != 1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "EncryptUpdate error: ");
|
||||||
|
ERR_print_errors_fp(stderr);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
assert(actual_out == n);
|
||||||
|
#endif
|
||||||
|
if (cl->write_csum_state && !(flags & WR_NO_CSUM))
|
||||||
|
XXH3_64bits_update(cl->write_csum_state, src+from, n);
|
||||||
|
send_tmp(n);
|
||||||
|
cl->write_op_pos += n;
|
||||||
|
from += n;
|
||||||
|
if (from < src_len)
|
||||||
|
return false;
|
||||||
|
from = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (cl->write_csum_state && !(flags & WR_NO_CSUM))
|
if (cl->write_csum_state && !(flags & WR_NO_CSUM))
|
||||||
@@ -435,13 +411,10 @@ public:
|
|||||||
{
|
{
|
||||||
if (cl->enc_ctx)
|
if (cl->enc_ctx)
|
||||||
{
|
{
|
||||||
if (cl->send_list.size() >= IOV_MAX)
|
|
||||||
return false;
|
|
||||||
// Tag is 16 bytes
|
// Tag is 16 bytes
|
||||||
ssl_extend_buf(cl, 16);
|
extend_tmp(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(msgr, cl, enc_buf + done_enc);
|
||||||
send_out_buf(cl, 16);
|
send_tmp(16);
|
||||||
done += 16;
|
|
||||||
gcm_op_writer_t::free_ctx(msgr, cl);
|
gcm_op_writer_t::free_ctx(msgr, cl);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -527,14 +500,15 @@ bool osd_messenger_t::try_send(osd_client_t *cl)
|
|||||||
if (cl->hs)
|
if (cl->hs)
|
||||||
{
|
{
|
||||||
// Send handshake message
|
// Send handshake message
|
||||||
if (cl->hs->get_out().size())
|
if (cl->hs->out_size())
|
||||||
{
|
{
|
||||||
get_op_writer_t::ssl_extend_buf(cl, cl->hs->get_out().size());
|
uint8_t *out = cl->hs->get_out();
|
||||||
memcpy(cl->ssl_out_buf+cl->ssl_out_buf_size, cl->hs->get_out().data(), cl->hs->get_out().size());
|
cl->send_list.push_back((iovec){ .iov_base = out, .iov_len = cl->hs->out_size() });
|
||||||
get_op_writer_t::send_out_buf(cl, cl->hs->get_out().size());
|
assert(!((size_t)out & 7));
|
||||||
cl->hs->get_out().clear();
|
cl->send_free_ops.push_back((osd_op_t*)((size_t)out | 1));
|
||||||
|
cl->hs->reset_out();
|
||||||
}
|
}
|
||||||
if (!cl->hs->get_out().size() && cl->hs->done())
|
if (!cl->hs->out_size() && cl->hs->done())
|
||||||
{
|
{
|
||||||
delete cl->hs;
|
delete cl->hs;
|
||||||
cl->hs = NULL;
|
cl->hs = NULL;
|
||||||
@@ -621,13 +595,13 @@ size_t osd_messenger_t::copy_ops_to(osd_client_t *cl, uint8_t *dst, size_t dst_l
|
|||||||
{
|
{
|
||||||
// Send handshake message
|
// Send handshake message
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
if (cl->hs->get_out().size())
|
if (cl->hs->out_size())
|
||||||
{
|
{
|
||||||
n = cl->hs->get_out().size() < dst_len ? cl->hs->get_out().size() : dst_len;
|
n = cl->hs->out_size() < dst_len ? cl->hs->out_size() : dst_len;
|
||||||
memcpy(dst, cl->hs->get_out().data(), n);
|
memcpy(dst, cl->hs->get_out(), n);
|
||||||
cl->hs->get_out().erase(cl->hs->get_out().begin(), cl->hs->get_out().begin() + n);
|
cl->hs->eat_out(n);
|
||||||
}
|
}
|
||||||
if (!cl->hs->get_out().size() && cl->hs->done())
|
if (!cl->hs->out_size() && cl->hs->done())
|
||||||
{
|
{
|
||||||
delete cl->hs;
|
delete cl->hs;
|
||||||
cl->hs = NULL;
|
cl->hs = NULL;
|
||||||
@@ -750,24 +724,14 @@ void osd_messenger_t::handle_send(int result, bool prev, bool more, osd_client_t
|
|||||||
for (auto op: cl->send_free_ops)
|
for (auto op: cl->send_free_ops)
|
||||||
{
|
{
|
||||||
if (more)
|
if (more)
|
||||||
{
|
|
||||||
assert(!((size_t)op & 7));
|
|
||||||
cl->zc_free_list.push_back(op);
|
cl->zc_free_list.push_back(op);
|
||||||
}
|
else if (!((size_t)op & 7))
|
||||||
else
|
|
||||||
delete op;
|
delete op;
|
||||||
|
else
|
||||||
|
free((void*)((size_t)op & ~(size_t)7));
|
||||||
}
|
}
|
||||||
if (more)
|
if (more)
|
||||||
{
|
|
||||||
if (cl->ssl_out_buf_size)
|
|
||||||
{
|
|
||||||
cl->zc_free_list.push_back((osd_op_t*)((size_t)cl->ssl_out_buf | 1));
|
|
||||||
cl->ssl_out_buf = NULL;
|
|
||||||
cl->ssl_out_buf_cap = 0;
|
|
||||||
}
|
|
||||||
cl->zc_free_list.push_back(NULL); // end marker
|
cl->zc_free_list.push_back(NULL); // end marker
|
||||||
}
|
|
||||||
cl->ssl_out_buf_size = 0;
|
|
||||||
cl->send_free_ops.clear();
|
cl->send_free_ops.clear();
|
||||||
cl->write_state = 0;
|
cl->write_state = 0;
|
||||||
if (cl->write_op || cl->write_ops.size())
|
if (cl->write_op || cl->write_ops.size())
|
||||||
@@ -875,7 +839,7 @@ bool osd_messenger_t::op_write_to(osd_client_t *cl, msgr_op_writer_t & wr)
|
|||||||
for (int i = 0; i < cl->write_op->iov.count; i++)
|
for (int i = 0; i < cl->write_op->iov.count; i++)
|
||||||
{
|
{
|
||||||
auto & iov = cl->write_op->iov.buf[i];
|
auto & iov = cl->write_op->iov.buf[i];
|
||||||
if (!wr.write((uint8_t*)iov.iov_base, iov.iov_len, (op->enc ? WR_XTS : 0)))
|
if (!wr.write((uint8_t*)iov.iov_base, iov.iov_len, (op->enc ? WR_XTS : 0) | (cl->proto_csum_status == MSGR_CSUM_GCM ? WR_GCM : 0)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,7 +202,10 @@ osd_client_t::~osd_client_t()
|
|||||||
{
|
{
|
||||||
if (op)
|
if (op)
|
||||||
{
|
{
|
||||||
delete op;
|
if (!((size_t)op & 7))
|
||||||
|
delete op;
|
||||||
|
else
|
||||||
|
free((void*)((size_t)op & ~(size_t)7));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (osd_op_t *op: zc_free_list)
|
for (osd_op_t *op: zc_free_list)
|
||||||
@@ -243,11 +246,6 @@ osd_client_t::~osd_client_t()
|
|||||||
#endif
|
#endif
|
||||||
dec_ctx = NULL;
|
dec_ctx = NULL;
|
||||||
}
|
}
|
||||||
if (ssl_out_buf)
|
|
||||||
{
|
|
||||||
free(ssl_out_buf);
|
|
||||||
ssl_out_buf = NULL;
|
|
||||||
}
|
|
||||||
if (hs)
|
if (hs)
|
||||||
{
|
{
|
||||||
delete hs;
|
delete hs;
|
||||||
|
|||||||
@@ -376,14 +376,23 @@ void osd_t::exec_show_config(osd_op_t *cur_op)
|
|||||||
if (msgr.use_proto_checksums)
|
if (msgr.use_proto_checksums)
|
||||||
{
|
{
|
||||||
auto peer_csums = req_json["features"]["proto_checksums"].uint64_value();
|
auto peer_csums = req_json["features"]["proto_checksums"].uint64_value();
|
||||||
if (peer_csums == MSGR_CSUM_FULL || peer_csums == MSGR_CSUM_PAYLOAD)
|
if (peer_csums == MSGR_CSUM_FULL || peer_csums == MSGR_CSUM_PAYLOAD ||
|
||||||
|
cl->gcm_enabled && peer_csums == MSGR_CSUM_GCM)
|
||||||
{
|
{
|
||||||
if (msgr.use_proto_checksums == MSGR_CSUM_FULL && peer_csums == MSGR_CSUM_FULL)
|
if (msgr.use_proto_checksums == MSGR_CSUM_GCM && peer_csums == MSGR_CSUM_GCM)
|
||||||
|
cl->proto_csum_status = MSGR_CSUM_GCM|MSGR_CSUM_NEG;
|
||||||
|
else if (msgr.use_proto_checksums == MSGR_CSUM_FULL && peer_csums == MSGR_CSUM_FULL)
|
||||||
cl->proto_csum_status = MSGR_CSUM_FULL|MSGR_CSUM_NEG;
|
cl->proto_csum_status = MSGR_CSUM_FULL|MSGR_CSUM_NEG;
|
||||||
else
|
else
|
||||||
cl->proto_csum_status = MSGR_CSUM_PAYLOAD|MSGR_CSUM_NEG;
|
cl->proto_csum_status = MSGR_CSUM_PAYLOAD|MSGR_CSUM_NEG;
|
||||||
features["proto_checksums"] = msgr.use_proto_checksums;
|
features["proto_checksums"] = msgr.use_proto_checksums;
|
||||||
}
|
}
|
||||||
|
if (peer_csums < msgr.force_proto_checksums)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: Client %ju use_proto_checksums security level is lower than force_proto_checksums\n", cl->client_id);
|
||||||
|
msgr.stop_client(cl->client_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Expose sensitive configuration values so peers can check them
|
// Expose sensitive configuration values so peers can check them
|
||||||
json11::Json::object wire_config = json11::Json::object {
|
json11::Json::object wire_config = json11::Json::object {
|
||||||
|
|||||||
@@ -663,11 +663,12 @@ void test_msgr_encrypt()
|
|||||||
uint8_t *crypt2 = (uint8_t*)malloc_or_die(sz);
|
uint8_t *crypt2 = (uint8_t*)malloc_or_die(sz);
|
||||||
uint8_t *key = (uint8_t*)malloc_or_die(64);
|
uint8_t *key = (uint8_t*)malloc_or_die(64);
|
||||||
RAND_bytes(key, 64);
|
RAND_bytes(key, 64);
|
||||||
|
osd_client_t cl;
|
||||||
|
|
||||||
// Basic encrypt+decrypt and also get reference data
|
// Basic encrypt+decrypt and also get reference data
|
||||||
|
|
||||||
auto enc = new op_aes_xts_encrypt_t();
|
auto enc = new op_aes_xts_encrypt_t();
|
||||||
enc->start(key, 4096 * 113, 4096);
|
enc->start(&cl, key, 4096 * 113, 4096);
|
||||||
size_t in_pos = 0;
|
size_t in_pos = 0;
|
||||||
size_t out_pos = 0;
|
size_t out_pos = 0;
|
||||||
while (out_pos < sz)
|
while (out_pos < sz)
|
||||||
@@ -676,7 +677,7 @@ void test_msgr_encrypt()
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto dec = new op_aes_xts_decrypt_t();
|
auto dec = new op_aes_xts_decrypt_t();
|
||||||
dec->start(&key, 1, NULL, 4096 * 113, 4096);
|
dec->start(&cl, &key, 1, NULL, 4096 * 113, 4096);
|
||||||
in_pos = out_pos = 0;
|
in_pos = out_pos = 0;
|
||||||
while (out_pos < sz)
|
while (out_pos < sz)
|
||||||
{
|
{
|
||||||
@@ -687,7 +688,7 @@ void test_msgr_encrypt()
|
|||||||
|
|
||||||
// Insufficient output encrypt
|
// Insufficient output encrypt
|
||||||
printf("...insufficient output encrypt\n");
|
printf("...insufficient output encrypt\n");
|
||||||
enc->start(key, 4096 * 114, 4096);
|
enc->start(&cl, key, 4096 * 114, 4096);
|
||||||
in_pos = out_pos = 0;
|
in_pos = out_pos = 0;
|
||||||
enc->update(src+4096, 4096, crypt2, 4095, in_pos, out_pos);
|
enc->update(src+4096, 4096, crypt2, 4095, in_pos, out_pos);
|
||||||
assert(in_pos == 4095);
|
assert(in_pos == 4095);
|
||||||
@@ -699,7 +700,7 @@ void test_msgr_encrypt()
|
|||||||
|
|
||||||
// Fragmented encrypt
|
// Fragmented encrypt
|
||||||
printf("...fragmented encrypt\n");
|
printf("...fragmented encrypt\n");
|
||||||
enc->start(key, 4096 * 114, 4096);
|
enc->start(&cl, key, 4096 * 114, 4096);
|
||||||
in_pos = out_pos = 0;
|
in_pos = out_pos = 0;
|
||||||
enc->update(src+4096, 2000, crypt2, 4095, in_pos, out_pos);
|
enc->update(src+4096, 2000, crypt2, 4095, in_pos, out_pos);
|
||||||
assert(in_pos == 2000);
|
assert(in_pos == 2000);
|
||||||
@@ -712,7 +713,7 @@ void test_msgr_encrypt()
|
|||||||
// Fragmented decrypt
|
// Fragmented decrypt
|
||||||
// Input: 1000 + 2000 + 3000 + 2192, output: 500 + 3000 + 1000 + 3000 + 692
|
// Input: 1000 + 2000 + 3000 + 2192, output: 500 + 3000 + 1000 + 3000 + 692
|
||||||
printf("...fragmented decrypt\n");
|
printf("...fragmented decrypt\n");
|
||||||
dec->start(&key, 1, NULL, 4096 * 114, 4096);
|
dec->start(&cl, &key, 1, NULL, 4096 * 114, 4096);
|
||||||
in_pos = out_pos = 0;
|
in_pos = out_pos = 0;
|
||||||
dec->update(crypt+4096, 1000, decrypt, 500, in_pos, out_pos);
|
dec->update(crypt+4096, 1000, decrypt, 500, in_pos, out_pos);
|
||||||
assert(in_pos == 1000);
|
assert(in_pos == 1000);
|
||||||
@@ -746,7 +747,7 @@ void test_msgr_encrypt()
|
|||||||
// Extra size decrypt
|
// Extra size decrypt
|
||||||
// Input: 8192, output: 4096
|
// Input: 8192, output: 4096
|
||||||
printf("...extra size decrypt\n");
|
printf("...extra size decrypt\n");
|
||||||
dec->start(&key, 1, NULL, 4096 * 114, 4096);
|
dec->start(&cl, &key, 1, NULL, 4096 * 114, 4096);
|
||||||
in_pos = out_pos = 0;
|
in_pos = out_pos = 0;
|
||||||
dec->update(crypt+4096, 8192, decrypt, 4096, in_pos, out_pos);
|
dec->update(crypt+4096, 8192, decrypt, 4096, in_pos, out_pos);
|
||||||
assert(in_pos == 4096);
|
assert(in_pos == 4096);
|
||||||
@@ -776,6 +777,7 @@ void test_msgr_decrypt_chain()
|
|||||||
RAND_bytes(key, 64);
|
RAND_bytes(key, 64);
|
||||||
uint8_t *key2 = (uint8_t*)malloc_or_die(64);
|
uint8_t *key2 = (uint8_t*)malloc_or_die(64);
|
||||||
RAND_bytes(key2, 64);
|
RAND_bytes(key2, 64);
|
||||||
|
osd_client_t cl;
|
||||||
|
|
||||||
// Chained decryption with multiple keys
|
// Chained decryption with multiple keys
|
||||||
|
|
||||||
@@ -783,17 +785,17 @@ void test_msgr_decrypt_chain()
|
|||||||
size_t in_pos = 0, out_pos = 0;
|
size_t in_pos = 0, out_pos = 0;
|
||||||
auto enc = new op_aes_xts_encrypt_t();
|
auto enc = new op_aes_xts_encrypt_t();
|
||||||
// block 1 with key1
|
// block 1 with key1
|
||||||
enc->start(key, 4096 * 113, 4096);
|
enc->start(&cl, key, 4096 * 113, 4096);
|
||||||
enc->update(src, 4096, crypt, 4096, in_pos, out_pos);
|
enc->update(src, 4096, crypt, 4096, in_pos, out_pos);
|
||||||
assert(in_pos == 4096 && out_pos == 4096);
|
assert(in_pos == 4096 && out_pos == 4096);
|
||||||
// block 2 as plain
|
// block 2 as plain
|
||||||
memcpy(crypt + 4096, src + 4096, 4096);
|
memcpy(crypt + 4096, src + 4096, 4096);
|
||||||
// block 3 with key2
|
// block 3 with key2
|
||||||
enc->start(key2, 4096 * 115, 4096);
|
enc->start(&cl, key2, 4096 * 115, 4096);
|
||||||
enc->update(src + 2*4096, 4096, crypt + 2*4096, 4096, in_pos, out_pos);
|
enc->update(src + 2*4096, 4096, crypt + 2*4096, 4096, in_pos, out_pos);
|
||||||
assert(in_pos == 2*4096 && out_pos == 2*4096);
|
assert(in_pos == 2*4096 && out_pos == 2*4096);
|
||||||
// block 4 again with key1
|
// block 4 again with key1
|
||||||
enc->start(key, 4096 * 116, 4096);
|
enc->start(&cl, key, 4096 * 116, 4096);
|
||||||
enc->update(src + 3*4096, 4096, crypt + 3*4096, 4096, in_pos, out_pos);
|
enc->update(src + 3*4096, 4096, crypt + 3*4096, 4096, in_pos, out_pos);
|
||||||
assert(in_pos == 3*4096 && out_pos == 3*4096);
|
assert(in_pos == 3*4096 && out_pos == 3*4096);
|
||||||
|
|
||||||
@@ -801,7 +803,7 @@ void test_msgr_decrypt_chain()
|
|||||||
uint8_t* keys[3] = { key, key2, NULL };
|
uint8_t* keys[3] = { key, key2, NULL };
|
||||||
uint8_t chain_info[4] = { 0, 2, 1, 0 };
|
uint8_t chain_info[4] = { 0, 2, 1, 0 };
|
||||||
auto dec = new op_aes_xts_decrypt_t();
|
auto dec = new op_aes_xts_decrypt_t();
|
||||||
dec->start(keys, 3, chain_info, 4096 * 113, 4096);
|
dec->start(&cl, keys, 3, chain_info, 4096 * 113, 4096);
|
||||||
in_pos = out_pos = 0;
|
in_pos = out_pos = 0;
|
||||||
while (out_pos < sz)
|
while (out_pos < sz)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ OLD=1 ./test_move_reappear.sh
|
|||||||
./test_snapshot_chain.sh
|
./test_snapshot_chain.sh
|
||||||
SCHEME=ec ./test_snapshot_chain.sh
|
SCHEME=ec ./test_snapshot_chain.sh
|
||||||
ENCRYPTED=1 ./test_snapshot_chain.sh
|
ENCRYPTED=1 ./test_snapshot_chain.sh
|
||||||
|
TEST_NAME=enc_gcm ENCRYPTED=1 VITASTOR_CFG=',"proto_checksums":"gcm"' ./test_snapshot_chain.sh
|
||||||
OLD=1 ./test_snapshot_chain.sh
|
OLD=1 ./test_snapshot_chain.sh
|
||||||
OLD=1 SCHEME=ec ./test_snapshot_chain.sh
|
OLD=1 SCHEME=ec ./test_snapshot_chain.sh
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user