Skip to main content

bouncycastle_factory/
hash_factory.rs

1//! Hash factory for creating instances of algorithms that implement the [Hash] trait.
2//!
3//! As with all Factory objects, this implements constructions from strings and defaults, and
4//! returns a [HashFactory] object which itself implements the [Hash] trait as a pass-through to the underlying algorithm.
5//!
6//! Example usage:
7//! ```
8//! use bouncycastle_factory::AlgorithmFactory;
9//! use bouncycastle_core::traits::Hash;
10//! use bouncycastle_sha3 as sha3;
11//!
12//! let data: &[u8] = b"Hello, world!";
13//!
14//! let h = bouncycastle_factory::hash_factory::HashFactory::new(sha3::SHA3_256_NAME).unwrap();
15//! let output: Vec<u8> = h.hash(data);
16//! ```
17//! You can equivalently invoke this by string instead of using the constant:
18//!
19//! ```
20//! use bouncycastle_factory::AlgorithmFactory;
21//! use bouncycastle_core::traits::Hash;
22//!
23//! let data: &[u8] = b"Hello, world!";
24//!
25//! let h = bouncycastle_factory::hash_factory::HashFactory::new("SHA3-256").unwrap();
26//! let output: Vec<u8> = h.hash(data);
27//! ```
28
29use crate::{AlgorithmFactory, FactoryError};
30use crate::{DEFAULT, DEFAULT_128_BIT, DEFAULT_256_BIT};
31use bouncycastle_core::errors::HashError;
32use bouncycastle_core::traits::{Hash, SecurityStrength};
33use bouncycastle_sha2 as sha2;
34use bouncycastle_sha2::{SHA224_NAME, SHA256_NAME, SHA384_NAME, SHA512_NAME};
35use bouncycastle_sha3 as sha3;
36use bouncycastle_sha3::{SHA3_224_NAME, SHA3_256_NAME, SHA3_384_NAME, SHA3_512_NAME};
37
38/*** Defaults ***/
39pub const DEFAULT_HASH_NAME: &str = SHA3_256_NAME;
40pub const DEFAULT_128BIT_HASH_NAME: &str = SHA3_256_NAME;
41pub const DEFAULT_256BIT_HASH_NAME: &str = SHA3_512_NAME;
42
43/// All members must impl Hash.
44/// Note: no SHAKE because SHAKE is not NIST approved as a hash function. See FIPS 202 section A.2.
45pub enum HashFactory {
46    SHA224(sha2::SHA224),
47    SHA256(sha2::SHA256),
48    SHA384(sha2::SHA384),
49    SHA512(sha2::SHA512),
50    SHA3_224(sha3::SHA3_224),
51    SHA3_256(sha3::SHA3_256),
52    SHA3_384(sha3::SHA3_384),
53    SHA3_512(sha3::SHA3_512),
54}
55
56impl Default for HashFactory {
57    fn default() -> HashFactory {
58        Self::new(DEFAULT_HASH_NAME).unwrap()
59    }
60}
61
62impl AlgorithmFactory for HashFactory {
63    fn default_128_bit() -> HashFactory {
64        Self::new(DEFAULT_128BIT_HASH_NAME).unwrap()
65    }
66    fn default_256_bit() -> HashFactory {
67        Self::new(DEFAULT_256BIT_HASH_NAME).unwrap()
68    }
69
70    fn new(alg_name: &str) -> Result<Self, FactoryError> {
71        match alg_name {
72            DEFAULT => Ok(Self::default()),
73            DEFAULT_128_BIT => Ok(Self::default_128_bit()),
74            DEFAULT_256_BIT => Ok(Self::default_256_bit()),
75            SHA224_NAME => Ok(Self::SHA224(sha2::SHA224::new())),
76            SHA256_NAME => Ok(Self::SHA256(sha2::SHA256::new())),
77            SHA384_NAME => Ok(Self::SHA384(sha2::SHA384::new())),
78            SHA512_NAME => Ok(Self::SHA512(sha2::SHA512::new())),
79            SHA3_224_NAME => Ok(Self::SHA3_224(sha3::SHA3_224::new())),
80            SHA3_256_NAME => Ok(Self::SHA3_256(sha3::SHA3_256::new())),
81            SHA3_384_NAME => Ok(Self::SHA3_384(sha3::SHA3_384::new())),
82            SHA3_512_NAME => Ok(Self::SHA3_512(sha3::SHA3_512::new())),
83            _ => Err(FactoryError::UnsupportedAlgorithm(format!(
84                "The algorithm: \"{}\" is not a known Hash",
85                alg_name
86            ))),
87        }
88    }
89}
90
91impl Hash for HashFactory {
92    fn block_bitlen(&self) -> usize {
93        match self {
94            Self::SHA224(h) => h.block_bitlen(),
95            Self::SHA256(h) => h.block_bitlen(),
96            Self::SHA384(h) => h.block_bitlen(),
97            Self::SHA512(h) => h.block_bitlen(),
98            Self::SHA3_224(h) => h.block_bitlen(),
99            Self::SHA3_256(h) => h.block_bitlen(),
100            Self::SHA3_384(h) => h.block_bitlen(),
101            Self::SHA3_512(h) => h.block_bitlen(),
102        }
103    }
104
105    fn output_len(&self) -> usize {
106        match self {
107            Self::SHA224(h) => h.output_len(),
108            Self::SHA256(h) => h.output_len(),
109            Self::SHA384(h) => h.output_len(),
110            Self::SHA512(h) => h.output_len(),
111            Self::SHA3_224(h) => h.output_len(),
112            Self::SHA3_256(h) => h.output_len(),
113            Self::SHA3_384(h) => h.output_len(),
114            Self::SHA3_512(h) => h.output_len(),
115        }
116    }
117
118    fn hash(self, data: &[u8]) -> Vec<u8> {
119        match self {
120            Self::SHA224(h) => h.hash(data),
121            Self::SHA256(h) => h.hash(data),
122            Self::SHA384(h) => h.hash(data),
123            Self::SHA512(h) => h.hash(data),
124            Self::SHA3_224(h) => h.hash(data),
125            Self::SHA3_256(h) => h.hash(data),
126            Self::SHA3_384(h) => h.hash(data),
127            Self::SHA3_512(h) => h.hash(data),
128        }
129    }
130
131    fn hash_out(self, data: &[u8], output: &mut [u8]) -> usize {
132        match self {
133            Self::SHA224(h) => h.hash_out(data, output),
134            Self::SHA256(h) => h.hash_out(data, output),
135            Self::SHA384(h) => h.hash_out(data, output),
136            Self::SHA512(h) => h.hash_out(data, output),
137            Self::SHA3_224(h) => h.hash_out(data, output),
138            Self::SHA3_256(h) => h.hash_out(data, output),
139            Self::SHA3_384(h) => h.hash_out(data, output),
140            Self::SHA3_512(h) => h.hash_out(data, output),
141        }
142    }
143
144    fn do_update(&mut self, data: &[u8]) {
145        match self {
146            Self::SHA224(h) => h.do_update(data),
147            Self::SHA256(h) => h.do_update(data),
148            Self::SHA384(h) => h.do_update(data),
149            Self::SHA512(h) => h.do_update(data),
150            Self::SHA3_224(h) => h.do_update(data),
151            Self::SHA3_256(h) => h.do_update(data),
152            Self::SHA3_384(h) => h.do_update(data),
153            Self::SHA3_512(h) => h.do_update(data),
154        }
155    }
156
157    fn do_final(self) -> Vec<u8> {
158        match self {
159            Self::SHA224(h) => h.do_final(),
160            Self::SHA256(h) => h.do_final(),
161            Self::SHA384(h) => h.do_final(),
162            Self::SHA512(h) => h.do_final(),
163            Self::SHA3_224(h) => h.do_final(),
164            Self::SHA3_256(h) => h.do_final(),
165            Self::SHA3_384(h) => h.do_final(),
166            Self::SHA3_512(h) => h.do_final(),
167        }
168    }
169
170    fn do_final_out(self, output: &mut [u8]) -> usize {
171        match self {
172            Self::SHA224(h) => h.do_final_out(output),
173            Self::SHA256(h) => h.do_final_out(output),
174            Self::SHA384(h) => h.do_final_out(output),
175            Self::SHA512(h) => h.do_final_out(output),
176            Self::SHA3_224(h) => h.do_final_out(output),
177            Self::SHA3_256(h) => h.do_final_out(output),
178            Self::SHA3_384(h) => h.do_final_out(output),
179            Self::SHA3_512(h) => h.do_final_out(output),
180        }
181    }
182
183    fn do_final_partial_bits(
184        self,
185        partial_byte: u8,
186        num_partial_bits: usize,
187    ) -> Result<Vec<u8>, HashError> {
188        match self {
189            Self::SHA224(h) => h.do_final_partial_bits(partial_byte, num_partial_bits),
190            Self::SHA256(h) => h.do_final_partial_bits(partial_byte, num_partial_bits),
191            Self::SHA384(h) => h.do_final_partial_bits(partial_byte, num_partial_bits),
192            Self::SHA512(h) => h.do_final_partial_bits(partial_byte, num_partial_bits),
193            Self::SHA3_224(h) => h.do_final_partial_bits(partial_byte, num_partial_bits),
194            Self::SHA3_256(h) => h.do_final_partial_bits(partial_byte, num_partial_bits),
195            Self::SHA3_384(h) => h.do_final_partial_bits(partial_byte, num_partial_bits),
196            Self::SHA3_512(h) => h.do_final_partial_bits(partial_byte, num_partial_bits),
197        }
198    }
199
200    fn do_final_partial_bits_out(
201        self,
202        partial_byte: u8,
203        num_partial_bits: usize,
204        output: &mut [u8],
205    ) -> Result<usize, HashError> {
206        match self {
207            Self::SHA224(h) => h.do_final_partial_bits_out(partial_byte, num_partial_bits, output),
208            Self::SHA256(h) => h.do_final_partial_bits_out(partial_byte, num_partial_bits, output),
209            Self::SHA384(h) => h.do_final_partial_bits_out(partial_byte, num_partial_bits, output),
210            Self::SHA512(h) => h.do_final_partial_bits_out(partial_byte, num_partial_bits, output),
211            Self::SHA3_224(h) => {
212                h.do_final_partial_bits_out(partial_byte, num_partial_bits, output)
213            }
214            Self::SHA3_256(h) => {
215                h.do_final_partial_bits_out(partial_byte, num_partial_bits, output)
216            }
217            Self::SHA3_384(h) => {
218                h.do_final_partial_bits_out(partial_byte, num_partial_bits, output)
219            }
220            Self::SHA3_512(h) => {
221                h.do_final_partial_bits_out(partial_byte, num_partial_bits, output)
222            }
223        }
224    }
225
226    fn max_security_strength(&self) -> SecurityStrength {
227        match self {
228            Self::SHA224(h) => h.max_security_strength(),
229            Self::SHA256(h) => h.max_security_strength(),
230            Self::SHA384(h) => h.max_security_strength(),
231            Self::SHA512(h) => h.max_security_strength(),
232            Self::SHA3_224(h) => h.max_security_strength(),
233            Self::SHA3_256(h) => h.max_security_strength(),
234            Self::SHA3_384(h) => h.max_security_strength(),
235            Self::SHA3_512(h) => h.max_security_strength(),
236        }
237    }
238}