Skip to main content

bouncycastle_factory/
kdf_factory.rs

1//! KDF factory for creating instances of algorithms that implement the [KDF] trait.
2//!
3//! As with all Factory objects, this implements constructions from strings and defaults, and
4//! returns a [KDFFactory] object which itself implements the [KDF] trait as a pass-through to the underlying algorithm.
5//!
6//! Example usage:
7//! ```
8//! use core_interface::key_material::{KeyMaterial256, KeyType};
9//! use factory::AlgorithmFactory;
10//! use core_interface::traits::KDF;
11//!
12//! // get your key material from a secure place; here we'll use the default RNG, seeded from the OS
13//! let seed_key = KeyMaterial256::from_rng(&mut rng::DefaultRNG::default()).unwrap();
14//! let additional_input: &[u8] = b"some additional input";
15//!
16//! let mut h = factory::kdf_factory::KDFFactory::new(hkdf::HKDF_SHA256_NAME).unwrap();
17//! let new_key = h.derive_key(&seed_key, additional_input).unwrap();
18//! ```
19//!
20//! You can equivalently invoke this by string instead of using the constant:
21//!
22//! ```
23//! use core_interface::key_material::{KeyMaterial256, KeyType};
24//! use factory::AlgorithmFactory;
25//! use core_interface::traits::KDF;
26//!
27//! // get your key material from a secure place; here we'll use the default RNG, seeded from the OS
28//! let seed_key = KeyMaterial256::from_rng(&mut rng::DefaultRNG::default()).unwrap();
29//! let additional_input: &[u8] = b"some additional input";
30//!
31//! let h = factory::kdf_factory::KDFFactory::new("HKDF-SHA256").unwrap();
32//! let new_key = h.derive_key(&seed_key, additional_input).unwrap();
33//! ```
34//!
35//! Or if you don't particularly care which algorithm is used, you can use the built-in default:
36//!
37//! ```
38//! use core_interface::key_material::{KeyMaterial256, KeyType};
39//! use factory::AlgorithmFactory;
40//! use core_interface::traits::KDF;
41//!
42//! // get your key material from a secure place; here we'll use the default RNG, seeded from the OS
43//! let seed_key = KeyMaterial256::from_rng(&mut rng::DefaultRNG::default()).unwrap();
44//! let additional_input: &[u8] = b"some additional input";
45//!
46//! let h = factory::kdf_factory::KDFFactory::default();
47//! let new_key = h.derive_key(&seed_key, additional_input).unwrap();
48//! ```
49
50use 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
59/*** Defaults ***/
60pub 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
64// All members must impl KDF.
65pub 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}