bring in Salt, Key and EncryptedKey type aliases

This commit is contained in:
brxken128 committed 2023-01-24 17:01:50 +00:00
1 parent 546bf643b2
commit c75e983fd4
9 files changed
+56 -61

No files matched your search

+5 -5
View File
@@ -4,7 +4,7 @@
use std::io::Cursor;
use crate::{
primitives::{AEAD_TAG_SIZE, BLOCK_SIZE, KEY_LEN},
primitives::{Key, AEAD_TAG_SIZE, BLOCK_SIZE},
protected::ProtectedVec,
Error, Protected, Result,
};
@@ -55,7 +55,7 @@ impl StreamEncryption {
///
/// The master key, a suitable nonce, and a specific algorithm should be provided.
#[allow(clippy::needless_pass_by_value)]
pub fn new(key: Protected<[u8; KEY_LEN]>, nonce: &[u8], algorithm: Algorithm) -> Result<Self> {
pub fn new(key: Protected<Key>, nonce: &[u8], algorithm: Algorithm) -> Result<Self> {
if nonce.len() != algorithm.nonce_len() {
return Err(Error::NonceLengthMismatch);
}
@@ -153,7 +153,7 @@ impl StreamEncryption {
/// It is just a thin wrapper around `encrypt_streams()`, but reduces the amount of code needed elsewhere.
#[allow(unused_mut)]
pub async fn encrypt_bytes(
key: Protected<[u8; KEY_LEN]>,
key: Protected<Key>,
nonce: &[u8],
algorithm: Algorithm,
bytes: &[u8],
@@ -174,7 +174,7 @@ impl StreamDecryption {
///
/// The master key, nonce and algorithm that were used for encryption should be provided.
#[allow(clippy::needless_pass_by_value)]
pub fn new(key: Protected<[u8; KEY_LEN]>, nonce: &[u8], algorithm: Algorithm) -> Result<Self> {
pub fn new(key: Protected<Key>, nonce: &[u8], algorithm: Algorithm) -> Result<Self> {
if nonce.len() != algorithm.nonce_len() {
return Err(Error::NonceLengthMismatch);
}
@@ -272,7 +272,7 @@ impl StreamDecryption {
/// It is just a thin wrapper around `decrypt_streams()`, but reduces the amount of code needed elsewhere.
#[allow(unused_mut)]
pub async fn decrypt_bytes(
key: Protected<[u8; KEY_LEN]>,
key: Protected<Key>,
nonce: &[u8],
algorithm: Algorithm,
bytes: &[u8],
+4 -7
View File
@@ -35,7 +35,7 @@ use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt};
use crate::{
crypto::stream::Algorithm,
primitives::{generate_nonce, to_array, KEY_LEN},
primitives::{generate_nonce, to_array, Key, KEY_LEN},
protected::ProtectedVec,
Error, Protected, Result,
};
@@ -101,10 +101,7 @@ impl FileHeader {
///
/// You receive an error if the password doesn't match or if there are no keyslots.
#[allow(clippy::needless_pass_by_value)]
pub async fn decrypt_master_key(
&self,
password: ProtectedVec<u8>,
) -> Result<Protected<[u8; KEY_LEN]>> {
pub async fn decrypt_master_key(&self, password: ProtectedVec<u8>) -> Result<Protected<Key>> {
if self.keyslots.is_empty() {
return Err(Error::NoKeyslots);
}
@@ -140,8 +137,8 @@ impl FileHeader {
#[allow(clippy::needless_pass_by_value)]
pub async fn decrypt_master_key_from_prehashed(
&self,
hashed_keys: Vec<Protected<[u8; KEY_LEN]>>,
) -> Result<Protected<[u8; KEY_LEN]>> {
hashed_keys: Vec<Protected<Key>>,
) -> Result<Protected<Key>> {
if self.keyslots.is_empty() {
return Err(Error::NoKeyslots);
}
+9 -9
View File
@@ -27,8 +27,8 @@ use crate::{
crypto::stream::{Algorithm, StreamDecryption, StreamEncryption},
keys::hashing::HashingAlgorithm,
primitives::{
derive_key, generate_nonce, generate_salt, to_array, ENCRYPTED_KEY_LEN, FILE_KEY_CONTEXT,
KEY_LEN, SALT_LEN,
derive_key, generate_nonce, generate_salt, to_array, EncryptedKey, Key, Salt,
ENCRYPTED_KEY_LEN, FILE_KEY_CONTEXT, SALT_LEN,
},
protected::ProtectedVec,
Error, Protected, Result,
@@ -42,9 +42,9 @@ pub struct Keyslot {
pub version: KeyslotVersion,
pub algorithm: Algorithm, // encryption algorithm
pub hashing_algorithm: HashingAlgorithm, // password hashing algorithm
pub salt: [u8; SALT_LEN], // the salt used for deriving a KEK from a (key/content salt) hash
pub content_salt: [u8; SALT_LEN],
pub master_key: [u8; ENCRYPTED_KEY_LEN], // this is encrypted so we can store it
pub salt: Salt, // the salt used for deriving a KEK from a (key/content salt) hash
pub content_salt: Salt,
pub master_key: EncryptedKey, // this is encrypted so we can store it
pub nonce: Vec<u8>,
}
@@ -69,9 +69,9 @@ impl Keyslot {
version: KeyslotVersion,
algorithm: Algorithm,
hashing_algorithm: HashingAlgorithm,
content_salt: [u8; SALT_LEN],
hashed_key: Protected<[u8; KEY_LEN]>,
master_key: Protected<[u8; KEY_LEN]>,
content_salt: Salt,
hashed_key: Protected<Key>,
master_key: Protected<Key>,
) -> Result<Self> {
let nonce = generate_nonce(algorithm);
@@ -130,7 +130,7 @@ impl Keyslot {
/// An error will be returned on failure.
pub async fn decrypt_master_key_from_prehashed(
&self,
key: Protected<[u8; KEY_LEN]>,
key: Protected<Key>,
) -> Result<ProtectedVec<u8>> {
StreamDecryption::decrypt_bytes(
derive_key(key, self.salt, FILE_KEY_CONTEXT),
+6 -3
View File
@@ -30,10 +30,13 @@
#[cfg(feature = "serde")]
use crate::protected::ProtectedVec;
#[cfg(feature = "serde")]
use crate::primitives::Key;
#[cfg(feature = "serde")]
use crate::{
crypto::stream::{StreamDecryption, StreamEncryption},
primitives::{generate_nonce, KEY_LEN},
primitives::generate_nonce,
Protected,
};
@@ -75,7 +78,7 @@ impl FileHeader {
&mut self,
version: MetadataVersion,
algorithm: Algorithm,
master_key: Protected<[u8; KEY_LEN]>,
master_key: Protected<Key>,
metadata: &T,
) -> Result<()>
where
@@ -110,7 +113,7 @@ impl FileHeader {
#[cfg(feature = "serde")]
pub async fn decrypt_metadata_from_prehashed<T>(
&self,
hashed_keys: Vec<Protected<[u8; KEY_LEN]>>,
hashed_keys: Vec<Protected<Key>>,
) -> Result<T>
where
T: serde::de::DeserializeOwned,
+3 -3
View File
@@ -24,7 +24,7 @@ use tokio::io::AsyncReadExt;
use crate::{
crypto::stream::{Algorithm, StreamDecryption, StreamEncryption},
primitives::{generate_nonce, KEY_LEN},
primitives::{generate_nonce, Key},
protected::ProtectedVec,
Error, Protected, Result,
};
@@ -62,7 +62,7 @@ impl FileHeader {
&mut self,
version: PreviewMediaVersion,
algorithm: Algorithm,
master_key: Protected<[u8; KEY_LEN]>,
master_key: Protected<Key>,
media: &[u8],
) -> Result<()> {
let media_nonce = generate_nonce(algorithm);
@@ -88,7 +88,7 @@ impl FileHeader {
/// Once provided, a `Vec<u8>` is returned that contains the preview media
pub async fn decrypt_preview_media_from_prehashed(
&self,
hashed_keys: Vec<Protected<[u8; KEY_LEN]>>,
hashed_keys: Vec<Protected<Key>>,
) -> Result<ProtectedVec<u8>> {
let master_key = self.decrypt_master_key_from_prehashed(hashed_keys).await?;
+8 -8
View File
@@ -11,10 +11,10 @@
//! let hashed_password = hashing_algorithm.hash(password, salt).unwrap();
//! ```
use crate::primitives::KEY_LEN;
use crate::primitives::{Key, Salt, KEY_LEN};
use crate::protected::ProtectedVec;
use crate::Protected;
use crate::{primitives::SALT_LEN, Error, Result};
use crate::{Error, Result};
use argon2::Argon2;
use balloon_hash::Balloon;
@@ -54,9 +54,9 @@ impl HashingAlgorithm {
pub fn hash(
&self,
password: ProtectedVec<u8>,
salt: [u8; SALT_LEN],
salt: Salt,
secret: Option<ProtectedVec<u8>>,
) -> Result<Protected<[u8; KEY_LEN]>> {
) -> Result<Protected<Key>> {
match self {
Self::Argon2id(params) => PasswordHasher::argon2id(password, salt, secret, *params),
Self::BalloonBlake3(params) => {
@@ -108,10 +108,10 @@ impl PasswordHasher {
#[allow(clippy::needless_pass_by_value)]
fn argon2id(
password: ProtectedVec<u8>,
salt: [u8; SALT_LEN],
salt: Salt,
secret: Option<ProtectedVec<u8>>,
params: Params,
) -> Result<Protected<[u8; KEY_LEN]>> {
) -> Result<Protected<Key>> {
let secret = secret.map_or(Protected::new(vec![]), |k| k);
let mut key = [0u8; KEY_LEN];
@@ -131,10 +131,10 @@ impl PasswordHasher {
#[allow(clippy::needless_pass_by_value)]
fn balloon_blake3(
password: ProtectedVec<u8>,
salt: [u8; SALT_LEN],
salt: Salt,
secret: Option<ProtectedVec<u8>>,
params: Params,
) -> Result<Protected<[u8; KEY_LEN]>> {
) -> Result<Protected<Key>> {
let secret = secret.map_or(Protected::new(vec![]), |k| k);
let mut key = [0u8; KEY_LEN];
+13 -17
View File
@@ -39,15 +39,11 @@ use std::sync::Mutex;
use crate::crypto::stream::{StreamDecryption, StreamEncryption};
use crate::primitives::{
derive_key, generate_master_key, generate_nonce, generate_salt, to_array, OnboardingConfig,
KEY_LEN, LATEST_STORED_KEY, MASTER_PASSWORD_CONTEXT, ROOT_KEY_CONTEXT,
derive_key, generate_master_key, generate_nonce, generate_salt, to_array, EncryptedKey, Key,
OnboardingConfig, Salt, KEY_LEN, LATEST_STORED_KEY, MASTER_PASSWORD_CONTEXT, ROOT_KEY_CONTEXT,
};
use crate::protected::ProtectedVec;
use crate::{
crypto::stream::Algorithm,
primitives::{ENCRYPTED_KEY_LEN, SALT_LEN},
Protected,
};
use crate::{crypto::stream::Algorithm, primitives::ENCRYPTED_KEY_LEN, Protected};
use crate::{Error, Result};
use dashmap::{DashMap, DashSet};
@@ -67,13 +63,13 @@ pub struct StoredKey {
pub version: StoredKeyVersion,
pub algorithm: Algorithm, // encryption algorithm for encrypting the master key. can be changed (requires a re-encryption though)
pub hashing_algorithm: HashingAlgorithm, // hashing algorithm used for hashing the key with the content salt
pub content_salt: [u8; SALT_LEN],
pub content_salt: Salt,
#[cfg_attr(feature = "serde", serde(with = "BigArray"))] // salt used for file data
pub master_key: [u8; ENCRYPTED_KEY_LEN], // this is for encrypting the `key`
pub master_key: EncryptedKey, // this is for encrypting the `key`
pub master_key_nonce: Vec<u8>, // nonce for encrypting the master key
pub key_nonce: Vec<u8>, // nonce used for encrypting the main key
pub key: Vec<u8>, // encrypted. the key stored in spacedrive (e.g. generated 64 char key)
pub salt: [u8; SALT_LEN],
pub salt: Salt,
pub memory_only: bool,
pub automount: bool,
}
@@ -90,8 +86,8 @@ pub enum StoredKeyVersion {
/// This contains the plaintext key, and the same key hashed with the content salt.
#[derive(Clone)]
pub struct MountedKey {
pub uuid: Uuid, // used for identification. shared with stored keys
pub hashed_key: Protected<[u8; KEY_LEN]>, // this is hashed with the content salt, for instant access
pub uuid: Uuid, // used for identification. shared with stored keys
pub hashed_key: Protected<Key>, // this is hashed with the content salt, for instant access
}
/// This is the key manager itself.
@@ -100,7 +96,7 @@ pub struct MountedKey {
///
/// Use the associated functions to interact with it.
pub struct KeyManager {
root_key: Mutex<Option<Protected<[u8; KEY_LEN]>>>, // the root key for the vault
root_key: Mutex<Option<Protected<Key>>>, // the root key for the vault
verification_key: Mutex<Option<StoredKey>>,
keystore: DashMap<Uuid, StoredKey>,
keymount: DashMap<Uuid, MountedKey>,
@@ -651,7 +647,7 @@ impl KeyManager {
hashing_algorithm: HashingAlgorithm,
memory_only: bool,
automount: bool,
content_salt: Option<[u8; SALT_LEN]>,
content_salt: Option<Salt>,
) -> Result<Uuid> {
let uuid = uuid::Uuid::new_v4();
@@ -741,7 +737,7 @@ impl KeyManager {
}
/// This should ONLY be used internally.
fn get_root_key(&self) -> Result<Protected<[u8; KEY_LEN]>> {
fn get_root_key(&self) -> Result<Protected<Key>> {
self.root_key.lock()?.clone().ok_or(Error::NoMasterPassword)
}
@@ -779,11 +775,11 @@ impl KeyManager {
///
/// This means we don't need to keep super specific track of which key goes to which file, and we can just throw all of them at it.
#[must_use]
pub fn enumerate_hashed_keys(&self) -> Vec<Protected<[u8; KEY_LEN]>> {
pub fn enumerate_hashed_keys(&self) -> Vec<Protected<Key>> {
self.keymount
.iter()
.map(|mounted_key| mounted_key.hashed_key.clone())
.collect::<Vec<Protected<[u8; KEY_LEN]>>>()
.collect::<Vec<Protected<Key>>>()
}
/// This function is for converting a memory-only key to a saved key which syncs to the library.
+8 -8
View File
@@ -44,6 +44,10 @@ pub const MASTER_PASSWORD_CONTEXT: &str =
"spacedrive 2022-12-14 15:35:41 master password hash derivation"; // used for deriving keys from the master password hash
pub const FILE_KEY_CONTEXT: &str = "spacedrive 2022-12-14 12:54:12 file key derivation"; // used for deriving keys from user key/content salt hashes (for file encryption)
pub type Key = [u8; KEY_LEN];
pub type EncryptedKey = [u8; ENCRYPTED_KEY_LEN];
pub type Salt = [u8; SALT_LEN];
#[derive(Clone)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[cfg_attr(feature = "rspc", derive(specta::Type))]
@@ -70,7 +74,7 @@ pub fn generate_nonce(algorithm: Algorithm) -> Vec<u8> {
///
/// This function uses `ChaCha20Rng` for generating cryptographically-secure random data
#[must_use]
pub fn generate_salt() -> [u8; SALT_LEN] {
pub fn generate_salt() -> Salt {
let mut salt = [0u8; SALT_LEN];
rand_chacha::ChaCha20Rng::from_entropy().fill_bytes(&mut salt);
salt
@@ -82,7 +86,7 @@ pub fn generate_salt() -> [u8; SALT_LEN] {
///
/// This function uses `ChaCha20Rng` for generating cryptographically-secure random data
#[must_use]
pub fn generate_master_key() -> Protected<[u8; KEY_LEN]> {
pub fn generate_master_key() -> Protected<Key> {
let mut master_key = [0u8; KEY_LEN];
rand_chacha::ChaCha20Rng::from_entropy().fill_bytes(&mut master_key);
Protected::new(master_key)
@@ -90,11 +94,7 @@ pub fn generate_master_key() -> Protected<[u8; KEY_LEN]> {
#[must_use]
#[allow(clippy::needless_pass_by_value)]
pub fn derive_key(
key: Protected<[u8; KEY_LEN]>,
salt: [u8; SALT_LEN],
context: &str,
) -> Protected<[u8; KEY_LEN]> {
pub fn derive_key(key: Protected<Key>, salt: Salt, context: &str) -> Protected<Key> {
let mut input = key.expose().to_vec();
input.extend_from_slice(&salt);
@@ -107,7 +107,7 @@ pub fn derive_key(
/// This is used for converting a `Vec<u8>` to an array of bytes
///
/// It's main usage is for converting an encrypted master key from a `Vec<u8>` to `[u8; ENCRYPTED_KEY_LEN]`
/// It's main usage is for converting an encrypted master key from a `Vec<u8>` to `EncryptedKey`
///
/// As the master key is encrypted at this point, it does not need to be `Protected<>`
///
-1
View File
@@ -32,7 +32,6 @@ use std::{fmt::Debug, mem::swap};
use zeroize::Zeroize;
pub type ProtectedVec<T> = Protected<Vec<T>>;
#[derive(Clone)]
pub struct Protected<T>
where