bc_components/encrypted_key/
key_derivation_method.rs

1use bc_ur::prelude::*;
2
3use crate::{Error, Result};
4
5/// Enum representing the supported key derivation methods.
6///
7/// CDDL:
8/// ```cddl
9/// KeyDerivationMethod = HKDF / PBKDF2 / Scrypt / Argon2id
10/// HKDF = 0
11/// PBKDF2 = 1
12/// Scrypt = 2
13/// Argon2id = 3
14/// ```
15#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
16pub enum KeyDerivationMethod {
17    HKDF     = 0,
18    PBKDF2   = 1,
19    Scrypt   = 2,
20    #[default]
21    Argon2id = 3,
22    #[cfg(feature = "ssh-agent")]
23    SSHAgent = 4,
24}
25
26impl KeyDerivationMethod {
27    /// Returns the zero-based index of the key derivation method.
28    pub fn index(&self) -> usize { *self as usize }
29
30    /// Attempts to create a `KeyDerivationMethod` from a zero-based index.
31    pub fn from_index(index: usize) -> Option<Self> {
32        match index {
33            0 => Some(KeyDerivationMethod::HKDF),
34            1 => Some(KeyDerivationMethod::PBKDF2),
35            2 => Some(KeyDerivationMethod::Scrypt),
36            3 => Some(KeyDerivationMethod::Argon2id),
37            #[cfg(feature = "ssh-agent")]
38            4 => Some(KeyDerivationMethod::SSHAgent),
39            _ => None,
40        }
41    }
42}
43
44impl std::fmt::Display for KeyDerivationMethod {
45    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46        match self {
47            KeyDerivationMethod::HKDF => write!(f, "HKDF"),
48            KeyDerivationMethod::PBKDF2 => write!(f, "PBKDF2"),
49            KeyDerivationMethod::Scrypt => write!(f, "Scrypt"),
50            KeyDerivationMethod::Argon2id => write!(f, "Argon2id"),
51            #[cfg(feature = "ssh-agent")]
52            KeyDerivationMethod::SSHAgent => write!(f, "SSHAgent"),
53        }
54    }
55}
56
57impl TryFrom<&CBOR> for KeyDerivationMethod {
58    type Error = Error;
59
60    fn try_from(cbor: &CBOR) -> Result<Self> {
61        let i: usize = cbor.clone().try_into()?;
62        KeyDerivationMethod::from_index(i)
63            .ok_or_else(|| Error::general("Invalid KeyDerivationMethod"))
64    }
65}