diff options
-rw-r--r-- | Cargo.lock | 33 | ||||
-rw-r--r-- | lockchain-core/src/record.rs | 2 | ||||
-rw-r--r-- | lockchain-core/src/traits.rs | 2 | ||||
-rw-r--r-- | lockchain-crypto/Cargo.toml | 6 | ||||
-rw-r--r-- | lockchain-crypto/src/data.rs | 13 | ||||
-rw-r--r-- | lockchain-crypto/src/databody.rs | 8 | ||||
-rw-r--r-- | lockchain-crypto/src/engine.rs | 62 | ||||
-rw-r--r-- | lockchain-crypto/src/keys.rs | 37 | ||||
-rw-r--r-- | lockchain-crypto/src/lib.rs | 18 | ||||
-rw-r--r-- | lockchain-crypto/src/utils.rs (renamed from src/security/utils.rs) | 0 |
10 files changed, 166 insertions, 15 deletions
@@ -43,6 +43,16 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] +name = "blake2" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crypto-mac 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "block-cipher-trait" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -111,6 +121,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "crypto-mac" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crypto-mac" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ @@ -127,6 +146,14 @@ dependencies = [ ] [[package]] +name = "digest" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] name = "dtoa" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -188,8 +215,11 @@ dependencies = [ name = "lockchain-crypto" version = "0.1.0" dependencies = [ + "base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "lockchain-core 0.3.1", "miscreant 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.50 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -372,6 +402,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum base64 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9263aa6a38da271eec5c91a83ce1e800f093c8535788d403d626d8d5c3f8f007" "checksum bcrypt 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a1512813db09170b44a00870b58421876d797b77b085c5205a24db90905f758" "checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789" +"checksum blake2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73b77e29dbd0115e43938be2d5128ecf81c0353e00acaa65339a1242586951d9" "checksum block-cipher-trait 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6136d803280ae3532efa36114335255ea94f3d75d735ddedd66b0d7cd30bad3" "checksum blowfish 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "95ede07672d9f4144c578439aa352604ec5c67a80c940fe8d382ddbeeeb3c6d8" "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40" @@ -381,8 +412,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "checksum cmac 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44f175b5f76aa82ebe4c7e85ef95b23e9293c5618db28461cb10ee929e0f6e2f" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" +"checksum crypto-mac 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0999b4ff4d3446d4ddb19a63e9e00c1876e75cd7000d20e57a693b4b3f08d958" "checksum crypto-mac 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "99376574a55849855052aa6e3b15f3bdebf8bcdd3b24f3cbc3371469bcd5b480" "checksum dbl 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "920e117b69060a961c4164ccf83af573292cb167ccdd918950bcf0f5afc32c1c" +"checksum digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603" "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" diff --git a/lockchain-core/src/record.rs b/lockchain-core/src/record.rs index d103b74..38bde97 100644 --- a/lockchain-core/src/record.rs +++ b/lockchain-core/src/record.rs @@ -96,7 +96,7 @@ impl<T: Body> Record<T> { #[derive(Serialize, Deserialize)] pub struct EncryptedBody { - pub ciph: String, + pub data: String, } impl Body for EncryptedBody { diff --git a/lockchain-core/src/traits.rs b/lockchain-core/src/traits.rs index 8b97745..122a7f4 100644 --- a/lockchain-core/src/traits.rs +++ b/lockchain-core/src/traits.rs @@ -62,7 +62,7 @@ where T: Encryptable + AutoEncoder + Body, { fn encrypt(&mut self, item: T) -> EncryptedBody; - fn decrypt(&mut self, item: EncryptedBody) -> T; + fn decrypt(&mut self, item: EncryptedBody) -> Option<T>; } /// A trait that abstracts file or record loading for diff --git a/lockchain-crypto/Cargo.toml b/lockchain-crypto/Cargo.toml index b028bd1..d21c4ca 100644 --- a/lockchain-crypto/Cargo.toml +++ b/lockchain-crypto/Cargo.toml @@ -8,5 +8,7 @@ lockchain-core = { path = "../lockchain-core" } serde_derive = "1.0" serde = "1.0" -# Cryptography -miscreant = "^0.3" +miscreant = "0.3" +base64 = "0.8" +rand = "*" +blake2 = "*"
\ No newline at end of file diff --git a/lockchain-crypto/src/data.rs b/lockchain-crypto/src/data.rs new file mode 100644 index 0000000..74698e4 --- /dev/null +++ b/lockchain-crypto/src/data.rs @@ -0,0 +1,13 @@ +//! A simple data layout + +use lcc::traits::AutoEncoder; + +/// Represents some packed data – includes nonce and blob +#[derive(Serialize, Deserialize)] +pub struct PackedData { + pub nonce: Vec<u8>, + pub iv: Vec<u8>, + pub data: Vec<u8>, +} + +impl AutoEncoder for PackedData {}
\ No newline at end of file diff --git a/lockchain-crypto/src/databody.rs b/lockchain-crypto/src/databody.rs index 1387f9d..aaedce7 100644 --- a/lockchain-crypto/src/databody.rs +++ b/lockchain-crypto/src/databody.rs @@ -9,6 +9,14 @@ pub struct DataBody { tree: BTreeMap<String, Payload>, } +impl DataBody { + pub fn new() -> Self { + DataBody { + tree: BTreeMap::new(), + } + } +} + impl AutoEncoder for DataBody {} impl Body for DataBody { diff --git a/lockchain-crypto/src/engine.rs b/lockchain-crypto/src/engine.rs index 1030bf2..388f4cc 100644 --- a/lockchain-crypto/src/engine.rs +++ b/lockchain-crypto/src/engine.rs @@ -1,19 +1,69 @@ //! -use databody::DataBody; -use lcc::{traits::{Encryptable, EncryptionHandler}, +use lcc::{traits::{AutoEncoder, Encryptable, EncryptionHandler}, EncryptedBody}; +use miscreant::aead::{Aes256Siv, Algorithm}; + +use super::data::PackedData; +use super::databody::DataBody; +use super::{keys::{Key, KEY_LENGTH}, + utils::random}; + +use std::collections::BTreeMap; impl Encryptable for DataBody {} -pub struct AesEngine {} +pub struct AesEngine { + ctx: Aes256Siv, + key: Key, + iv: Vec<u8>, +} + +impl AesEngine { + /// Generate new key and encryption engine + pub fn generate() -> Self { + let key = Key::generate(); + Self { + ctx: Aes256Siv::new(&key.to_slice()), + key, + iv: random::bytes(KEY_LENGTH), + } + } + + pub fn from_pw(pw: &str, salt: &str) -> Self { + let key = Key::from_password(pw, salt); + Self { + ctx: Aes256Siv::new(&key.to_slice()), + key, + iv: random::bytes(KEY_LENGTH), + } + } +} impl EncryptionHandler<DataBody> for AesEngine { fn encrypt(&mut self, item: DataBody) -> EncryptedBody { - unimplemented!() + let ser = item.encode(); + let nonce = random::bytes(64); + let iv = &self.iv.as_slice(); + let data = &ser.as_bytes(); + + let encrypted = self.ctx.seal(nonce.as_slice(), iv, data); + let data = PackedData { + iv: self.iv.clone(), + data: encrypted, + nonce: nonce, + }.encode(); + + EncryptedBody { data } } - fn decrypt(&mut self, item: EncryptedBody) -> DataBody { - unimplemented!() + fn decrypt(&mut self, item: EncryptedBody) -> Option<DataBody> { + let packed = PackedData::decode(&item.data); + let iv = &self.iv.as_slice(); + let decrypted = self.ctx + .open(packed.nonce.as_slice(), iv, packed.data.as_slice()) + .ok()?; + + Some(DataBody::decode(&String::from_utf8(decrypted).ok()?)) } } diff --git a/lockchain-crypto/src/keys.rs b/lockchain-crypto/src/keys.rs new file mode 100644 index 0000000..bde3e69 --- /dev/null +++ b/lockchain-crypto/src/keys.rs @@ -0,0 +1,37 @@ +//! A module that handles key generation and key loading + +use super::utils::{hashing, random}; +pub const KEY_LENGTH: usize = 64; + + +/// A wrapper to represent a key for encryption +#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)] +pub struct Key { + pub data: Vec<u8>, +} + +impl Key { + + /// Create a new key from scratch + pub fn generate() -> Key { + let data = random::bytes(KEY_LENGTH); + return Key { data: data }; + } + + /// Use a password as a key + pub fn from_password(password: &str, salt: &str) -> Key { + let hashed = hashing::blake2(password, salt); + let mut vec: Vec<u8> = Vec::new(); + for b in &hashed { + vec.push(b.clone()); + } + return Key { data: vec }; + } + + /// Used to get the raw data from this key, as a slice copy + pub fn to_slice(&self) -> [u8; KEY_LENGTH] { + let mut slice: [u8; KEY_LENGTH] = [0; KEY_LENGTH]; + slice.clone_from_slice(&self.data); + return slice; + } +} diff --git a/lockchain-crypto/src/lib.rs b/lockchain-crypto/src/lib.rs index 0799c96..5daba02 100644 --- a/lockchain-crypto/src/lib.rs +++ b/lockchain-crypto/src/lib.rs @@ -1,17 +1,25 @@ -//! +//! A shim-layer crate for lockchain encryption +//! +//! To get going with encrypted lockchain files, just initialise an +//! AesEngine type and start working with encrypted types provided by +//! some backend. #[macro_use] extern crate serde_derive; extern crate serde; +extern crate miscreant; +extern crate base64; +extern crate blake2; +extern crate rand; extern crate lockchain_core as lcc; -use lcc::{traits::{AutoEncoder, Body}, - Payload}; -use std::collections::BTreeMap; mod databody; mod engine; +mod keys; +mod utils; +mod data; pub use databody::*; -pub use engine::*; +pub use engine::AesEngine; diff --git a/src/security/utils.rs b/lockchain-crypto/src/utils.rs index 36e611c..36e611c 100644 --- a/src/security/utils.rs +++ b/lockchain-crypto/src/utils.rs |