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