askar_storage/protect/kdf/
argon2.rs

1use askar_crypto::kdf::KeyDerivation;
2
3use crate::{
4    crypto::{
5        buffer::ArrayKey,
6        kdf::argon2::{Argon2, Params, PARAMS_INTERACTIVE, PARAMS_MODERATE},
7        repr::{KeyMeta, KeySecretBytes},
8    },
9    error::Error,
10    protect::store_key::{StoreKey, StoreKeyType},
11};
12
13pub use crate::crypto::kdf::argon2::SaltSize;
14
15pub const LEVEL_INTERACTIVE: &str = "13:int";
16pub const LEVEL_MODERATE: &str = "13:mod";
17
18/// Argon2i derivation methods
19#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
20pub enum Level {
21    /// Interactive method
22    Interactive,
23    /// Stronger Moderate method
24    Moderate,
25}
26
27impl Default for Level {
28    fn default() -> Self {
29        Self::Moderate
30    }
31}
32
33impl Level {
34    pub(crate) fn from_str(level: &str) -> Option<Self> {
35        match level {
36            "int" | LEVEL_INTERACTIVE => Some(Self::Interactive),
37            "mod" | LEVEL_MODERATE => Some(Self::Moderate),
38            "" => Some(Self::default()),
39            _ => None,
40        }
41    }
42
43    pub(crate) fn as_str(&self) -> &'static str {
44        match self {
45            Self::Interactive => LEVEL_INTERACTIVE,
46            Self::Moderate => LEVEL_MODERATE,
47        }
48    }
49
50    pub(crate) fn generate_salt(&self) -> ArrayKey<SaltSize> {
51        ArrayKey::random()
52    }
53
54    fn params(&self) -> &Params {
55        match self {
56            Self::Interactive => &PARAMS_INTERACTIVE,
57            Self::Moderate => &PARAMS_MODERATE,
58        }
59    }
60
61    pub(crate) fn derive_key(&self, password: &[u8], salt: &[u8]) -> Result<StoreKey, Error> {
62        ArrayKey::<<StoreKeyType as KeyMeta>::KeySize>::temp(|key| {
63            Argon2::new(password, salt, *self.params())?.derive_key_bytes(key)?;
64            Ok(StoreKey::from(StoreKeyType::from_secret_bytes(&*key)?))
65        })
66    }
67}