1use crate::{SHA2Params};
2use core::slice;
3use bouncycastle_core_interface::errors::HashError;
4use bouncycastle_core_interface::traits::{Hash, SecurityStrength};
5use bouncycastle_utils::min;
6
7const SHA256_K: [u32; 64] = [
8 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
9 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
10 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
11 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
12 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
13 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
14 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
15 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
16];
17
18#[inline]
19fn ch(x: u32, y: u32, z: u32) -> u32 {
20 (x & y) ^ (!x & z)
21}
22
23#[inline]
24fn maj(x: u32, y: u32, z: u32) -> u32 {
25 (x & y) | (z & (x ^ y))
26}
27
28#[inline]
29fn sum0(x: u32) -> u32 {
30 x.rotate_right(2) ^ x.rotate_right(13) ^ x.rotate_right(22)
31}
32
33#[inline]
34fn sum1(x: u32) -> u32 {
35 x.rotate_right(6) ^ x.rotate_right(11) ^ x.rotate_right(25)
36}
37
38#[inline]
39fn theta0(x: u32) -> u32 {
40 x.rotate_right(7) ^ x.rotate_right(18) ^ (x >> 3)
41}
42
43#[inline]
44fn theta1(x: u32) -> u32 {
45 x.rotate_right(17) ^ x.rotate_right(19) ^ (x >> 10)
46}
47
48#[derive(Clone)]
51pub(crate) struct Sha256State<PARAMS: SHA2Params> {
52 _params: std::marker::PhantomData<PARAMS>,
53 h: [u32; 8],
54}
55
56impl<PARAMS: SHA2Params> Drop for Sha256State<PARAMS> {
57 fn drop(&mut self) {
58 self.h.fill(0);
59 }
60}
61
62impl<PARAMS: SHA2Params> Sha256State<PARAMS> {
63 pub(crate) fn new() -> Self {
64 match PARAMS::OUTPUT_LEN * 8 {
65 224 => Self {
66 _params: std::marker::PhantomData,
67 h: [
68 0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939, 0xFFC00B31, 0x68581511,
69 0x64F98FA7, 0xBEFA4FA4,
70 ],
71 },
72 256 => Self {
73 _params: std::marker::PhantomData,
74 h: [
75 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C,
76 0x1F83D9AB, 0x5BE0CD19,
77 ],
78 },
79 _ => panic!("Invalid SHA-2 bit size: {}", PARAMS::OUTPUT_LEN),
80 }
81 }
82
83 fn compress(&mut self, blocks: &[[u8; 64]]) {
84 let mut x = [0u32; 64];
85
86 let s = &mut self.h;
87 let &mut [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h] = s;
88
89 for block in blocks {
90 let (chunks, _remainder) = block.as_chunks::<4>();
91 for (i, w) in x[..16].iter_mut().zip(chunks) {
92 *i = u32::from_be_bytes(*w);
93 }
94
95 for i in 16..64 {
96 x[i] = theta1(x[i - 2])
97 .wrapping_add(x[i - 7])
98 .wrapping_add(theta0(x[i - 15]))
99 .wrapping_add(x[i - 16]);
100 }
101
102 macro_rules! sha256_round {
103 ($a:ident,$b:ident,$c:ident,$d:ident,$e:ident,$f:ident,$g:ident,$h:ident,$t:ident,$K:ident,$x:ident) => {
104 $h = $h
105 .wrapping_add(sum1($e))
106 .wrapping_add(ch($e, $f, $g))
107 .wrapping_add($K[$t])
108 .wrapping_add($x[$t]);
109 $d = $d.wrapping_add($h);
110 $h = $h.wrapping_add(sum0($a)).wrapping_add(maj($a, $b, $c));
111 $t += 1;
112 };
113 }
114
115 let mut t: usize = 0;
116 for _ in 0..8 {
117 sha256_round!(a, b, c, d, e, f, g, h, t, SHA256_K, x);
118 sha256_round!(h, a, b, c, d, e, f, g, t, SHA256_K, x);
119 sha256_round!(g, h, a, b, c, d, e, f, t, SHA256_K, x);
120 sha256_round!(f, g, h, a, b, c, d, e, t, SHA256_K, x);
121 sha256_round!(e, f, g, h, a, b, c, d, t, SHA256_K, x);
122 sha256_round!(d, e, f, g, h, a, b, c, t, SHA256_K, x);
123 sha256_round!(c, d, e, f, g, h, a, b, t, SHA256_K, x);
124 sha256_round!(b, c, d, e, f, g, h, a, t, SHA256_K, x);
125 }
126
127 a = a.wrapping_add(s[0]);
128 b = b.wrapping_add(s[1]);
129 c = c.wrapping_add(s[2]);
130 d = d.wrapping_add(s[3]);
131 e = e.wrapping_add(s[4]);
132 f = f.wrapping_add(s[5]);
133 g = g.wrapping_add(s[6]);
134 h = h.wrapping_add(s[7]);
135
136 s[0] = a;
137 s[1] = b;
138 s[2] = c;
139 s[3] = d;
140 s[4] = e;
141 s[5] = f;
142 s[6] = g;
143 s[7] = h;
144 }
145 }
146}
147
148#[derive(Clone)]
151pub struct SHA256Internal<PARAMS: SHA2Params> {
152 _params: std::marker::PhantomData<PARAMS>,
153 state: Sha256State<PARAMS>,
154 byte_count: u64,
155 x_buf: [u8; 64],
156 x_buf_off: usize,
157 }
159
160impl<PARAMS: SHA2Params> Drop for SHA256Internal<PARAMS> {
161 fn drop(&mut self) {
162 self.x_buf.fill(0);
163 }}
164
165impl<PARAMS: SHA2Params> SHA256Internal<PARAMS> {
166 pub fn new() -> Self {
167 Self {
168 _params: std::marker::PhantomData,
169 state: Sha256State::<PARAMS>::new(),
170 byte_count: 0,
171 x_buf: [0; 64],
172 x_buf_off: 0,
173 }
174 }
175}
176
177impl<PARAMS: SHA2Params> Default for SHA256Internal<PARAMS> {
178 fn default() -> Self {
179 Self::new()
180 }
181}
182
183impl<PARAMS: SHA2Params> Hash for SHA256Internal<PARAMS> {
184 fn block_bitlen(&self) -> usize {
186 512
187 }
188
189 fn output_len(&self) -> usize {
190 PARAMS::OUTPUT_LEN
191 }
192
193 fn hash(self, data: &[u8]) -> Vec<u8> {
194 let mut output = vec![0u8; PARAMS::OUTPUT_LEN];
195 self.hash_out(data, &mut output);
196 output
197 }
198
199 fn hash_out(mut self, data: &[u8], output: &mut [u8]) -> usize {
200 self.do_update(data);
201 self.do_final_out(output)
202 }
203
204 fn do_update(&mut self, block: &[u8]) {
205 let len = block.len();
206
207 self.byte_count += len as u64;
210
211 let available = 64 - self.x_buf_off;
212
213 if len < available {
215 self.x_buf[self.x_buf_off..self.x_buf_off + len].copy_from_slice(block);
216 self.x_buf_off += len;
217 return;
218 }
219
220 let mut block = block;
221 if self.x_buf_off != 0 {
222 self.x_buf[self.x_buf_off..].copy_from_slice(&block[..available]);
223 block = &block[available..];
224
225 self.state.compress(slice::from_ref(&self.x_buf));
226 }
227
228 let (chunks, remainder) = block.as_chunks::<64>();
229
230 self.state.compress(chunks);
231
232 let remaining = remainder.len();
233 self.x_buf[..remaining].copy_from_slice(remainder);
234 self.x_buf_off = remaining;
235 }
236
237 fn do_final(self) -> Vec<u8> {
238 let mut output = vec![0u8; PARAMS::OUTPUT_LEN];
239 self.do_final_out(&mut output);
240 output
241 }
242
243 fn do_final_out(mut self, output: &mut [u8]) -> usize {
244 let n = *min(&output.len(), &PARAMS::OUTPUT_LEN);
245
246 let bit_len: u64 = self.byte_count << 3;
247
248 self.x_buf[self.x_buf_off] = 0x80;
249 self.x_buf_off += 1;
250
251 if self.x_buf_off > 56 {
252 self.x_buf[self.x_buf_off..].fill(0x00);
253 self.state.compress(slice::from_ref(&self.x_buf));
254 self.x_buf_off = 0;
255 }
256
257 self.x_buf[self.x_buf_off..56].fill(0x00);
258 self.x_buf[56..64].copy_from_slice(&bit_len.to_be_bytes());
259 self.state.compress(slice::from_ref(&self.x_buf));
260
261 let h = &self.state.h;
262
263 for i in 0..(n / 4) {
265 output[i * 4..i * 4 + 4].copy_from_slice(&h[i].to_be_bytes());
266 }
267 if !n.is_multiple_of(4) {
268 output[((n / 4) * 4)..((n / 4) * 4) + (n % 4)]
269 .copy_from_slice(&h[n / 4].to_be_bytes()[0..(n % 4)]);
270 }
271
272 n
273 }
274
275 #[allow(unused)]
279 fn do_final_partial_bits(
280 self,
281 partial_byte: u8,
282 num_partial_bits: usize,
283 ) -> Result<Vec<u8>, HashError> {
284 unimplemented!()
285 }
286
287 #[allow(unused)]
291 fn do_final_partial_bits_out(
292 self,
293 partial_byte: u8,
294 num_partial_bits: usize,
295 output: &mut [u8],
296 ) -> Result<usize, HashError> {
297 unimplemented!()
298 }
299
300 fn max_security_strength(&self) -> SecurityStrength {
301 SecurityStrength::from_bytes(PARAMS::OUTPUT_LEN / 2)
302 }
303}