Unverified Commit c912ea07 authored by dorianzheng's avatar dorianzheng Committed by GitHub

Support self-defined base env for encrypted env (#254)

* Support encrypted env

* Support encrypted env

* Add tests

* guard base env

* guard base env

* guard base env
parent c2eb1400
...@@ -3282,15 +3282,16 @@ struct CTRBlockCipher : public BlockCipher { ...@@ -3282,15 +3282,16 @@ struct CTRBlockCipher : public BlockCipher {
size_t block_size_; size_t block_size_;
}; };
crocksdb_env_t* crocksdb_default_ctr_encrypted_env_create( crocksdb_env_t*
crocksdb_ctr_encrypted_env_create(crocksdb_env_t* base_env,
const char* ciphertext, size_t ciphertext_len) { const char* ciphertext, size_t ciphertext_len) {
auto result = new crocksdb_env_t; auto result = new crocksdb_env_t;
result->block_cipher = new CTRBlockCipher( result->block_cipher = new CTRBlockCipher(
ciphertext_len, std::string(ciphertext, ciphertext_len)); ciphertext_len, std::string(ciphertext, ciphertext_len));
result->encryption_provoider = result->encryption_provoider =
new CTREncryptionProvider(*result->block_cipher); new CTREncryptionProvider(*result->block_cipher);
result->rep = NewEncryptedEnv(Env::Default(), result->encryption_provoider); result->rep = NewEncryptedEnv(base_env->rep, result->encryption_provoider);
result->is_default = true; result->is_default = false;
return result; return result;
} }
......
...@@ -1309,8 +1309,9 @@ extern C_ROCKSDB_LIBRARY_API void crocksdb_cache_set_capacity( ...@@ -1309,8 +1309,9 @@ extern C_ROCKSDB_LIBRARY_API void crocksdb_cache_set_capacity(
extern C_ROCKSDB_LIBRARY_API crocksdb_env_t* crocksdb_default_env_create(); extern C_ROCKSDB_LIBRARY_API crocksdb_env_t* crocksdb_default_env_create();
extern C_ROCKSDB_LIBRARY_API crocksdb_env_t* crocksdb_mem_env_create(); extern C_ROCKSDB_LIBRARY_API crocksdb_env_t* crocksdb_mem_env_create();
extern C_ROCKSDB_LIBRARY_API crocksdb_env_t* extern C_ROCKSDB_LIBRARY_API crocksdb_env_t*
crocksdb_default_ctr_encrypted_env_create(const char* ciphertext, crocksdb_ctr_encrypted_env_create(crocksdb_env_t* base_env,
size_t ciphertext_len); const char* ciphertext,
size_t ciphertext_len);
extern C_ROCKSDB_LIBRARY_API void crocksdb_env_set_background_threads( extern C_ROCKSDB_LIBRARY_API void crocksdb_env_set_background_threads(
crocksdb_env_t* env, int n); crocksdb_env_t* env, int n);
extern C_ROCKSDB_LIBRARY_API void extern C_ROCKSDB_LIBRARY_API void
......
...@@ -1128,7 +1128,8 @@ extern "C" { ...@@ -1128,7 +1128,8 @@ extern "C" {
// Env // Env
pub fn crocksdb_default_env_create() -> *mut DBEnv; pub fn crocksdb_default_env_create() -> *mut DBEnv;
pub fn crocksdb_mem_env_create() -> *mut DBEnv; pub fn crocksdb_mem_env_create() -> *mut DBEnv;
pub fn crocksdb_default_ctr_encrypted_env_create( pub fn crocksdb_ctr_encrypted_env_create(
base_env: *mut DBEnv,
ciphertext: *const c_char, ciphertext: *const c_char,
ciphertext_len: size_t, ciphertext_len: size_t,
) -> *mut DBEnv; ) -> *mut DBEnv;
......
...@@ -1664,7 +1664,10 @@ impl Drop for DB { ...@@ -1664,7 +1664,10 @@ impl Drop for DB {
fn drop(&mut self) { fn drop(&mut self) {
// SyncWAL before call close. // SyncWAL before call close.
if !self.readonly { if !self.readonly {
self.sync_wal().unwrap(); // DB::SyncWal requires writable file support thread safe sync, but
// not all types of env can create writable file that support thread
// safe sync. eg, MemEnv.
self.sync_wal().unwrap_or_else(|_| {});
} }
unsafe { unsafe {
self.cfs.clear(); self.cfs.clear();
...@@ -2082,6 +2085,8 @@ pub fn supported_compression() -> Vec<DBCompressionType> { ...@@ -2082,6 +2085,8 @@ pub fn supported_compression() -> Vec<DBCompressionType> {
pub struct Env { pub struct Env {
pub inner: *mut DBEnv, pub inner: *mut DBEnv,
#[allow(dead_code)]
base: Option<Arc<Env>>,
} }
unsafe impl Send for Env {} unsafe impl Send for Env {}
...@@ -2093,6 +2098,7 @@ impl Default for Env { ...@@ -2093,6 +2098,7 @@ impl Default for Env {
unsafe { unsafe {
Env { Env {
inner: crocksdb_ffi::crocksdb_default_env_create(), inner: crocksdb_ffi::crocksdb_default_env_create(),
base: None,
} }
} }
} }
...@@ -2103,14 +2109,15 @@ impl Env { ...@@ -2103,14 +2109,15 @@ impl Env {
unsafe { unsafe {
Env { Env {
inner: crocksdb_ffi::crocksdb_mem_env_create(), inner: crocksdb_ffi::crocksdb_mem_env_create(),
base: None,
} }
} }
} }
// Create a ctr encrypted env with the default env and a given ciper text. // Create a ctr encrypted env with a given base env and a given ciper text.
// The length of ciper text must be 2^n, and must be less or equal to 2048. // The length of ciper text must be 2^n, and must be less or equal to 2048.
// The recommanded block size are 1024, 512 and 256. // The recommanded block size are 1024, 512 and 256.
pub fn new_default_ctr_encrypted_env(ciphertext: &[u8]) -> Result<Env, String> { pub fn new_ctr_encrypted_env(base_env: Arc<Env>, ciphertext: &[u8]) -> Result<Env, String> {
let len = ciphertext.len(); let len = ciphertext.len();
if len > 2048 || !is_power_of_two(len) { if len > 2048 || !is_power_of_two(len) {
return Err( return Err(
...@@ -2119,12 +2126,21 @@ impl Env { ...@@ -2119,12 +2126,21 @@ impl Env {
); );
} }
let env = unsafe { let env = unsafe {
crocksdb_ffi::crocksdb_default_ctr_encrypted_env_create( crocksdb_ffi::crocksdb_ctr_encrypted_env_create(
base_env.inner,
mem::transmute(&ciphertext[0]), mem::transmute(&ciphertext[0]),
len, len,
) )
}; };
Ok(Env { inner: env }) Ok(Env {
inner: env,
base: Some(base_env),
})
}
// Create a ctr encrypted env with the default env
pub fn new_default_ctr_encrypted_env(ciphertext: &[u8]) -> Result<Env, String> {
Env::new_ctr_encrypted_env(Arc::new(Env::default()), ciphertext)
} }
pub fn new_sequential_file( pub fn new_sequential_file(
......
...@@ -22,6 +22,12 @@ fn test_ctr_encrypted_env() { ...@@ -22,6 +22,12 @@ fn test_ctr_encrypted_env() {
&[16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], &[16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1],
&[8, 7, 6, 5, 4, 3, 2, 1], &[8, 7, 6, 5, 4, 3, 2, 1],
]; ];
for ciphertext in test_cipher_texts {
let base_env = Arc::new(Env::new_mem());
test_ctr_encrypted_env_impl(Arc::new(
Env::new_ctr_encrypted_env(Arc::clone(&base_env), ciphertext).unwrap(),
));
}
for ciphertext in test_cipher_texts { for ciphertext in test_cipher_texts {
test_ctr_encrypted_env_impl(Arc::new( test_ctr_encrypted_env_impl(Arc::new(
Env::new_default_ctr_encrypted_env(ciphertext).unwrap(), Env::new_default_ctr_encrypted_env(ciphertext).unwrap(),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment