diff --git a/matrix_sdk_crypto/Cargo.toml b/matrix_sdk_crypto/Cargo.toml index 495cfb6b..3ee88c84 100644 --- a/matrix_sdk_crypto/Cargo.toml +++ b/matrix_sdk_crypto/Cargo.toml @@ -25,7 +25,8 @@ async-trait = "0.1.40" matrix-sdk-common-macros = { version = "0.1.0", path = "../matrix_sdk_common_macros" } matrix-sdk-common = { version = "0.1.0", path = "../matrix_sdk_common" } -olm-rs = { git = 'https://gitlab.gnome.org/jhaye/olm-rs/', features = ["serde"]} +olm-rs = { version = "0.6.0", features = ["serde"] } +getrandom = "0.1.14" serde = { version = "1.0.115", features = ["derive", "rc"] } serde_json = "1.0.57" cjson = "0.1.1" diff --git a/matrix_sdk_crypto/src/key_export.rs b/matrix_sdk_crypto/src/key_export.rs index 5d6fc057..d4b4045a 100644 --- a/matrix_sdk_crypto/src/key_export.rs +++ b/matrix_sdk_crypto/src/key_export.rs @@ -16,6 +16,7 @@ use std::io::{Cursor, Read, Seek, SeekFrom}; use base64::{decode_config, encode_config, DecodeError, STANDARD_NO_PAD}; use byteorder::{BigEndian, ReadBytesExt}; +use getrandom::getrandom; use aes_ctr::{ stream_cipher::{NewStreamCipher, SyncStreamCipher}, @@ -38,6 +39,42 @@ pub fn encode(input: impl AsRef<[u8]>) -> String { encode_config(input, STANDARD_NO_PAD) } +pub fn encrypt(mut plaintext: &mut [u8], passphrase: &str, rounds: u32) -> String { + let mut salt = [0u8; SALT_SIZE]; + let mut iv = [0u8; IV_SIZE]; + let mut derived_keys = [0u8; KEY_SIZE * 2]; + let version: u8 = 1; + + getrandom(&mut salt).expect("Can't generate randomness"); + getrandom(&mut iv).expect("Can't generate randomness"); + + let mut iv = u128::from_be_bytes(iv); + iv &= !(1 << 63); + + pbkdf2::>(passphrase.as_bytes(), &salt, rounds, &mut derived_keys); + let (key, hmac_key) = derived_keys.split_at(KEY_SIZE); + + let mut aes = Aes256Ctr::new_var(&key, &iv.to_be_bytes()).expect("Can't create AES"); + + aes.apply_keystream(&mut plaintext); + + let mut payload: Vec = vec![]; + + payload.extend(&version.to_be_bytes()); + payload.extend(&salt); + payload.extend(&iv.to_be_bytes()); + payload.extend(&rounds.to_be_bytes()); + payload.extend_from_slice(&plaintext); + + let mut hmac = Hmac::::new_varkey(hmac_key).unwrap(); + hmac.update(&payload); + let mac = hmac.finalize(); + + payload.extend(mac.into_bytes()); + + encode(payload) +} + pub fn decrypt(ciphertext: &str, passphrase: &str) -> Result { let decoded = decode(ciphertext)?; @@ -84,7 +121,7 @@ pub fn decrypt(ciphertext: &str, passphrase: &str) -> Result