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