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