1use bouncycastle_hkdf as hkdf;
51use bouncycastle_sha3 as sha3;
52use bouncycastle_core_interface::errors::KDFError;
53use bouncycastle_core_interface::traits::{KeyMaterial, SecurityStrength, KDF};
54use bouncycastle_sha3::{SHA3_224_NAME, SHA3_256_NAME, SHA3_384_NAME, SHA3_512_NAME, SHAKE128_NAME, SHAKE256_NAME};
55use bouncycastle_hkdf::{HKDF_SHA256_NAME, HKDF_SHA512_NAME};
56use crate::{AlgorithmFactory, FactoryError, DEFAULT, DEFAULT_128_BIT, DEFAULT_256_BIT};
57
58
59pub const DEFAULT_KDF_NAME: &str = HKDF_SHA512_NAME;
61pub const DEFAULT_128BIT_KDF_NAME: &str = HKDF_SHA256_NAME;
62pub const DEFAULT_256BIT_KDF_NAME: &str = HKDF_SHA512_NAME;
63
64pub enum KDFFactory {
66 #[allow(non_camel_case_types)]
67 HKDF_SHA256(hkdf::HKDF_SHA256),
68 #[allow(non_camel_case_types)]
69 HKDF_SHA512(hkdf::HKDF_SHA512),
70 SHA3_224(sha3::SHA3_224),
71 SHA3_256(sha3::SHA3_256),
72 SHA3_384(sha3::SHA3_384),
73 SHA3_512(sha3::SHA3_512),
74 SHAKE128(sha3::SHAKE128),
75 SHAKE256(sha3::SHAKE256),
76}
77
78impl Default for KDFFactory {
79 fn default() -> Self {
80 KDFFactory::new(DEFAULT_KDF_NAME).unwrap()
81 }
82}
83
84impl AlgorithmFactory for KDFFactory {
85 fn default_128_bit() -> Self {
86 KDFFactory::new(DEFAULT_128BIT_KDF_NAME).unwrap()
87 }
88
89 fn default_256_bit() -> Self {
90 KDFFactory::new(DEFAULT_256BIT_KDF_NAME).unwrap()
91 }
92
93 fn new(alg_name: &str) -> Result<Self, FactoryError> {
94 match alg_name {
95 DEFAULT => Ok(KDFFactory::default()),
96 DEFAULT_128_BIT => Ok(KDFFactory::default_128_bit()),
97 DEFAULT_256_BIT => Ok(KDFFactory::default_256_bit()),
98 HKDF_SHA256_NAME => Ok(Self::HKDF_SHA256(hkdf::HKDF_SHA256::new())),
99 HKDF_SHA512_NAME => Ok(Self::HKDF_SHA512(hkdf::HKDF_SHA512::new())),
100 SHA3_224_NAME => Ok(Self::SHA3_224(sha3::SHA3_224::new())),
101 SHA3_256_NAME => Ok(Self::SHA3_256(sha3::SHA3_256::new())),
102 SHA3_384_NAME => Ok(Self::SHA3_384(sha3::SHA3_384::new())),
103 SHA3_512_NAME => Ok(Self::SHA3_512(sha3::SHA3_512::new())),
104 SHAKE128_NAME => Ok(Self::SHAKE128(sha3::SHAKE128::new())),
105 SHAKE256_NAME => Ok(Self::SHAKE256(sha3::SHAKE256::new())),
106 _ => Err(FactoryError::UnsupportedAlgorithm(format!("The algorithm: \"{}\" is not a known KDF", alg_name))),
107 }
108 }
109}
110
111impl KDF for KDFFactory {
112 fn derive_key(self, key: &impl KeyMaterial, additional_input: &[u8]) -> Result<Box<dyn KeyMaterial>, KDFError> {
113 match self {
114 Self::HKDF_SHA256(h) => h.derive_key(key, additional_input),
115 Self::HKDF_SHA512(h) => h.derive_key(key, additional_input),
116 Self::SHA3_224(h) => h.derive_key(key, additional_input),
117 Self::SHA3_256(h) => h.derive_key(key, additional_input),
118 Self::SHA3_384(h) => h.derive_key(key, additional_input),
119 Self::SHA3_512(h) => h.derive_key(key, additional_input),
120 Self::SHAKE128(h) => h.derive_key(key, additional_input),
121 Self::SHAKE256(h) => h.derive_key(key, additional_input),
122 }
123 }
124
125 fn derive_key_out(self, key: &impl KeyMaterial, additional_input: &[u8], output_key: &mut impl KeyMaterial) -> Result<usize, KDFError> {
126 match self {
127 Self::HKDF_SHA256(h) => h.derive_key_out(key, additional_input, output_key),
128 Self::HKDF_SHA512(h) => h.derive_key_out(key, additional_input, output_key),
129 Self::SHA3_224(h) => h.derive_key_out(key, additional_input, output_key),
130 Self::SHA3_256(h) => h.derive_key_out(key, additional_input, output_key),
131 Self::SHA3_384(h) => h.derive_key_out(key, additional_input, output_key),
132 Self::SHA3_512(h) => h.derive_key_out(key, additional_input, output_key),
133 Self::SHAKE128(h) => h.derive_key_out(key, additional_input, output_key),
134 Self::SHAKE256(h) => h.derive_key_out(key, additional_input, output_key),
135 }
136 }
137
138 fn derive_key_from_multiple(self, keys: &[&impl KeyMaterial], additional_input: &[u8]) -> Result<Box<dyn KeyMaterial>, KDFError> {
139 match self {
140 Self::HKDF_SHA256(h) => h.derive_key_from_multiple(keys, additional_input),
141 Self::HKDF_SHA512(h) => h.derive_key_from_multiple(keys, additional_input),
142 Self::SHA3_224(h) => h.derive_key_from_multiple(keys, additional_input),
143 Self::SHA3_256(h) => h.derive_key_from_multiple(keys, additional_input),
144 Self::SHA3_384(h) => h.derive_key_from_multiple(keys, additional_input),
145 Self::SHA3_512(h) => h.derive_key_from_multiple(keys, additional_input),
146 Self::SHAKE128(h) => h.derive_key_from_multiple(keys, additional_input),
147 Self::SHAKE256(h) => h.derive_key_from_multiple(keys, additional_input),
148 }
149 }
150
151 fn derive_key_from_multiple_out(self, keys: &[&impl KeyMaterial], additional_input: &[u8], output_key: &mut impl KeyMaterial) -> Result<usize, KDFError> {
152 match self {
153 Self::HKDF_SHA256(h) => h.derive_key_from_multiple_out(keys, additional_input, output_key),
154 Self::HKDF_SHA512(h) => h.derive_key_from_multiple_out(keys, additional_input, output_key),
155 Self::SHA3_224(h) => h.derive_key_from_multiple_out(keys, additional_input, output_key),
156 Self::SHA3_256(h) => h.derive_key_from_multiple_out(keys, additional_input, output_key),
157 Self::SHA3_384(h) => h.derive_key_from_multiple_out(keys, additional_input, output_key),
158 Self::SHA3_512(h) => h.derive_key_from_multiple_out(keys, additional_input, output_key),
159 Self::SHAKE128(h) => h.derive_key_from_multiple_out(keys, additional_input, output_key),
160 Self::SHAKE256(h) => h.derive_key_from_multiple_out(keys, additional_input, output_key),
161 }
162 }
163
164 fn max_security_strength(&self) -> SecurityStrength {
165 match self {
166 Self::HKDF_SHA256(h) => h.max_security_strength(),
167 Self::HKDF_SHA512(h) => h.max_security_strength(),
168 Self::SHA3_224(h) => h.max_security_strength(),
169 Self::SHA3_256(h) => h.max_security_strength(),
170 Self::SHA3_384(h) => h.max_security_strength(),
171 Self::SHA3_512(h) => h.max_security_strength(),
172 Self::SHAKE128(h) => h.max_security_strength(),
173 Self::SHAKE256(h) => h.max_security_strength(),
174 }
175 }
176}