Coverage Report

Created: 2026-05-30 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/spdm-rs/external/ring/src/digest/sha2/fallback.rs
Line
Count
Source
1
// Copyright 2019-2025 Brian Smith.
2
//
3
// Permission to use, copy, modify, and/or distribute this software for any
4
// purpose with or without fee is hereby granted, provided that the above
5
// copyright notice and this permission notice appear in all copies.
6
//
7
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15
use super::CHAINING_WORDS;
16
use crate::polyfill::slice::{self, AsChunks};
17
use core::{
18
    num::Wrapping,
19
    ops::{Add, AddAssign, BitAnd, BitOr, BitXor, Not, Shr},
20
};
21
22
#[cfg_attr(
23
    any(
24
        all(target_arch = "aarch64", target_endian = "little"),
25
        all(target_arch = "arm", target_endian = "little"),
26
        target_arch = "x86_64"
27
    ),
28
    allow(dead_code)
29
)]
30
#[inline]
31
pub(super) fn block_data_order<S: Sha2, const BLOCK_LEN: usize, const BYTES_LEN: usize>(
32
    mut H: [S; CHAINING_WORDS],
33
    M: AsChunks<u8, BLOCK_LEN>,
34
) -> [S; CHAINING_WORDS]
35
where
36
    for<'a> &'a S::InputBytes: From<&'a [u8; BYTES_LEN]>,
37
{
38
    for M in M {
39
        let (M, remainder): (AsChunks<u8, BYTES_LEN>, &[u8]) = slice::as_chunks(M);
40
        debug_assert!(remainder.is_empty());
41
42
        // FIPS 180-4 {6.2.2, 6.4.2} Step 1
43
        //
44
        // TODO(MSRV): Use `let W: [S::from(0); S::ROUNDS]` instead; depends on
45
        // https://github.com/rust-lang/rust/issues/43408.
46
        let mut W = S::zero_w();
47
        let W = W.as_mut();
48
        W.iter_mut().zip(M).for_each(|(Wt, Mt)| {
49
            let Mt: &S::InputBytes = Mt.into();
50
            *Wt = S::from_be_bytes(*Mt);
51
        });
52
        for t in 16..S::ROUNDS {
53
            W[t] = sigma_1(W[t - 2]) + W[t - 7] + sigma_0(W[t - 15]) + W[t - 16]
54
        }
55
56
        // FIPS 180-4 {6.2.2, 6.4.2} Step 2
57
        let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h] = H;
58
59
        // FIPS 180-4 {6.2.2, 6.4.2} Step 3
60
        for (Kt, Wt) in S::K.as_ref().iter().zip(W.iter()) {
61
            let T1 = h + SIGMA_1(e) + ch(e, f, g) + *Kt + *Wt;
62
            let T2 = SIGMA_0(a) + maj(a, b, c);
63
            h = g;
64
            g = f;
65
            f = e;
66
            e = d + T1;
67
            d = c;
68
            c = b;
69
            b = a;
70
            a = T1 + T2;
71
        }
72
73
        // FIPS 180-4 {6.2.2, 6.4.2} Step 4
74
        H[0] += a;
75
        H[1] += b;
76
        H[2] += c;
77
        H[3] += d;
78
        H[4] += e;
79
        H[5] += f;
80
        H[6] += g;
81
        H[7] += h;
82
    }
83
84
    H
85
}
86
87
// FIPS 180-4 {4.1.1, 4.1.2, 4.1.3}
88
#[inline(always)]
89
0
pub(in super::super) fn ch<W: Word>(x: W, y: W, z: W) -> W {
90
0
    (x & y) | (!x & z)
91
0
}
92
93
// FIPS 180-4 {4.1.1, 4.1.2, 4.1.3}
94
#[inline(always)]
95
0
pub(in super::super) fn maj<W: Word>(x: W, y: W, z: W) -> W {
96
0
    (x & y) | (x & z) | (y & z)
97
0
}
98
99
// FIPS 180-4 {4.1.2, 4.1.3}
100
#[inline(always)]
101
fn SIGMA_0<S: Sha2>(x: S) -> S {
102
    x.rotr(S::BIG_SIGMA_0.0) ^ x.rotr(S::BIG_SIGMA_0.1) ^ x.rotr(S::BIG_SIGMA_0.2)
103
}
104
105
// FIPS 180-4 {4.1.2, 4.1.3}
106
#[inline(always)]
107
fn SIGMA_1<S: Sha2>(x: S) -> S {
108
    x.rotr(S::BIG_SIGMA_1.0) ^ x.rotr(S::BIG_SIGMA_1.1) ^ x.rotr(S::BIG_SIGMA_1.2)
109
}
110
111
// FIPS 180-4 {4.1.2, 4.1.3}
112
#[inline(always)]
113
fn sigma_0<S: Sha2>(x: S) -> S {
114
    x.rotr(S::SMALL_SIGMA_0.0) ^ x.rotr(S::SMALL_SIGMA_0.1) ^ (x >> S::SMALL_SIGMA_0.2)
115
}
116
117
// FIPS 180-4 {4.1.2, 4.1.3}
118
#[inline(always)]
119
fn sigma_1<S: Sha2>(x: S) -> S {
120
    x.rotr(S::SMALL_SIGMA_1.0) ^ x.rotr(S::SMALL_SIGMA_1.1) ^ (x >> S::SMALL_SIGMA_1.2)
121
}
122
123
// Commonality between SHA-1 and SHA-2 words.
124
pub(in super::super) trait Word:
125
    'static
126
    + Sized
127
    + Copy
128
    + Add<Output = Self>
129
    + AddAssign
130
    + BitAnd<Output = Self>
131
    + BitOr<Output = Self>
132
    + Not<Output = Self>
133
{
134
    const ZERO: Self;
135
136
    type InputBytes: Copy;
137
138
    fn from_be_bytes(input: Self::InputBytes) -> Self;
139
140
    fn rotr(self, count: u32) -> Self;
141
}
142
143
/// A SHA-2 input word.
144
pub(super) trait Sha2: Word + BitXor<Output = Self> + Shr<usize, Output = Self> {
145
    const BIG_SIGMA_0: (u32, u32, u32);
146
    const BIG_SIGMA_1: (u32, u32, u32);
147
    const SMALL_SIGMA_0: (u32, u32, usize);
148
    const SMALL_SIGMA_1: (u32, u32, usize);
149
150
    const ROUNDS: usize;
151
152
    type W: AsRef<[Self]> + AsMut<[Self]>;
153
    fn zero_w() -> Self::W;
154
155
    const K: &'static Self::W;
156
}
157
158
impl Word for Wrapping<u32> {
159
    const ZERO: Self = Self(0);
160
    type InputBytes = [u8; 4];
161
162
    #[inline(always)]
163
0
    fn from_be_bytes(input: Self::InputBytes) -> Self {
164
0
        Self(u32::from_be_bytes(input))
165
0
    }
166
167
    #[inline(always)]
168
    fn rotr(self, count: u32) -> Self {
169
        Self(self.0.rotate_right(count))
170
    }
171
}
172
173
// SHA-256
174
impl Sha2 for Wrapping<u32> {
175
    // FIPS 180-4 4.1.2
176
    const BIG_SIGMA_0: (u32, u32, u32) = (2, 13, 22);
177
    const BIG_SIGMA_1: (u32, u32, u32) = (6, 11, 25);
178
    const SMALL_SIGMA_0: (u32, u32, usize) = (7, 18, 3);
179
    const SMALL_SIGMA_1: (u32, u32, usize) = (17, 19, 10);
180
181
    // FIPS 180-4 {6.2.2} Step 1
182
    const ROUNDS: usize = 64;
183
184
    type W = [Self; Self::ROUNDS];
185
0
    fn zero_w() -> Self::W {
186
0
        [Self::ZERO; Self::ROUNDS]
187
0
    }
188
189
    // FIPS 180-4 4.2.2
190
    const K: &'static Self::W = &[
191
        Self(0x428a2f98),
192
        Self(0x71374491),
193
        Self(0xb5c0fbcf),
194
        Self(0xe9b5dba5),
195
        Self(0x3956c25b),
196
        Self(0x59f111f1),
197
        Self(0x923f82a4),
198
        Self(0xab1c5ed5),
199
        Self(0xd807aa98),
200
        Self(0x12835b01),
201
        Self(0x243185be),
202
        Self(0x550c7dc3),
203
        Self(0x72be5d74),
204
        Self(0x80deb1fe),
205
        Self(0x9bdc06a7),
206
        Self(0xc19bf174),
207
        Self(0xe49b69c1),
208
        Self(0xefbe4786),
209
        Self(0x0fc19dc6),
210
        Self(0x240ca1cc),
211
        Self(0x2de92c6f),
212
        Self(0x4a7484aa),
213
        Self(0x5cb0a9dc),
214
        Self(0x76f988da),
215
        Self(0x983e5152),
216
        Self(0xa831c66d),
217
        Self(0xb00327c8),
218
        Self(0xbf597fc7),
219
        Self(0xc6e00bf3),
220
        Self(0xd5a79147),
221
        Self(0x06ca6351),
222
        Self(0x14292967),
223
        Self(0x27b70a85),
224
        Self(0x2e1b2138),
225
        Self(0x4d2c6dfc),
226
        Self(0x53380d13),
227
        Self(0x650a7354),
228
        Self(0x766a0abb),
229
        Self(0x81c2c92e),
230
        Self(0x92722c85),
231
        Self(0xa2bfe8a1),
232
        Self(0xa81a664b),
233
        Self(0xc24b8b70),
234
        Self(0xc76c51a3),
235
        Self(0xd192e819),
236
        Self(0xd6990624),
237
        Self(0xf40e3585),
238
        Self(0x106aa070),
239
        Self(0x19a4c116),
240
        Self(0x1e376c08),
241
        Self(0x2748774c),
242
        Self(0x34b0bcb5),
243
        Self(0x391c0cb3),
244
        Self(0x4ed8aa4a),
245
        Self(0x5b9cca4f),
246
        Self(0x682e6ff3),
247
        Self(0x748f82ee),
248
        Self(0x78a5636f),
249
        Self(0x84c87814),
250
        Self(0x8cc70208),
251
        Self(0x90befffa),
252
        Self(0xa4506ceb),
253
        Self(0xbef9a3f7),
254
        Self(0xc67178f2),
255
    ];
256
}
257
258
impl Word for Wrapping<u64> {
259
    const ZERO: Self = Self(0);
260
    type InputBytes = [u8; 8];
261
262
    #[inline(always)]
263
    fn from_be_bytes(input: Self::InputBytes) -> Self {
264
        Self(u64::from_be_bytes(input))
265
    }
266
267
    #[inline(always)]
268
    fn rotr(self, count: u32) -> Self {
269
        Self(self.0.rotate_right(count))
270
    }
271
}
272
273
// SHA-384 and SHA-512
274
impl Sha2 for Wrapping<u64> {
275
    // FIPS 180-4 4.1.3
276
    const BIG_SIGMA_0: (u32, u32, u32) = (28, 34, 39);
277
    const BIG_SIGMA_1: (u32, u32, u32) = (14, 18, 41);
278
    const SMALL_SIGMA_0: (u32, u32, usize) = (1, 8, 7);
279
    const SMALL_SIGMA_1: (u32, u32, usize) = (19, 61, 6);
280
281
    // FIPS 180-4 {6.4.2} Step 1
282
    const ROUNDS: usize = 80;
283
284
    type W = [Self; Self::ROUNDS];
285
0
    fn zero_w() -> Self::W {
286
0
        [Self::ZERO; Self::ROUNDS]
287
0
    }
288
289
    // FIPS 180-4 4.2.3
290
    const K: &'static Self::W = &[
291
        Self(0x428a2f98d728ae22),
292
        Self(0x7137449123ef65cd),
293
        Self(0xb5c0fbcfec4d3b2f),
294
        Self(0xe9b5dba58189dbbc),
295
        Self(0x3956c25bf348b538),
296
        Self(0x59f111f1b605d019),
297
        Self(0x923f82a4af194f9b),
298
        Self(0xab1c5ed5da6d8118),
299
        Self(0xd807aa98a3030242),
300
        Self(0x12835b0145706fbe),
301
        Self(0x243185be4ee4b28c),
302
        Self(0x550c7dc3d5ffb4e2),
303
        Self(0x72be5d74f27b896f),
304
        Self(0x80deb1fe3b1696b1),
305
        Self(0x9bdc06a725c71235),
306
        Self(0xc19bf174cf692694),
307
        Self(0xe49b69c19ef14ad2),
308
        Self(0xefbe4786384f25e3),
309
        Self(0x0fc19dc68b8cd5b5),
310
        Self(0x240ca1cc77ac9c65),
311
        Self(0x2de92c6f592b0275),
312
        Self(0x4a7484aa6ea6e483),
313
        Self(0x5cb0a9dcbd41fbd4),
314
        Self(0x76f988da831153b5),
315
        Self(0x983e5152ee66dfab),
316
        Self(0xa831c66d2db43210),
317
        Self(0xb00327c898fb213f),
318
        Self(0xbf597fc7beef0ee4),
319
        Self(0xc6e00bf33da88fc2),
320
        Self(0xd5a79147930aa725),
321
        Self(0x06ca6351e003826f),
322
        Self(0x142929670a0e6e70),
323
        Self(0x27b70a8546d22ffc),
324
        Self(0x2e1b21385c26c926),
325
        Self(0x4d2c6dfc5ac42aed),
326
        Self(0x53380d139d95b3df),
327
        Self(0x650a73548baf63de),
328
        Self(0x766a0abb3c77b2a8),
329
        Self(0x81c2c92e47edaee6),
330
        Self(0x92722c851482353b),
331
        Self(0xa2bfe8a14cf10364),
332
        Self(0xa81a664bbc423001),
333
        Self(0xc24b8b70d0f89791),
334
        Self(0xc76c51a30654be30),
335
        Self(0xd192e819d6ef5218),
336
        Self(0xd69906245565a910),
337
        Self(0xf40e35855771202a),
338
        Self(0x106aa07032bbd1b8),
339
        Self(0x19a4c116b8d2d0c8),
340
        Self(0x1e376c085141ab53),
341
        Self(0x2748774cdf8eeb99),
342
        Self(0x34b0bcb5e19b48a8),
343
        Self(0x391c0cb3c5c95a63),
344
        Self(0x4ed8aa4ae3418acb),
345
        Self(0x5b9cca4f7763e373),
346
        Self(0x682e6ff3d6b2b8a3),
347
        Self(0x748f82ee5defb2fc),
348
        Self(0x78a5636f43172f60),
349
        Self(0x84c87814a1f0ab72),
350
        Self(0x8cc702081a6439ec),
351
        Self(0x90befffa23631e28),
352
        Self(0xa4506cebde82bde9),
353
        Self(0xbef9a3f7b2c67915),
354
        Self(0xc67178f2e372532b),
355
        Self(0xca273eceea26619c),
356
        Self(0xd186b8c721c0c207),
357
        Self(0xeada7dd6cde0eb1e),
358
        Self(0xf57d4f7fee6ed178),
359
        Self(0x06f067aa72176fba),
360
        Self(0x0a637dc5a2c898a6),
361
        Self(0x113f9804bef90dae),
362
        Self(0x1b710b35131c471b),
363
        Self(0x28db77f523047d84),
364
        Self(0x32caab7b40c72493),
365
        Self(0x3c9ebe0a15c9bebc),
366
        Self(0x431d67c49c100d4c),
367
        Self(0x4cc5d4becb3e42b6),
368
        Self(0x597f299cfc657e2a),
369
        Self(0x5fcb6fab3ad6faec),
370
        Self(0x6c44198c4a475817),
371
    ];
372
}