1use crate::SHA2Params;
2use bouncycastle_core::errors::{HashError, SuspendableError};
3use bouncycastle_core::suspendable_state::{add_lib_ver, check_lib_ver};
4use bouncycastle_core::traits::{Algorithm, Hash, SecurityStrength, Suspendable};
5use bouncycastle_utils::{min, secret::Secret};
6use core::slice;
7
8const SHA256_K: [u32; 64] = [
9 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
10 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
11 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
12 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
13 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
14 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
15 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
16 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
17];
18
19#[inline]
20fn ch(x: u32, y: u32, z: u32) -> u32 {
21 (x & y) ^ (!x & z)
22}
23
24#[inline]
25fn maj(x: u32, y: u32, z: u32) -> u32 {
26 (x & y) | (z & (x ^ y))
27}
28
29#[inline]
30fn sum0(x: u32) -> u32 {
31 x.rotate_right(2) ^ x.rotate_right(13) ^ x.rotate_right(22)
32}
33
34#[inline]
35fn sum1(x: u32) -> u32 {
36 x.rotate_right(6) ^ x.rotate_right(11) ^ x.rotate_right(25)
37}
38
39#[inline]
40fn theta0(x: u32) -> u32 {
41 x.rotate_right(7) ^ x.rotate_right(18) ^ (x >> 3)
42}
43
44#[inline]
45fn theta1(x: u32) -> u32 {
46 x.rotate_right(17) ^ x.rotate_right(19) ^ (x >> 10)
47}
48
49#[derive(Clone)]
50pub(crate) struct Sha256State<PARAMS: SHA2Params> {
51 _params: core::marker::PhantomData<PARAMS>,
52 h: Secret<[u32; 8]>,
53}
54
55impl<PARAMS: SHA2Params> Sha256State<PARAMS> {
56 pub(crate) fn new() -> Self {
57 let mut h = Secret::<[u32; 8]>::new();
58 match PARAMS::OUTPUT_LEN * 8 {
59 224 => {
60 h.copy_from_slice(&[
61 0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939, 0xFFC00B31, 0x68581511,
62 0x64F98FA7, 0xBEFA4FA4,
63 ]);
64 Self { _params: core::marker::PhantomData, h }
65 }
66 256 => {
67 h.copy_from_slice(&[
68 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C,
69 0x1F83D9AB, 0x5BE0CD19,
70 ]);
71 Self { _params: std::marker::PhantomData, h }
72 }
73 _ => panic!("Invalid SHA-2 bit size: {}", PARAMS::OUTPUT_LEN),
74 }
75 }
76
77 fn compress(&mut self, blocks: &[[u8; 64]]) {
78 let mut x = [0u32; 64];
79
80 let s = &mut *self.h;
82 let &mut [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h] = s;
83
84 for block in blocks {
85 let (chunks, _remainder) = block.as_chunks::<4>();
86 for (i, w) in x[..16].iter_mut().zip(chunks) {
87 *i = u32::from_be_bytes(*w);
88 }
89
90 for i in 16..64 {
91 x[i] = theta1(x[i - 2])
92 .wrapping_add(x[i - 7])
93 .wrapping_add(theta0(x[i - 15]))
94 .wrapping_add(x[i - 16]);
95 }
96
97 macro_rules! sha256_round {
98 ($a:ident,$b:ident,$c:ident,$d:ident,$e:ident,$f:ident,$g:ident,$h:ident,$t:ident,$K:ident,$x:ident) => {
99 $h = $h
100 .wrapping_add(sum1($e))
101 .wrapping_add(ch($e, $f, $g))
102 .wrapping_add($K[$t])
103 .wrapping_add($x[$t]);
104 $d = $d.wrapping_add($h);
105 $h = $h.wrapping_add(sum0($a)).wrapping_add(maj($a, $b, $c));
106 $t += 1;
107 };
108 }
109
110 let mut t: usize = 0;
111 for _ in 0..8 {
112 sha256_round!(a, b, c, d, e, f, g, h, t, SHA256_K, x);
113 sha256_round!(h, a, b, c, d, e, f, g, t, SHA256_K, x);
114 sha256_round!(g, h, a, b, c, d, e, f, t, SHA256_K, x);
115 sha256_round!(f, g, h, a, b, c, d, e, t, SHA256_K, x);
116 sha256_round!(e, f, g, h, a, b, c, d, t, SHA256_K, x);
117 sha256_round!(d, e, f, g, h, a, b, c, t, SHA256_K, x);
118 sha256_round!(c, d, e, f, g, h, a, b, t, SHA256_K, x);
119 sha256_round!(b, c, d, e, f, g, h, a, t, SHA256_K, x);
120 }
121
122 a = a.wrapping_add(s[0]);
123 b = b.wrapping_add(s[1]);
124 c = c.wrapping_add(s[2]);
125 d = d.wrapping_add(s[3]);
126 e = e.wrapping_add(s[4]);
127 f = f.wrapping_add(s[5]);
128 g = g.wrapping_add(s[6]);
129 h = h.wrapping_add(s[7]);
130
131 s[0] = a;
132 s[1] = b;
133 s[2] = c;
134 s[3] = d;
135 s[4] = e;
136 s[5] = f;
137 s[6] = g;
138 s[7] = h;
139 }
140 }
141}
142
143#[derive(Clone)]
147pub struct SHA256Internal<PARAMS: SHA2Params> {
148 _params: core::marker::PhantomData<PARAMS>,
149 state: Sha256State<PARAMS>,
150 byte_count: u64,
151 x_buf: Secret<[u8; 64]>,
152 x_buf_off: usize,
153 }
156
157impl<PARAMS: SHA2Params> SHA256Internal<PARAMS> {
158 pub fn new() -> Self {
160 Self {
161 _params: core::marker::PhantomData,
162 state: Sha256State::<PARAMS>::new(),
163 byte_count: 0,
164 x_buf: Secret::new(),
165 x_buf_off: 0,
166 }
167 }
168}
169
170impl<PARAMS: SHA2Params> Default for SHA256Internal<PARAMS> {
171 fn default() -> Self {
172 Self::new()
173 }
174}
175
176impl<PARAMS: SHA2Params> Algorithm for SHA256Internal<PARAMS> {
177 const ALG_NAME: &'static str = PARAMS::ALG_NAME;
178 const MAX_SECURITY_STRENGTH: SecurityStrength = PARAMS::MAX_SECURITY_STRENGTH;
179}
180
181impl<PARAMS: SHA2Params> Hash for SHA256Internal<PARAMS> {
182 fn block_bitlen(&self) -> usize {
184 512
185 }
186
187 fn output_len(&self) -> usize {
188 PARAMS::OUTPUT_LEN
189 }
190
191 fn hash(self, data: &[u8]) -> Vec<u8> {
192 let mut output = vec![0u8; PARAMS::OUTPUT_LEN];
193 self.hash_out(data, &mut output);
194 output
195 }
196
197 fn hash_out(mut self, data: &[u8], output: &mut [u8]) -> usize {
198 output.fill(0);
199
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 output.fill(0);
245
246 let n = *min(&output.len(), &PARAMS::OUTPUT_LEN);
247
248 let bit_len: u64 = self.byte_count << 3;
249
250 self.x_buf[self.x_buf_off] = 0x80;
251 self.x_buf_off += 1;
252
253 if self.x_buf_off > 56 {
254 self.x_buf[self.x_buf_off..].fill(0x00);
255 self.state.compress(slice::from_ref(&self.x_buf));
256 self.x_buf_off = 0;
257 }
258
259 self.x_buf[self.x_buf_off..56].fill(0x00);
260 self.x_buf[56..64].copy_from_slice(&bit_len.to_be_bytes());
261 self.state.compress(slice::from_ref(&self.x_buf));
262
263 let h = &self.state.h;
264
265 for i in 0..(n / 4) {
267 output[i * 4..i * 4 + 4].copy_from_slice(&h[i].to_be_bytes());
268 }
269 if !n.is_multiple_of(4) {
270 output[((n / 4) * 4)..((n / 4) * 4) + (n % 4)]
271 .copy_from_slice(&h[n / 4].to_be_bytes()[0..(n % 4)]);
272 }
273
274 n
275 }
276
277 #[allow(unused)]
281 fn do_final_partial_bits(
282 self,
283 partial_byte: u8,
284 num_partial_bits: usize,
285 ) -> Result<Vec<u8>, HashError> {
286 unimplemented!()
287 }
288
289 #[allow(unused)]
293 fn do_final_partial_bits_out(
294 self,
295 partial_byte: u8,
296 num_partial_bits: usize,
297 output: &mut [u8],
298 ) -> Result<usize, HashError> {
299 unimplemented!()
300 }
301
302 fn max_security_strength(&self) -> SecurityStrength {
303 SecurityStrength::from_bytes(PARAMS::OUTPUT_LEN / 2)
304 }
305}
306
307pub const SUSPENDED_SHA256_STATE_LEN: usize = 108;
309
310impl<PARAMS: SHA2Params> Suspendable<SUSPENDED_SHA256_STATE_LEN> for SHA256Internal<PARAMS> {
311 fn suspend(self) -> [u8; SUSPENDED_SHA256_STATE_LEN] {
312 debug_assert_eq!(SUSPENDED_SHA256_STATE_LEN, 108);
313
314 let mut out_to_return = [0u8; SUSPENDED_SHA256_STATE_LEN];
315
316 let out: &mut [u8; 105] = add_lib_ver(&mut out_to_return).try_into().unwrap();
319
320 for i in 0..8 {
323 out[i * 4..(i * 4) + 4].copy_from_slice(&self.state.h[i].to_le_bytes());
324 }
325
326 out[32..40].copy_from_slice(&self.byte_count.to_le_bytes());
328
329 out[40..104].copy_from_slice(&*self.x_buf);
331
332 debug_assert!(self.x_buf_off < 64);
335 out[104] = self.x_buf_off as u8;
336
337 out_to_return
338 }
339
340 fn from_suspended(
341 serialized_state: [u8; SUSPENDED_SHA256_STATE_LEN],
342 ) -> Result<Self, SuspendableError> {
343 debug_assert_eq!(SUSPENDED_SHA256_STATE_LEN, 108);
344
345 let input: &[u8; 105] = check_lib_ver(&serialized_state, None)?.try_into().unwrap();
349
350 let mut h = Secret::<[u32; 8]>::new();
353 for i in 0..8 {
354 h[i] = u32::from_le_bytes(input[i * 4..(i * 4) + 4].try_into().unwrap());
355 }
356
357 let byte_count: u64 = u64::from_le_bytes(input[32..40].try_into().unwrap());
359
360 let mut x_buf = Secret::<[u8; 64]>::new();
362 x_buf.copy_from_slice(&input[40..104]);
363
364 let x_buf_off: usize = input[104] as usize;
367 if x_buf_off >= 64 {
368 return Err(SuspendableError::InvalidData);
369 }
370
371 let state = Sha256State { _params: core::marker::PhantomData, h };
373 Ok(SHA256Internal {
374 _params: core::marker::PhantomData,
375 state,
376 byte_count,
377 x_buf,
378 x_buf_off,
379 })
380 }
381}