Skip to content

Commit

Permalink
upgrade to AES-GCM-SIV
Browse files Browse the repository at this point in the history
  • Loading branch information
Your Name committed Mar 25, 2024
1 parent 367c8fe commit 2ac4b20
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 27 deletions.
8 changes: 6 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rxqlite"
version = "0.1.6"
version = "0.1.7"
readme = "README.md"

edition = "2021"
Expand Down Expand Up @@ -80,6 +80,10 @@ version = "0.7"
version = "0.9"
optional = true

[dependencies.aes-gcm-siv]
version = "0.11.1"
optional = true

[dependencies.ring]
version = "0.17"
optional = true
Expand All @@ -99,7 +103,7 @@ rxqlite-tests-common = { version = "0.1" , path = "crates/rxqlite-tests-common"
[features]
default = [ "bundled-sqlcipher-vendored-openssl" ]
test-dependency = [ "futures" , "rxqlite-tests-common" ]
sqlcipher = [ "sqlx-sqlite-cipher/sqlcipher" , "rsa-crate" , "ring" , "base64" ]
sqlcipher = [ "sqlx-sqlite-cipher/sqlcipher" , "rsa-crate" , "ring" , "base64" , "aes-gcm-siv" ]
bundled-sqlcipher = [ "sqlx-sqlite-cipher/bundled-sqlcipher" , "sqlcipher" ]
bundled-sqlcipher-vendored-openssl = [ "sqlx-sqlite-cipher/bundled-sqlcipher-vendored-openssl" , "sqlcipher" ]

Expand Down
68 changes: 68 additions & 0 deletions src/cipher/aes_gcm_siv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use super::*;

use ::aes_gcm_siv::{Aes256GcmSiv,AeadInPlace,KeyInit,Nonce};
use ::aes_gcm_siv::aead::generic_array::GenericArray;


use ::ring::rand::{SystemRandom, SecureRandom};
use ::ring::pbkdf2;
use rustls::pki_types::PrivatePkcs8KeyDer;
use std::num::NonZeroU32;

pub struct Aes256GcmSivEncryptor {
cipher: Aes256GcmSiv,
}

impl Aes256GcmSivEncryptor {
pub fn new(pkcs8_key_der: &PrivatePkcs8KeyDer) -> Self {
let key_bytes = pkcs8_key_der.secret_pkcs8_der();
let mut derived_key = vec![0u8; 32];
let iterations = NonZeroU32::new(1).unwrap(); // only one iteration: private key is said secure
static PBKDF2_ALG: pbkdf2::Algorithm = pbkdf2::PBKDF2_HMAC_SHA256;
pbkdf2::derive(
PBKDF2_ALG,
iterations,
key_bytes, // use key_bytes as salt
&key_bytes,
&mut derived_key,
);

let key = GenericArray::clone_from_slice(&derived_key);
let cipher = Aes256GcmSiv::new(&key);

Aes256GcmSivEncryptor { cipher }
}
}

impl EncryptData for Aes256GcmSivEncryptor {
fn encrypt(&self, mut data: Vec<u8>) -> Result<Vec<u8>,StorageIOError> {
let rng = SystemRandom::new();
let mut nonce_ = [0u8; 12];
rng.fill(&mut nonce_).map_err(|err|StorageIOError::write_logs(&std::io::Error::new(
std::io::ErrorKind::Other,format!("{}",err).as_str()
)))?;
let nonce = Nonce::from_slice(&nonce_);
self.cipher.encrypt_in_place(nonce, b"", &mut data).map_err(|err|StorageIOError::write_logs(&std::io::Error::new(
std::io::ErrorKind::Other,format!("{}",err).as_str()
)))?;
let mut encrypted_data = nonce.to_vec();
encrypted_data.append(&mut data);
Ok(encrypted_data)
}

fn decrypt(&self, data: &mut Vec<u8>) -> Result<(), StorageIOError> {
let nonce = &data[..12];
let nonce: [u8 ; 12] = nonce.to_vec().try_into().unwrap();
let nonce = Nonce::from(nonce);
data.drain(0..12);

match self.cipher.decrypt_in_place(&nonce, b"", data) {
Ok(_) => {
Ok(())
},
Err(err) => Err(StorageIOError::read_logs(&std::io::Error::new(
std::io::ErrorKind::Other, format!("{}", err).as_str()
))),
}
}
}
18 changes: 9 additions & 9 deletions src/cipher/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
use std::sync::Arc;
use crate::NodeId;
use std::ops::Range;

type StorageIOError = openraft::StorageIOError<NodeId>;

pub trait EncryptData : Send + Sync + 'static {
fn encrypt(&self,data: Vec<u8>) -> Result<Vec<u8>,StorageIOError>;
fn decrypt(&self,data: &mut [u8]) -> Result<Range<usize>,StorageIOError>;
fn decrypt(&self,data: &mut Vec<u8>) -> Result<(),StorageIOError>;
}

pub struct NoEncrypt;
Expand All @@ -15,8 +14,8 @@ impl EncryptData for NoEncrypt {
fn encrypt(&self,data: Vec<u8>) -> Result<Vec<u8>,StorageIOError> {
Ok(data)
}
fn decrypt(&self,data: &mut [u8]) -> Result<Range<usize>,StorageIOError> {
Ok(0..data.len())
fn decrypt(&self,_data: &mut Vec<u8>) -> Result<(),StorageIOError> {
Ok(())
}
}

Expand All @@ -27,19 +26,20 @@ impl EncryptData for Option<Arc<Box<dyn EncryptData>>> {
None=>Ok(data),
}
}
fn decrypt(&self,data: &mut [u8]) -> Result<Range<usize>,StorageIOError> {
fn decrypt(&self,data: &mut Vec<u8>) -> Result<(),StorageIOError> {
match self {
Some(encrypt_data)=>encrypt_data.decrypt(data),
None=>Ok(0..data.len()),
None=>Ok(()),
}
}
}

//#[cfg(feature = "rsa-crate")]
//pub mod rsa;

#[cfg(feature = "sqlcipher")]
pub mod ring;

//#[cfg(feature = "sqlcipher")]
//pub mod ring;

#[cfg(feature = "sqlcipher")]
pub mod aes_gcm_siv;

4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ use std::io::BufReader;
use serde::{Serialize,Deserialize};

#[cfg(feature = "sqlcipher")]
use crate::cipher::ring::Aes256GcmEncryptor;
use crate::cipher::aes_gcm_siv::Aes256GcmSivEncryptor;
#[cfg(feature = "sqlcipher")]
use ring::digest;
#[cfg(feature = "sqlcipher")]
Expand Down Expand Up @@ -183,7 +183,7 @@ where

let private_key = rustls::pki_types::PrivatePkcs8KeyDer::from(private_key_bytes);

let encrypt_data = Aes256GcmEncryptor::new(&private_key);
let encrypt_data = Aes256GcmSivEncryptor::new(&private_key);



Expand Down
31 changes: 17 additions & 14 deletions src/sqlite_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ impl StateMachineStore {
})?;
match encrypted_data {
Some(mut encrypted_data)=> {
let r=self.encrypt_data.decrypt(&mut encrypted_data)?;
Ok(serde_json::from_slice(&encrypted_data[r.start..r.end]).ok())
self.encrypt_data.decrypt(&mut encrypted_data)?;
Ok(serde_json::from_slice(&encrypted_data).ok())
}
None=>{
Ok(None)
Expand Down Expand Up @@ -345,8 +345,8 @@ impl LogStore {
return Ok(None);
}
let mut encrypted_data = encrypted_data.unwrap();
let r=self.encrypt_data.decrypt(&mut encrypted_data)?;
Ok(serde_json::from_slice(&encrypted_data[r.start..r.end]).ok())
self.encrypt_data.decrypt(&mut encrypted_data)?;
Ok(serde_json::from_slice(&encrypted_data).ok())
}

fn set_last_purged_(&self, log_id: LogId<u64>) -> StorageResult<()> {
Expand Down Expand Up @@ -386,8 +386,8 @@ impl LogStore {
return Ok(None);
}
let mut encrypted_data = encrypted_data.unwrap();
let r=self.encrypt_data.decrypt(&mut encrypted_data)?;
Ok(serde_json::from_slice(&encrypted_data[r.start..r.end]).ok())
self.encrypt_data.decrypt(&mut encrypted_data)?;
Ok(serde_json::from_slice(&encrypted_data).ok())
}

fn set_vote_(&self, vote: &Vote<NodeId>) -> StorageResult<()> {
Expand Down Expand Up @@ -416,8 +416,8 @@ impl LogStore {
return Ok(None);
}
let mut encrypted_data = encrypted_data.unwrap();
let r=self.encrypt_data.decrypt(&mut encrypted_data)?;
Ok(serde_json::from_slice(&encrypted_data[r.start..r.end]).ok())
self.encrypt_data.decrypt(&mut encrypted_data)?;
Ok(serde_json::from_slice(&encrypted_data).ok())
}
}

Expand All @@ -434,17 +434,19 @@ impl RaftLogReader<TypeConfig> for LogStore {
self.db
.iterator_cf(self.logs(), rocksdb::IteratorMode::From(&start, Direction::Forward))
.map(|res| {
let (id, mut val) = res.unwrap();
let (id, val) = res.unwrap();
/*
let val=match self.encrypt_data.decrypt(Some(val.to_vec())) {
Ok(val)=>val.unwrap(),
Err(err)=>return (bin_to_id(&id),Err(err.into())),
};
*/
let mut val = val.into_vec();
let entry: StorageResult<Entry<_>> =

match self.encrypt_data.decrypt(&mut val) {
Ok(r)=> {
serde_json::from_slice(&val[r.start..r.end]).map_err(|e|
Ok(_)=> {
serde_json::from_slice(&val).map_err(|e|
StorageError::IO {
source: StorageIOError::read_logs(&e),
})
Expand Down Expand Up @@ -479,10 +481,11 @@ impl RaftLogStorage<TypeConfig> for LogStore {

async fn get_log_state(&mut self) -> StorageResult<LogState<TypeConfig>> {
let last = self.db.iterator_cf(self.logs(), rocksdb::IteratorMode::End).next().and_then(|res| {
let (_, mut ent) = res.unwrap();
let (_, ent) = res.unwrap();
let mut ent = ent.into_vec();
match self.encrypt_data.decrypt(&mut ent) {
Ok(r)=> {
Some(Ok(serde_json::from_slice::<Entry<TypeConfig>>(&ent[r.start..r.end]).ok()?.log_id))
Ok(_)=> {
Some(Ok(serde_json::from_slice::<Entry<TypeConfig>>(&ent).ok()?.log_id))
}
Err(err)=>return Some(Err::<_,StorageError<NodeId>>(err.into())),
}
Expand Down

0 comments on commit 2ac4b20

Please sign in to comment.