Coverage Report

Created: 2025-07-02 06:49

/rust/registry/src/index.crates.io-6f17d22bba15001f/ring-0.17.14/src/digest/sha1.rs
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2015-2025 Brian Smith.
2
// Copyright 2016 Simon Sapin.
3
//
4
// Permission to use, copy, modify, and/or distribute this software for any
5
// purpose with or without fee is hereby granted, provided that the above
6
// copyright notice and this permission notice appear in all copies.
7
//
8
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
16
use super::{
17
    sha2::{
18
        fallback::{ch, maj, Word},
19
        State32,
20
    },
21
    BlockLen, OutputLen,
22
};
23
use crate::polyfill::slice::{self, AsChunks};
24
use core::{mem::size_of, num::Wrapping};
25
26
pub(super) const BLOCK_LEN: BlockLen = BlockLen::_512;
27
pub const CHAINING_LEN: usize = 160 / 8;
28
pub(super) const OUTPUT_LEN: OutputLen = OutputLen::_160;
29
const CHAINING_WORDS: usize = CHAINING_LEN / 4;
30
31
type W32 = Wrapping<u32>;
32
33
// FIPS 180-4 4.1.1
34
#[inline]
35
0
fn parity(x: W32, y: W32, z: W32) -> W32 {
36
0
    x ^ y ^ z
37
0
}
38
39
type State = [W32; CHAINING_WORDS];
40
const ROUNDS: usize = 80;
41
42
0
pub fn sha1_block_data_order(state: &mut State32, data: AsChunks<u8, { BLOCK_LEN.into() }>) {
43
0
    // The unwrap won't fail because `CHAINING_WORDS` is smaller than the
44
0
    // length.
45
0
    let state: &mut State = (&mut state[..CHAINING_WORDS]).try_into().unwrap();
46
0
    // SAFETY: The caller guarantees that this is called with data pointing to `num`
47
0
    // `BLOCK_LEN`-long blocks.
48
0
    *state = block_data_order(*state, data)
49
0
}
50
51
#[inline]
52
#[rustfmt::skip]
53
0
fn block_data_order(
54
0
    mut H: [W32; CHAINING_WORDS],
55
0
    M: AsChunks<u8, { BLOCK_LEN.into() }>,
56
0
) -> [W32; CHAINING_WORDS]
57
0
{
58
0
    for M in M {
59
0
        let (M, remainder): (AsChunks<u8, {size_of::<W32>()}>, &[u8]) = slice::as_chunks(M);
60
0
        debug_assert!(remainder.is_empty());
61
62
        // FIPS 180-4 6.1.2 Step 1
63
0
        let mut W: [W32; ROUNDS] = [W32::ZERO; ROUNDS];
64
0
        W.iter_mut().zip(M).for_each(|(Wt, Mt)| {
65
0
            *Wt = W32::from_be_bytes(*Mt);
66
0
        });
67
0
        for t in 16..ROUNDS {
68
0
            let wt = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
69
0
            W[t] = rotl(wt, 1);
70
0
        }
71
72
        // FIPS 180-4 6.1.2 Step 2
73
0
        let [a, b, c, d, e] = H;
74
0
75
0
        // FIPS 180-4 6.1.2 Step 3 with constants and functions from FIPS 180-4 {4.1.1, 4.2.1}
76
0
        let (a, b, c, d, e) = step3(a, b, c, d, e, &W, 0, Wrapping(0x5a827999), ch);
77
0
        let (a, b, c, d, e) = step3(a, b, c, d, e, &W, 20, Wrapping(0x6ed9eba1), parity);
78
0
        let (a, b, c, d, e) = step3(a, b, c, d, e, &W, 40, Wrapping(0x8f1bbcdc), maj);
79
0
        let (a, b, c, d, e) = step3(a, b, c, d, e, &W, 60, Wrapping(0xca62c1d6), parity);
80
0
81
0
        // FIPS 180-4 6.1.2 Step 4
82
0
        H[0] += a;
83
0
        H[1] += b;
84
0
        H[2] += c;
85
0
        H[3] += d;
86
0
        H[4] += e;
87
    }
88
89
0
    H
90
0
}
91
92
#[inline(always)]
93
0
fn step3(
94
0
    mut a: W32,
95
0
    mut b: W32,
96
0
    mut c: W32,
97
0
    mut d: W32,
98
0
    mut e: W32,
99
0
    W: &[W32; 80],
100
0
    t: usize,
101
0
    k: W32,
102
0
    f: impl Fn(W32, W32, W32) -> W32,
103
0
) -> (W32, W32, W32, W32, W32) {
104
0
    let W = &W[t..(t + 20)];
105
0
    for W_t in W.iter() {
106
0
        let T = rotl(a, 5) + f(b, c, d) + e + k + W_t;
107
0
        e = d;
108
0
        d = c;
109
0
        c = rotl(b, 30);
110
0
        b = a;
111
0
        a = T;
112
0
    }
113
0
    (a, b, c, d, e)
114
0
}
Unexecuted instantiation: ring::digest::sha1::step3::<ring::digest::sha2::fallback::ch<core::num::wrapping::Wrapping<u32>>>
Unexecuted instantiation: ring::digest::sha1::step3::<ring::digest::sha2::fallback::maj<core::num::wrapping::Wrapping<u32>>>
Unexecuted instantiation: ring::digest::sha1::step3::<ring::digest::sha1::parity>
115
116
#[inline(always)]
117
0
fn rotl(x: W32, n: u32) -> W32 {
118
0
    Wrapping(x.0.rotate_left(n))
119
0
}