bc_components/encrypted_key/
key_derivation_params.rs1use dcbor::prelude::*;
2
3use super::{
4 Argon2idParams, HKDFParams, KeyDerivation, KeyDerivationMethod,
5 PBKDF2Params, SSHAgentParams, ScryptParams,
6};
7use crate::{EncryptedMessage, Result, SymmetricKey};
8
9#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum KeyDerivationParams {
12 HKDF(HKDFParams),
13 PBKDF2(PBKDF2Params),
14 Scrypt(ScryptParams),
15 Argon2id(Argon2idParams),
16 SSHAgent(SSHAgentParams),
17}
18
19impl KeyDerivationParams {
20 pub fn method(&self) -> KeyDerivationMethod {
22 match self {
23 KeyDerivationParams::HKDF(_) => KeyDerivationMethod::HKDF,
24 KeyDerivationParams::PBKDF2(_) => KeyDerivationMethod::PBKDF2,
25 KeyDerivationParams::Scrypt(_) => KeyDerivationMethod::Scrypt,
26 KeyDerivationParams::Argon2id(_) => KeyDerivationMethod::Argon2id,
27 KeyDerivationParams::SSHAgent(_) => KeyDerivationMethod::SSHAgent,
28 }
29 }
30
31 pub fn is_password_based(&self) -> bool {
32 matches!(
33 self,
34 KeyDerivationParams::PBKDF2(_)
35 | KeyDerivationParams::Scrypt(_)
36 | KeyDerivationParams::Argon2id(_)
37 )
38 }
39
40 pub fn is_ssh_agent(&self) -> bool {
41 matches!(self, KeyDerivationParams::SSHAgent(_))
42 }
43
44 pub fn lock(
45 &mut self,
46 content_key: &SymmetricKey,
47 secret: impl AsRef<[u8]>,
48 ) -> Result<EncryptedMessage> {
49 match self {
50 KeyDerivationParams::HKDF(params) => {
51 params.lock(content_key, secret)
52 }
53 KeyDerivationParams::PBKDF2(params) => {
54 params.lock(content_key, secret)
55 }
56 KeyDerivationParams::Scrypt(params) => {
57 params.lock(content_key, secret)
58 }
59 KeyDerivationParams::Argon2id(params) => {
60 params.lock(content_key, secret)
61 }
62 KeyDerivationParams::SSHAgent(params) => {
63 params.lock(content_key, secret)
64 }
65 }
66 }
67}
68
69impl std::fmt::Display for KeyDerivationParams {
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 match self {
72 KeyDerivationParams::HKDF(params) => write!(f, "{}", params),
73 KeyDerivationParams::PBKDF2(params) => write!(f, "{}", params),
74 KeyDerivationParams::Scrypt(params) => write!(f, "{}", params),
75 KeyDerivationParams::Argon2id(params) => write!(f, "{}", params),
76 KeyDerivationParams::SSHAgent(params) => write!(f, "{}", params),
77 }
78 }
79}
80
81impl From<KeyDerivationParams> for CBOR {
82 fn from(value: KeyDerivationParams) -> Self {
83 match value {
84 KeyDerivationParams::HKDF(params) => params.into(),
85 KeyDerivationParams::PBKDF2(params) => params.into(),
86 KeyDerivationParams::Scrypt(params) => params.into(),
87 KeyDerivationParams::Argon2id(params) => params.into(),
88 KeyDerivationParams::SSHAgent(params) => params.into(),
89 }
90 }
91}
92
93impl TryFrom<CBOR> for KeyDerivationParams {
94 type Error = dcbor::Error;
95
96 fn try_from(cbor: CBOR) -> dcbor::Result<Self> {
97 let a = cbor.clone().try_into_array()?;
98 let mut iter = a.into_iter();
99 let index: usize = iter
100 .next()
101 .ok_or_else(|| dcbor::Error::msg("Missing index"))?
102 .try_into()?;
103 match KeyDerivationMethod::from_index(index) {
104 Some(KeyDerivationMethod::HKDF) => {
105 Ok(KeyDerivationParams::HKDF(HKDFParams::try_from(cbor)?))
106 }
107 Some(KeyDerivationMethod::PBKDF2) => {
108 Ok(KeyDerivationParams::PBKDF2(PBKDF2Params::try_from(cbor)?))
109 }
110 Some(KeyDerivationMethod::Scrypt) => {
111 Ok(KeyDerivationParams::Scrypt(ScryptParams::try_from(cbor)?))
112 }
113 Some(KeyDerivationMethod::Argon2id) => Ok(
114 KeyDerivationParams::Argon2id(Argon2idParams::try_from(cbor)?),
115 ),
116 Some(KeyDerivationMethod::SSHAgent) => Ok(
117 KeyDerivationParams::SSHAgent(SSHAgentParams::try_from(cbor)?),
118 ),
119 None => Err(dcbor::Error::msg("Invalid KeyDerivationMethod")),
120 }
121 }
122}