Coverage Report

Created: 2025-10-10 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/hmac-0.12.1/src/optim.rs
Line
Count
Source
1
use super::{get_der_key, IPAD, OPAD};
2
use core::{fmt, slice};
3
#[cfg(feature = "reset")]
4
use digest::Reset;
5
use digest::{
6
    block_buffer::Eager,
7
    core_api::{
8
        AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreProxy, CoreWrapper,
9
        FixedOutputCore, OutputSizeUser, UpdateCore,
10
    },
11
    crypto_common::{Key, KeySizeUser},
12
    generic_array::typenum::{IsLess, Le, NonZero, U256},
13
    HashMarker, InvalidLength, KeyInit, MacMarker, Output,
14
};
15
16
/// Generic HMAC instance.
17
pub type Hmac<D> = CoreWrapper<HmacCore<D>>;
18
19
/// Generic core HMAC instance, which operates over blocks.
20
pub struct HmacCore<D>
21
where
22
    D: CoreProxy,
23
    D::Core: HashMarker
24
        + UpdateCore
25
        + FixedOutputCore
26
        + BufferKindUser<BufferKind = Eager>
27
        + Default
28
        + Clone,
29
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
30
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
31
{
32
    digest: D::Core,
33
    opad_digest: D::Core,
34
    #[cfg(feature = "reset")]
35
    ipad_digest: D::Core,
36
}
37
38
impl<D> Clone for HmacCore<D>
39
where
40
    D: CoreProxy,
41
    D::Core: HashMarker
42
        + UpdateCore
43
        + FixedOutputCore
44
        + BufferKindUser<BufferKind = Eager>
45
        + Default
46
        + Clone,
47
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
48
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
49
{
50
0
    fn clone(&self) -> Self {
51
0
        Self {
52
0
            digest: self.digest.clone(),
53
0
            opad_digest: self.opad_digest.clone(),
54
0
            #[cfg(feature = "reset")]
55
0
            ipad_digest: self.ipad_digest.clone(),
56
0
        }
57
0
    }
58
}
59
60
impl<D> MacMarker for HmacCore<D>
61
where
62
    D: CoreProxy,
63
    D::Core: HashMarker
64
        + UpdateCore
65
        + FixedOutputCore
66
        + BufferKindUser<BufferKind = Eager>
67
        + Default
68
        + Clone,
69
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
70
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
71
{
72
}
73
74
impl<D> BufferKindUser for HmacCore<D>
75
where
76
    D: CoreProxy,
77
    D::Core: HashMarker
78
        + UpdateCore
79
        + FixedOutputCore
80
        + BufferKindUser<BufferKind = Eager>
81
        + Default
82
        + Clone,
83
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
84
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
85
{
86
    type BufferKind = Eager;
87
}
88
89
impl<D> KeySizeUser for HmacCore<D>
90
where
91
    D: CoreProxy,
92
    D::Core: HashMarker
93
        + UpdateCore
94
        + FixedOutputCore
95
        + BufferKindUser<BufferKind = Eager>
96
        + Default
97
        + Clone,
98
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
99
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
100
{
101
    type KeySize = <<D as CoreProxy>::Core as BlockSizeUser>::BlockSize;
102
}
103
104
impl<D> BlockSizeUser for HmacCore<D>
105
where
106
    D: CoreProxy,
107
    D::Core: HashMarker
108
        + UpdateCore
109
        + FixedOutputCore
110
        + BufferKindUser<BufferKind = Eager>
111
        + Default
112
        + Clone,
113
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
114
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
115
{
116
    type BlockSize = <<D as CoreProxy>::Core as BlockSizeUser>::BlockSize;
117
}
118
119
impl<D> OutputSizeUser for HmacCore<D>
120
where
121
    D: CoreProxy,
122
    D::Core: HashMarker
123
        + UpdateCore
124
        + FixedOutputCore
125
        + BufferKindUser<BufferKind = Eager>
126
        + Default
127
        + Clone,
128
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
129
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
130
{
131
    type OutputSize = <<D as CoreProxy>::Core as OutputSizeUser>::OutputSize;
132
}
133
134
impl<D> KeyInit for HmacCore<D>
135
where
136
    D: CoreProxy,
137
    D::Core: HashMarker
138
        + UpdateCore
139
        + FixedOutputCore
140
        + BufferKindUser<BufferKind = Eager>
141
        + Default
142
        + Clone,
143
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
144
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
145
{
146
    #[inline(always)]
147
    fn new(key: &Key<Self>) -> Self {
148
        Self::new_from_slice(key.as_slice()).unwrap()
149
    }
150
151
    #[inline(always)]
152
0
    fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
153
0
        let mut buf = get_der_key::<CoreWrapper<D::Core>>(key);
154
0
        for b in buf.iter_mut() {
155
0
            *b ^= IPAD;
156
0
        }
157
0
        let mut digest = D::Core::default();
158
0
        digest.update_blocks(slice::from_ref(&buf));
159
160
0
        for b in buf.iter_mut() {
161
0
            *b ^= IPAD ^ OPAD;
162
0
        }
163
164
0
        let mut opad_digest = D::Core::default();
165
0
        opad_digest.update_blocks(slice::from_ref(&buf));
166
167
0
        Ok(Self {
168
0
            #[cfg(feature = "reset")]
169
0
            ipad_digest: digest.clone(),
170
0
            opad_digest,
171
0
            digest,
172
0
        })
173
0
    }
174
}
175
176
impl<D> UpdateCore for HmacCore<D>
177
where
178
    D: CoreProxy,
179
    D::Core: HashMarker
180
        + UpdateCore
181
        + FixedOutputCore
182
        + BufferKindUser<BufferKind = Eager>
183
        + Default
184
        + Clone,
185
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
186
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
187
{
188
    #[inline(always)]
189
0
    fn update_blocks(&mut self, blocks: &[Block<Self>]) {
190
0
        self.digest.update_blocks(blocks);
191
0
    }
192
}
193
194
impl<D> FixedOutputCore for HmacCore<D>
195
where
196
    D: CoreProxy,
197
    D::Core: HashMarker
198
        + UpdateCore
199
        + FixedOutputCore
200
        + BufferKindUser<BufferKind = Eager>
201
        + Default
202
        + Clone,
203
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
204
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
205
{
206
    #[inline(always)]
207
0
    fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
208
0
        let mut hash = Output::<D::Core>::default();
209
0
        self.digest.finalize_fixed_core(buffer, &mut hash);
210
        // finalize_fixed_core should reset the buffer as well, but
211
        // to be extra safe we reset it explicitly again.
212
0
        buffer.reset();
213
        #[cfg(not(feature = "reset"))]
214
        let h = &mut self.opad_digest;
215
        #[cfg(feature = "reset")]
216
0
        let mut h = self.opad_digest.clone();
217
0
        buffer.digest_blocks(&hash, |b| h.update_blocks(b));
218
0
        h.finalize_fixed_core(buffer, out);
219
0
    }
220
}
221
222
#[cfg(feature = "reset")]
223
#[cfg_attr(docsrs, doc(cfg(feature = "reset")))]
224
impl<D> Reset for HmacCore<D>
225
where
226
    D: CoreProxy,
227
    D::Core: HashMarker
228
        + UpdateCore
229
        + FixedOutputCore
230
        + BufferKindUser<BufferKind = Eager>
231
        + Default
232
        + Clone,
233
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
234
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
235
{
236
    #[inline(always)]
237
0
    fn reset(&mut self) {
238
0
        self.digest = self.ipad_digest.clone();
239
0
    }
240
}
241
242
impl<D> AlgorithmName for HmacCore<D>
243
where
244
    D: CoreProxy,
245
    D::Core: HashMarker
246
        + AlgorithmName
247
        + UpdateCore
248
        + FixedOutputCore
249
        + BufferKindUser<BufferKind = Eager>
250
        + Default
251
        + Clone,
252
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
253
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
254
{
255
    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
256
        f.write_str("Hmac<")?;
257
        <D::Core as AlgorithmName>::write_alg_name(f)?;
258
        f.write_str(">")
259
    }
260
}
261
262
impl<D> fmt::Debug for HmacCore<D>
263
where
264
    D: CoreProxy,
265
    D::Core: HashMarker
266
        + AlgorithmName
267
        + UpdateCore
268
        + FixedOutputCore
269
        + BufferKindUser<BufferKind = Eager>
270
        + Default
271
        + Clone,
272
    <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
273
    Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
274
{
275
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
276
        f.write_str("HmacCore<")?;
277
        <D::Core as AlgorithmName>::write_alg_name(f)?;
278
        f.write_str("> { ... }")
279
    }
280
}