mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-10-27 19:38:48 -04:00
bring in Salt, Key and EncryptedKey type aliases
This commit is contained in:
9 files changed
+56
-61
No files matched your search
@@ -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],
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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?;
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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<>`
|
||||
///
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user