1#[cfg(not(feature = "std"))]
7use alloc::vec::Vec;
8
9use crate::error::{validate, Result};
10use crate::hash::{Hash, HashAlgorithm, HashFunction};
11use crate::types::Digest;
12use byteorder::{BigEndian, ByteOrder};
13use zeroize::Zeroize;
14
15use dcrypt_common::security::{EphemeralSecret, SecureZeroingType, ZeroizeGuard};
17#[cfg(not(feature = "std"))]
18use portable_atomic::{compiler_fence, Ordering};
19#[cfg(feature = "std")]
20use std::sync::atomic::{compiler_fence, Ordering};
21
22use dcrypt_params::utils::hash::{
23 SHA224_OUTPUT_SIZE, SHA256_BLOCK_SIZE, SHA256_OUTPUT_SIZE, SHA384_OUTPUT_SIZE,
24 SHA512_BLOCK_SIZE, SHA512_OUTPUT_SIZE,
25};
26
27const K256: [u32; 64] = [
29 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
30 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
31 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
32 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
33 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
34 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
35 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
36 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
37];
38
39const K512: [u64; 80] = [
41 0x428a2f98d728ae22,
42 0x7137449123ef65cd,
43 0xb5c0fbcfec4d3b2f,
44 0xe9b5dba58189dbbc,
45 0x3956c25bf348b538,
46 0x59f111f1b605d019,
47 0x923f82a4af194f9b,
48 0xab1c5ed5da6d8118,
49 0xd807aa98a3030242,
50 0x12835b0145706fbe,
51 0x243185be4ee4b28c,
52 0x550c7dc3d5ffb4e2,
53 0x72be5d74f27b896f,
54 0x80deb1fe3b1696b1,
55 0x9bdc06a725c71235,
56 0xc19bf174cf692694,
57 0xe49b69c19ef14ad2,
58 0xefbe4786384f25e3,
59 0x0fc19dc68b8cd5b5,
60 0x240ca1cc77ac9c65,
61 0x2de92c6f592b0275,
62 0x4a7484aa6ea6e483,
63 0x5cb0a9dcbd41fbd4,
64 0x76f988da831153b5,
65 0x983e5152ee66dfab,
66 0xa831c66d2db43210,
67 0xb00327c898fb213f,
68 0xbf597fc7beef0ee4,
69 0xc6e00bf33da88fc2,
70 0xd5a79147930aa725,
71 0x06ca6351e003826f,
72 0x142929670a0e6e70,
73 0x27b70a8546d22ffc,
74 0x2e1b21385c26c926,
75 0x4d2c6dfc5ac42aed,
76 0x53380d139d95b3df,
77 0x650a73548baf63de,
78 0x766a0abb3c77b2a8,
79 0x81c2c92e47edaee6,
80 0x92722c851482353b,
81 0xa2bfe8a14cf10364,
82 0xa81a664bbc423001,
83 0xc24b8b70d0f89791,
84 0xc76c51a30654be30,
85 0xd192e819d6ef5218,
86 0xd69906245565a910,
87 0xf40e35855771202a,
88 0x106aa07032bbd1b8,
89 0x19a4c116b8d2d0c8,
90 0x1e376c085141ab53,
91 0x2748774cdf8eeb99,
92 0x34b0bcb5e19b48a8,
93 0x391c0cb3c5c95a63,
94 0x4ed8aa4ae3418acb,
95 0x5b9cca4f7763e373,
96 0x682e6ff3d6b2b8a3,
97 0x748f82ee5defb2fc,
98 0x78a5636f43172f60,
99 0x84c87814a1f0ab72,
100 0x8cc702081a6439ec,
101 0x90befffa23631e28,
102 0xa4506cebde82bde9,
103 0xbef9a3f7b2c67915,
104 0xc67178f2e372532b,
105 0xca273eceea26619c,
106 0xd186b8c721c0c207,
107 0xeada7dd6cde0eb1e,
108 0xf57d4f7fee6ed178,
109 0x06f067aa72176fba,
110 0x0a637dc5a2c898a6,
111 0x113f9804bef90dae,
112 0x1b710b35131c471b,
113 0x28db77f523047d84,
114 0x32caab7b40c72493,
115 0x3c9ebe0a15c9bebc,
116 0x431d67c49c100d4c,
117 0x4cc5d4becb3e42b6,
118 0x597f299cfc657e2a,
119 0x5fcb6fab3ad6faec,
120 0x6c44198c4a475817,
121];
122
123pub enum Sha256Algorithm {}
126
127impl HashAlgorithm for Sha256Algorithm {
128 const OUTPUT_SIZE: usize = SHA256_OUTPUT_SIZE;
129 const BLOCK_SIZE: usize = SHA256_BLOCK_SIZE;
130 const ALGORITHM_ID: &'static str = "SHA-256";
131}
132
133pub enum Sha224Algorithm {}
135
136impl HashAlgorithm for Sha224Algorithm {
137 const OUTPUT_SIZE: usize = SHA224_OUTPUT_SIZE;
138 const BLOCK_SIZE: usize = SHA256_BLOCK_SIZE;
139 const ALGORITHM_ID: &'static str = "SHA-224";
140}
141
142pub enum Sha384Algorithm {}
144
145impl HashAlgorithm for Sha384Algorithm {
146 const OUTPUT_SIZE: usize = SHA384_OUTPUT_SIZE;
147 const BLOCK_SIZE: usize = SHA512_BLOCK_SIZE;
148 const ALGORITHM_ID: &'static str = "SHA-384";
149}
150
151pub enum Sha512Algorithm {}
153
154impl HashAlgorithm for Sha512Algorithm {
155 const OUTPUT_SIZE: usize = SHA512_OUTPUT_SIZE;
156 const BLOCK_SIZE: usize = SHA512_BLOCK_SIZE;
157 const ALGORITHM_ID: &'static str = "SHA-512";
158}
159
160pub enum Sha512_224Algorithm {}
162
163impl HashAlgorithm for Sha512_224Algorithm {
164 const OUTPUT_SIZE: usize = SHA224_OUTPUT_SIZE;
165 const BLOCK_SIZE: usize = SHA512_BLOCK_SIZE;
166 const ALGORITHM_ID: &'static str = "SHA-512/224";
167}
168
169pub enum Sha512_256Algorithm {}
171
172impl HashAlgorithm for Sha512_256Algorithm {
173 const OUTPUT_SIZE: usize = SHA256_OUTPUT_SIZE;
174 const BLOCK_SIZE: usize = SHA512_BLOCK_SIZE;
175 const ALGORITHM_ID: &'static str = "SHA-512/256";
176}
177
178#[derive(Clone, Zeroize)]
180pub struct Sha224 {
181 state: [u32; 8],
182 buffer: [u8; SHA256_BLOCK_SIZE],
183 buffer_idx: usize,
184 total_bytes: u64,
185}
186
187impl Drop for Sha224 {
188 fn drop(&mut self) {
189 self.zeroize();
190 }
191}
192
193#[derive(Clone, Zeroize)]
195pub struct Sha256 {
196 state: [u32; 8],
197 buffer: [u8; SHA256_BLOCK_SIZE],
198 buffer_idx: usize,
199 total_bytes: u64,
200}
201
202impl Drop for Sha256 {
203 fn drop(&mut self) {
204 self.zeroize();
205 }
206}
207
208#[derive(Clone, Zeroize)]
210pub struct Sha384 {
211 state: [u64; 8],
212 buffer: [u8; SHA512_BLOCK_SIZE],
213 buffer_idx: usize,
214 total_bytes: u128, }
216
217impl Drop for Sha384 {
218 fn drop(&mut self) {
219 self.zeroize();
220 }
221}
222
223#[derive(Clone, Zeroize)]
225pub struct Sha512 {
226 state: [u64; 8],
227 buffer: [u8; SHA512_BLOCK_SIZE],
228 buffer_idx: usize,
229 total_bytes: u128,
230}
231
232impl Drop for Sha512 {
233 fn drop(&mut self) {
234 self.zeroize();
235 }
236}
237
238#[derive(Clone, Zeroize)]
240pub struct Sha512_224 {
241 state: [u64; 8],
242 buffer: [u8; SHA512_BLOCK_SIZE],
243 buffer_idx: usize,
244 total_bytes: u128,
245}
246
247impl Drop for Sha512_224 {
248 fn drop(&mut self) {
249 self.zeroize();
250 }
251}
252
253#[derive(Clone, Zeroize)]
255pub struct Sha512_256 {
256 state: [u64; 8],
257 buffer: [u8; SHA512_BLOCK_SIZE],
258 buffer_idx: usize,
259 total_bytes: u128,
260}
261
262impl Drop for Sha512_256 {
263 fn drop(&mut self) {
264 self.zeroize();
265 }
266}
267
268impl Sha256 {
270 fn init_state() -> [u32; 8] {
271 [
272 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab,
273 0x5be0cd19,
274 ]
275 }
276
277 fn new() -> Self {
278 Sha256 {
279 state: Self::init_state(),
280 buffer: [0u8; SHA256_BLOCK_SIZE],
281 buffer_idx: 0,
282 total_bytes: 0,
283 }
284 }
285
286 fn compress(state: &mut [u32; 8], block: &[u8; SHA256_BLOCK_SIZE]) -> Result<()> {
287 let mut w = EphemeralSecret::new([0u32; 64]);
289
290 compiler_fence(Ordering::SeqCst);
292
293 for i in 0..16 {
294 let start = i * 4;
295 validate::max_length("SHA-256 block read", start + 4, SHA256_BLOCK_SIZE)?;
296 w[i] = BigEndian::read_u32(&block[start..]);
297 }
298
299 for i in 16..64 {
300 let s0 = w[i - 15].rotate_right(7) ^ w[i - 15].rotate_right(18) ^ (w[i - 15] >> 3);
301 let s1 = w[i - 2].rotate_right(17) ^ w[i - 2].rotate_right(19) ^ (w[i - 2] >> 10);
302 w[i] = w[i - 16]
303 .wrapping_add(s0)
304 .wrapping_add(w[i - 7])
305 .wrapping_add(s1);
306 }
307
308 let mut working_vars = [
310 state[0], state[1], state[2], state[3], state[4], state[5], state[6], state[7],
311 ];
312 let mut guard = ZeroizeGuard::new(&mut working_vars);
313
314 let mut a = guard[0];
316 let mut b = guard[1];
317 let mut c = guard[2];
318 let mut d = guard[3];
319 let mut e = guard[4];
320 let mut f = guard[5];
321 let mut g = guard[6];
322 let mut h = guard[7];
323
324 for i in 0..64 {
325 let s1 = e.rotate_right(6) ^ e.rotate_right(11) ^ e.rotate_right(25);
326 let ch = (e & f) ^ ((!e) & g);
327 let temp1 = h
328 .wrapping_add(s1)
329 .wrapping_add(ch)
330 .wrapping_add(K256[i])
331 .wrapping_add(w[i]);
332 let s0 = a.rotate_right(2) ^ a.rotate_right(13) ^ a.rotate_right(22);
333 let maj = (a & b) ^ (a & c) ^ (b & c);
334 let temp2 = s0.wrapping_add(maj);
335
336 h = g;
337 g = f;
338 f = e;
339 e = d.wrapping_add(temp1);
340 d = c;
341 c = b;
342 b = a;
343 a = temp1.wrapping_add(temp2);
344 }
345
346 guard[0] = a;
348 guard[1] = b;
349 guard[2] = c;
350 guard[3] = d;
351 guard[4] = e;
352 guard[5] = f;
353 guard[6] = g;
354 guard[7] = h;
355
356 state[0] = state[0].wrapping_add(guard[0]);
358 state[1] = state[1].wrapping_add(guard[1]);
359 state[2] = state[2].wrapping_add(guard[2]);
360 state[3] = state[3].wrapping_add(guard[3]);
361 state[4] = state[4].wrapping_add(guard[4]);
362 state[5] = state[5].wrapping_add(guard[5]);
363 state[6] = state[6].wrapping_add(guard[6]);
364 state[7] = state[7].wrapping_add(guard[7]);
365
366 compiler_fence(Ordering::SeqCst);
368
369 Ok(())
370 }
371
372 fn update_internal(&mut self, mut input: &[u8]) -> Result<()> {
373 while !input.is_empty() {
374 let fill = core::cmp::min(input.len(), SHA256_BLOCK_SIZE - self.buffer_idx);
375 self.buffer[self.buffer_idx..self.buffer_idx + fill].copy_from_slice(&input[..fill]);
376 self.buffer_idx += fill;
377 input = &input[fill..];
378 if self.buffer_idx == SHA256_BLOCK_SIZE {
379 let mut block = [0u8; SHA256_BLOCK_SIZE];
380 block.copy_from_slice(&self.buffer);
381 Self::compress(&mut self.state, &block)?;
382 self.total_bytes += SHA256_BLOCK_SIZE as u64;
383 self.buffer_idx = 0;
384 }
385 }
386 Ok(())
387 }
388
389 fn finalize_internal(&mut self) -> Result<Hash> {
390 self.total_bytes += self.buffer_idx as u64;
391 let bit_len = self.total_bytes * 8;
392
393 let pad_buffer = EphemeralSecret::new([0u8; SHA256_BLOCK_SIZE]);
395
396 self.buffer[self.buffer_idx] = 0x80;
398 if self.buffer_idx >= 56 {
399 for b in &mut self.buffer[self.buffer_idx + 1..] {
400 *b = 0;
401 }
402 let mut block = [0u8; SHA256_BLOCK_SIZE];
403 block.copy_from_slice(&self.buffer);
404 Self::compress(&mut self.state, &block)?;
405 self.buffer = *pad_buffer;
406 } else {
407 for b in &mut self.buffer[self.buffer_idx + 1..56] {
408 *b = 0;
409 }
410 }
411
412 BigEndian::write_u64(&mut self.buffer[56..], bit_len);
413 let mut block = [0u8; SHA256_BLOCK_SIZE];
414 block.copy_from_slice(&self.buffer);
415 Self::compress(&mut self.state, &block)?;
416
417 let mut out = Vec::with_capacity(SHA256_OUTPUT_SIZE);
418 for &word in &self.state {
419 out.extend_from_slice(&word.to_be_bytes());
420 }
421 self.zeroize();
422 Ok(out)
423 }
424}
425
426impl Sha224 {
428 fn init_state() -> [u32; 8] {
429 [
430 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7,
431 0xbefa4fa4,
432 ]
433 }
434
435 fn new() -> Self {
436 Sha224 {
437 state: Self::init_state(),
438 buffer: [0u8; SHA256_BLOCK_SIZE],
439 buffer_idx: 0,
440 total_bytes: 0,
441 }
442 }
443}
444
445impl Sha512 {
447 fn init_state() -> [u64; 8] {
448 [
449 0x6a09e667f3bcc908,
450 0xbb67ae8584caa73b,
451 0x3c6ef372fe94f82b,
452 0xa54ff53a5f1d36f1,
453 0x510e527fade682d1,
454 0x9b05688c2b3e6c1f,
455 0x1f83d9abfb41bd6b,
456 0x5be0cd19137e2179,
457 ]
458 }
459
460 fn new() -> Self {
461 Sha512 {
462 state: Self::init_state(),
463 buffer: [0u8; SHA512_BLOCK_SIZE],
464 buffer_idx: 0,
465 total_bytes: 0,
466 }
467 }
468
469 fn compress(state: &mut [u64; 8], block: &[u8; SHA512_BLOCK_SIZE]) -> Result<()> {
470 let mut w = EphemeralSecret::new([0u64; 80]);
472
473 compiler_fence(Ordering::SeqCst);
475
476 for i in 0..16 {
477 let start = i * 8;
478 validate::max_length("SHA-512 block read", start + 8, SHA512_BLOCK_SIZE)?;
479 w[i] = BigEndian::read_u64(&block[start..]);
480 }
481
482 for i in 16..80 {
483 let s0 = w[i - 15].rotate_right(1) ^ w[i - 15].rotate_right(8) ^ (w[i - 15] >> 7);
484 let s1 = w[i - 2].rotate_right(19) ^ w[i - 2].rotate_right(61) ^ (w[i - 2] >> 6);
485 w[i] = w[i - 16]
486 .wrapping_add(s0)
487 .wrapping_add(w[i - 7])
488 .wrapping_add(s1);
489 }
490
491 let mut working_vars = [
493 state[0], state[1], state[2], state[3], state[4], state[5], state[6], state[7],
494 ];
495 let mut guard = ZeroizeGuard::new(&mut working_vars);
496
497 let mut a = guard[0];
499 let mut b = guard[1];
500 let mut c = guard[2];
501 let mut d = guard[3];
502 let mut e = guard[4];
503 let mut f = guard[5];
504 let mut g = guard[6];
505 let mut h = guard[7];
506
507 for i in 0..80 {
508 let s1 = e.rotate_right(14) ^ e.rotate_right(18) ^ e.rotate_right(41);
509 let ch = (e & f) ^ ((!e) & g);
510 let temp1 = h
511 .wrapping_add(s1)
512 .wrapping_add(ch)
513 .wrapping_add(K512[i])
514 .wrapping_add(w[i]);
515 let s0 = a.rotate_right(28) ^ a.rotate_right(34) ^ a.rotate_right(39);
516 let maj = (a & b) ^ (a & c) ^ (b & c);
517 let temp2 = s0.wrapping_add(maj);
518
519 h = g;
520 g = f;
521 f = e;
522 e = d.wrapping_add(temp1);
523 d = c;
524 c = b;
525 b = a;
526 a = temp1.wrapping_add(temp2);
527 }
528
529 guard[0] = a;
531 guard[1] = b;
532 guard[2] = c;
533 guard[3] = d;
534 guard[4] = e;
535 guard[5] = f;
536 guard[6] = g;
537 guard[7] = h;
538
539 state[0] = state[0].wrapping_add(guard[0]);
541 state[1] = state[1].wrapping_add(guard[1]);
542 state[2] = state[2].wrapping_add(guard[2]);
543 state[3] = state[3].wrapping_add(guard[3]);
544 state[4] = state[4].wrapping_add(guard[4]);
545 state[5] = state[5].wrapping_add(guard[5]);
546 state[6] = state[6].wrapping_add(guard[6]);
547 state[7] = state[7].wrapping_add(guard[7]);
548
549 compiler_fence(Ordering::SeqCst);
551
552 Ok(())
553 }
554
555 fn update_internal_u128(&mut self, mut input: &[u8]) -> Result<()> {
556 while !input.is_empty() {
557 let fill = core::cmp::min(input.len(), SHA512_BLOCK_SIZE - self.buffer_idx);
558 self.buffer[self.buffer_idx..self.buffer_idx + fill].copy_from_slice(&input[..fill]);
559 self.buffer_idx += fill;
560 input = &input[fill..];
561 if self.buffer_idx == SHA512_BLOCK_SIZE {
562 let mut block = [0u8; SHA512_BLOCK_SIZE];
563 block.copy_from_slice(&self.buffer);
564 Self::compress(&mut self.state, &block)?;
565 self.total_bytes = self.total_bytes.wrapping_add(SHA512_BLOCK_SIZE as u128);
566 self.buffer_idx = 0;
567 }
568 }
569 Ok(())
570 }
571
572 fn finalize_internal_u128(&mut self) -> Result<Hash> {
573 self.total_bytes = self.total_bytes.wrapping_add(self.buffer_idx as u128);
574 let bit_len = self.total_bytes.wrapping_mul(8);
575
576 let pad_buffer = EphemeralSecret::new([0u8; SHA512_BLOCK_SIZE]);
578
579 self.buffer[self.buffer_idx] = 0x80;
580 if self.buffer_idx >= SHA512_BLOCK_SIZE - 16 {
581 for b in &mut self.buffer[self.buffer_idx + 1..] {
582 *b = 0;
583 }
584 let mut block = [0u8; SHA512_BLOCK_SIZE];
585 block.copy_from_slice(&self.buffer);
586 Self::compress(&mut self.state, &block)?;
587 self.buffer = *pad_buffer;
588 } else {
589 for b in &mut self.buffer[self.buffer_idx + 1..SHA512_BLOCK_SIZE - 16] {
590 *b = 0;
591 }
592 }
593
594 BigEndian::write_u64(
595 &mut self.buffer[SHA512_BLOCK_SIZE - 16..SHA512_BLOCK_SIZE - 8],
596 0,
597 );
598 BigEndian::write_u64(&mut self.buffer[SHA512_BLOCK_SIZE - 8..], bit_len as u64);
599 let mut block = [0u8; SHA512_BLOCK_SIZE];
600 block.copy_from_slice(&self.buffer);
601 Self::compress(&mut self.state, &block)?;
602
603 let mut out = Vec::with_capacity(SHA512_OUTPUT_SIZE);
604 for &word in &self.state {
605 out.extend_from_slice(&word.to_be_bytes());
606 }
607 self.zeroize();
608 Ok(out)
609 }
610}
611
612impl Sha512_224 {
614 fn init_state() -> [u64; 8] {
615 [
616 0x8c3d37c819544da2,
617 0x73e1996689dcd4d6,
618 0x1dfab7ae32ff9c82,
619 0x679dd514582f9fcf,
620 0x0f6d2b697bd44da8,
621 0x77e36f7304c48942,
622 0x3f9d85a86a1d36c8,
623 0x1112e6ad91d692a1,
624 ]
625 }
626
627 fn new() -> Self {
628 Sha512_224 {
629 state: Self::init_state(),
630 buffer: [0u8; SHA512_BLOCK_SIZE],
631 buffer_idx: 0,
632 total_bytes: 0,
633 }
634 }
635}
636
637impl Sha512_256 {
639 fn init_state() -> [u64; 8] {
640 [
641 0x22312194fc2bf72c,
642 0x9f555fa3c84c64c2,
643 0x2393b86b6f53b151,
644 0x963877195940eabd,
645 0x96283ee2a88effe3,
646 0xbe5e1e2553863992,
647 0x2b0199fc2c85b8aa,
648 0x0eb72ddc81c52ca2,
649 ]
650 }
651
652 fn new() -> Self {
653 Sha512_256 {
654 state: Self::init_state(),
655 buffer: [0u8; SHA512_BLOCK_SIZE],
656 buffer_idx: 0,
657 total_bytes: 0,
658 }
659 }
660}
661
662impl SecureZeroingType for Sha256 {
664 fn zeroed() -> Self {
665 Self::new()
666 }
667}
668
669impl HashFunction for Sha256 {
670 type Algorithm = Sha256Algorithm;
671 type Output = Digest<SHA256_OUTPUT_SIZE>;
672
673 fn new() -> Self {
674 Sha256::new()
675 }
676
677 fn update(&mut self, data: &[u8]) -> Result<&mut Self> {
678 self.update_internal(data)?;
679 Ok(self)
680 }
681
682 fn finalize(&mut self) -> Result<Self::Output> {
683 let hash = self.finalize_internal()?;
684 let mut digest = [0u8; SHA256_OUTPUT_SIZE];
685 digest.copy_from_slice(&hash);
686 Ok(Digest::new(digest))
687 }
688
689 fn output_size() -> usize {
690 SHA256_OUTPUT_SIZE
691 }
692
693 fn block_size() -> usize {
694 SHA256_BLOCK_SIZE
695 }
696
697 fn name() -> String {
698 "SHA-256".to_string()
699 }
700}
701
702impl SecureZeroingType for Sha224 {
703 fn zeroed() -> Self {
704 Self::new()
705 }
706}
707
708impl HashFunction for Sha224 {
709 type Algorithm = Sha224Algorithm;
710 type Output = Digest<SHA224_OUTPUT_SIZE>;
711
712 fn new() -> Self {
713 Sha224::new()
714 }
715
716 fn update(&mut self, data: &[u8]) -> Result<&mut Self> {
717 let mut tmp = Sha256::new();
718 tmp.state = self.state;
719 tmp.buffer = self.buffer;
720 tmp.buffer_idx = self.buffer_idx;
721 tmp.total_bytes = self.total_bytes;
722 tmp.update_internal(data)?;
723 self.state = tmp.state;
724 self.buffer = tmp.buffer;
725 self.buffer_idx = tmp.buffer_idx;
726 self.total_bytes = tmp.total_bytes;
727 Ok(self)
728 }
729
730 fn finalize(&mut self) -> Result<Self::Output> {
731 let mut tmp = Sha256::new();
732 tmp.state = self.state;
733 tmp.buffer = self.buffer;
734 tmp.buffer_idx = self.buffer_idx;
735 tmp.total_bytes = self.total_bytes;
736 let full = tmp.finalize_internal()?;
737 let mut digest = [0u8; SHA224_OUTPUT_SIZE];
738 digest.copy_from_slice(&full[..SHA224_OUTPUT_SIZE]);
739 Ok(Digest::new(digest))
740 }
741
742 fn output_size() -> usize {
743 SHA224_OUTPUT_SIZE
744 }
745
746 fn block_size() -> usize {
747 SHA256_BLOCK_SIZE
748 }
749
750 fn name() -> String {
751 "SHA-224".to_string()
752 }
753}
754
755impl SecureZeroingType for Sha384 {
756 fn zeroed() -> Self {
757 Sha384 {
758 state: [
759 0xcbbb9d5dc1059ed8,
760 0x629a292a367cd507,
761 0x9159015a3070dd17,
762 0x152fecd8f70e5939,
763 0x67332667ffc00b31,
764 0x8eb44a8768581511,
765 0xdb0c2e0d64f98fa7,
766 0x47b5481dbefa4fa4,
767 ],
768 buffer: [0u8; SHA512_BLOCK_SIZE],
769 buffer_idx: 0,
770 total_bytes: 0,
771 }
772 }
773}
774
775impl HashFunction for Sha384 {
776 type Algorithm = Sha384Algorithm;
777 type Output = Digest<SHA384_OUTPUT_SIZE>;
778
779 fn new() -> Self {
780 SecureZeroingType::zeroed()
781 }
782
783 fn update(&mut self, data: &[u8]) -> Result<&mut Self> {
784 let mut tmp = Sha512::new();
785 tmp.state = self.state;
786 tmp.buffer = self.buffer;
787 tmp.buffer_idx = self.buffer_idx;
788 tmp.total_bytes = self.total_bytes;
789 tmp.update_internal_u128(data)?;
790 self.state = tmp.state;
791 self.buffer = tmp.buffer;
792 self.buffer_idx = tmp.buffer_idx;
793 self.total_bytes = tmp.total_bytes;
794 Ok(self)
795 }
796
797 fn finalize(&mut self) -> Result<Self::Output> {
798 let mut tmp = Sha512::new();
799 tmp.state = self.state;
800 tmp.buffer = self.buffer;
801 tmp.buffer_idx = self.buffer_idx;
802 tmp.total_bytes = self.total_bytes;
803 let full = tmp.finalize_internal_u128()?;
804 let mut digest = [0u8; SHA384_OUTPUT_SIZE];
805 digest.copy_from_slice(&full[..SHA384_OUTPUT_SIZE]);
806 Ok(Digest::new(digest))
807 }
808
809 fn output_size() -> usize {
810 SHA384_OUTPUT_SIZE
811 }
812
813 fn block_size() -> usize {
814 SHA512_BLOCK_SIZE
815 }
816
817 fn name() -> String {
818 "SHA-384".to_string()
819 }
820}
821
822impl SecureZeroingType for Sha512 {
823 fn zeroed() -> Self {
824 Self::new()
825 }
826}
827
828impl HashFunction for Sha512 {
829 type Algorithm = Sha512Algorithm;
830 type Output = Digest<SHA512_OUTPUT_SIZE>;
831
832 fn new() -> Self {
833 Sha512::new()
834 }
835
836 fn update(&mut self, data: &[u8]) -> Result<&mut Self> {
837 self.update_internal_u128(data)?;
838 Ok(self)
839 }
840
841 fn finalize(&mut self) -> Result<Self::Output> {
842 let hash = self.finalize_internal_u128()?;
843 let mut digest = [0u8; SHA512_OUTPUT_SIZE];
844 digest.copy_from_slice(&hash);
845 Ok(Digest::new(digest))
846 }
847
848 fn output_size() -> usize {
849 SHA512_OUTPUT_SIZE
850 }
851
852 fn block_size() -> usize {
853 SHA512_BLOCK_SIZE
854 }
855
856 fn name() -> String {
857 "SHA-512".to_string()
858 }
859}
860
861impl SecureZeroingType for Sha512_224 {
862 fn zeroed() -> Self {
863 Self::new()
864 }
865}
866
867impl HashFunction for Sha512_224 {
868 type Algorithm = Sha512_224Algorithm;
869 type Output = Digest<SHA224_OUTPUT_SIZE>;
870
871 fn new() -> Self {
872 Sha512_224::new()
873 }
874
875 fn update(&mut self, data: &[u8]) -> Result<&mut Self> {
876 let mut tmp = Sha512::new();
877 tmp.state = self.state;
878 tmp.buffer = self.buffer;
879 tmp.buffer_idx = self.buffer_idx;
880 tmp.total_bytes = self.total_bytes;
881 tmp.update_internal_u128(data)?;
882 self.state = tmp.state;
883 self.buffer = tmp.buffer;
884 self.buffer_idx = tmp.buffer_idx;
885 self.total_bytes = tmp.total_bytes;
886 Ok(self)
887 }
888
889 fn finalize(&mut self) -> Result<Self::Output> {
890 let mut tmp = Sha512::new();
891 tmp.state = self.state;
892 tmp.buffer = self.buffer;
893 tmp.buffer_idx = self.buffer_idx;
894 tmp.total_bytes = self.total_bytes;
895 let full = tmp.finalize_internal_u128()?;
896 let mut digest = [0u8; SHA224_OUTPUT_SIZE];
897 digest.copy_from_slice(&full[..SHA224_OUTPUT_SIZE]);
898 Ok(Digest::new(digest))
899 }
900
901 fn output_size() -> usize {
902 SHA224_OUTPUT_SIZE
903 }
904
905 fn block_size() -> usize {
906 SHA512_BLOCK_SIZE
907 }
908
909 fn name() -> String {
910 "SHA-512/224".to_string()
911 }
912}
913
914impl SecureZeroingType for Sha512_256 {
915 fn zeroed() -> Self {
916 Self::new()
917 }
918}
919
920impl HashFunction for Sha512_256 {
921 type Algorithm = Sha512_256Algorithm;
922 type Output = Digest<SHA256_OUTPUT_SIZE>;
923
924 fn new() -> Self {
925 Sha512_256::new()
926 }
927
928 fn update(&mut self, data: &[u8]) -> Result<&mut Self> {
929 let mut tmp = Sha512::new();
930 tmp.state = self.state;
931 tmp.buffer = self.buffer;
932 tmp.buffer_idx = self.buffer_idx;
933 tmp.total_bytes = self.total_bytes;
934 tmp.update_internal_u128(data)?;
935 self.state = tmp.state;
936 self.buffer = tmp.buffer;
937 self.buffer_idx = tmp.buffer_idx;
938 self.total_bytes = tmp.total_bytes;
939 Ok(self)
940 }
941
942 fn finalize(&mut self) -> Result<Self::Output> {
943 let mut tmp = Sha512::new();
944 tmp.state = self.state;
945 tmp.buffer = self.buffer;
946 tmp.buffer_idx = self.buffer_idx;
947 tmp.total_bytes = self.total_bytes;
948 let full = tmp.finalize_internal_u128()?;
949 let mut digest = [0u8; SHA256_OUTPUT_SIZE];
950 digest.copy_from_slice(&full[..SHA256_OUTPUT_SIZE]);
951 Ok(Digest::new(digest))
952 }
953
954 fn output_size() -> usize {
955 SHA256_OUTPUT_SIZE
956 }
957
958 fn block_size() -> usize {
959 SHA512_BLOCK_SIZE
960 }
961
962 fn name() -> String {
963 "SHA-512/256".to_string()
964 }
965}
966
967#[cfg(test)]
968mod tests;