Coverage Report

Created: 2026-07-13 08:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/aws-lc-rs-1.16.3/src/kdf/sskdf.rs
Line
Count
Source
1
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
// SPDX-License-Identifier: Apache-2.0 OR ISC
3
4
#![allow(clippy::module_name_repetitions)]
5
6
use crate::aws_lc::{SSKDF_digest, SSKDF_hmac, EVP_MD};
7
8
use crate::digest::{match_digest_type, AlgorithmID};
9
use crate::error::Unspecified;
10
use crate::ptr::ConstPointer;
11
12
/// SSKDF with HMAC-SHA224
13
#[allow(dead_code)]
14
const SSKDF_HMAC_SHA224: SskdfHmacAlgorithm = SskdfHmacAlgorithm {
15
    id: SskdfHmacAlgorithmId::Sha224,
16
};
17
18
/// SSKDF with HMAC-SHA256
19
#[allow(dead_code)]
20
const SSKDF_HMAC_SHA256: SskdfHmacAlgorithm = SskdfHmacAlgorithm {
21
    id: SskdfHmacAlgorithmId::Sha256,
22
};
23
24
/// SSKDF with HMAC-SHA384
25
#[allow(dead_code)]
26
const SSKDF_HMAC_SHA384: SskdfHmacAlgorithm = SskdfHmacAlgorithm {
27
    id: SskdfHmacAlgorithmId::Sha384,
28
};
29
30
/// SSKDF with HMAC-SHA512
31
#[allow(dead_code)]
32
const SSKDF_HMAC_SHA512: SskdfHmacAlgorithm = SskdfHmacAlgorithm {
33
    id: SskdfHmacAlgorithmId::Sha512,
34
};
35
36
/// SSKDF with SHA224
37
#[allow(dead_code)]
38
const SSKDF_DIGEST_SHA224: SskdfDigestAlgorithm = SskdfDigestAlgorithm {
39
    id: SskdfDigestAlgorithmId::Sha224,
40
};
41
42
/// SSKDF with SHA256
43
#[allow(dead_code)]
44
const SSKDF_DIGEST_SHA256: SskdfDigestAlgorithm = SskdfDigestAlgorithm {
45
    id: SskdfDigestAlgorithmId::Sha256,
46
};
47
48
/// SSKDF with SHA384
49
#[allow(dead_code)]
50
const SSKDF_DIGEST_SHA384: SskdfDigestAlgorithm = SskdfDigestAlgorithm {
51
    id: SskdfDigestAlgorithmId::Sha384,
52
};
53
54
/// SSKDF with SHA512
55
#[allow(dead_code)]
56
const SSKDF_DIGEST_SHA512: SskdfDigestAlgorithm = SskdfDigestAlgorithm {
57
    id: SskdfDigestAlgorithmId::Sha512,
58
};
59
60
/// Retrieve [`SskdfHmacAlgorithm`] using the [`SskdfHmacAlgorithmId`] specified by `id`.
61
#[must_use]
62
0
pub const fn get_sskdf_hmac_algorithm(
63
0
    id: SskdfHmacAlgorithmId,
64
0
) -> Option<&'static SskdfHmacAlgorithm> {
65
    {
66
0
        match id {
67
0
            SskdfHmacAlgorithmId::Sha224 => Some(&SSKDF_HMAC_SHA224),
68
0
            SskdfHmacAlgorithmId::Sha256 => Some(&SSKDF_HMAC_SHA256),
69
0
            SskdfHmacAlgorithmId::Sha384 => Some(&SSKDF_HMAC_SHA384),
70
0
            SskdfHmacAlgorithmId::Sha512 => Some(&SSKDF_HMAC_SHA512),
71
        }
72
    }
73
0
}
74
75
/// Retrieve [`SskdfDigestAlgorithm`] using the [`SskdfDigestAlgorithmId`] specified by `id`.
76
#[must_use]
77
0
pub const fn get_sskdf_digest_algorithm(
78
0
    id: SskdfDigestAlgorithmId,
79
0
) -> Option<&'static SskdfDigestAlgorithm> {
80
    {
81
0
        match id {
82
0
            SskdfDigestAlgorithmId::Sha224 => Some(&SSKDF_DIGEST_SHA224),
83
0
            SskdfDigestAlgorithmId::Sha256 => Some(&SSKDF_DIGEST_SHA256),
84
0
            SskdfDigestAlgorithmId::Sha384 => Some(&SSKDF_DIGEST_SHA384),
85
0
            SskdfDigestAlgorithmId::Sha512 => Some(&SSKDF_DIGEST_SHA512),
86
        }
87
    }
88
0
}
89
90
/// SSKDF algorithm using HMAC
91
pub struct SskdfHmacAlgorithm {
92
    id: SskdfHmacAlgorithmId,
93
}
94
95
impl SskdfHmacAlgorithm {
96
    /// Returns the SSKDF HMAC Algorithm Identifier
97
    #[must_use]
98
0
    pub fn id(&self) -> SskdfHmacAlgorithmId {
99
0
        self.id
100
0
    }
101
102
    #[must_use]
103
0
    fn get_evp_md(&self) -> ConstPointer<'_, EVP_MD> {
104
0
        match_digest_type(match self.id {
105
0
            SskdfHmacAlgorithmId::Sha224 => &AlgorithmID::SHA224,
106
0
            SskdfHmacAlgorithmId::Sha256 => &AlgorithmID::SHA256,
107
0
            SskdfHmacAlgorithmId::Sha384 => &AlgorithmID::SHA384,
108
0
            SskdfHmacAlgorithmId::Sha512 => &AlgorithmID::SHA512,
109
        })
110
0
    }
111
}
112
113
impl PartialEq for SskdfHmacAlgorithm {
114
0
    fn eq(&self, other: &Self) -> bool {
115
0
        self.id == other.id
116
0
    }
117
}
118
119
impl Eq for SskdfHmacAlgorithm {}
120
121
impl core::fmt::Debug for SskdfHmacAlgorithm {
122
0
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
123
0
        core::fmt::Debug::fmt(&self.id, f)
124
0
    }
125
}
126
127
/// SSKDF algorithm using digest
128
pub struct SskdfDigestAlgorithm {
129
    id: SskdfDigestAlgorithmId,
130
}
131
132
impl SskdfDigestAlgorithm {
133
    /// Returns the SSKDF Algorithm Identifier
134
    #[must_use]
135
0
    pub fn id(&self) -> SskdfDigestAlgorithmId {
136
0
        self.id
137
0
    }
138
139
    #[must_use]
140
0
    fn get_evp_md(&self) -> ConstPointer<'_, EVP_MD> {
141
0
        match_digest_type(match self.id {
142
0
            SskdfDigestAlgorithmId::Sha224 => &AlgorithmID::SHA224,
143
0
            SskdfDigestAlgorithmId::Sha256 => &AlgorithmID::SHA256,
144
0
            SskdfDigestAlgorithmId::Sha384 => &AlgorithmID::SHA384,
145
0
            SskdfDigestAlgorithmId::Sha512 => &AlgorithmID::SHA512,
146
        })
147
0
    }
148
}
149
150
impl PartialEq for SskdfDigestAlgorithm {
151
0
    fn eq(&self, other: &Self) -> bool {
152
0
        self.id == other.id
153
0
    }
154
}
155
156
impl Eq for SskdfDigestAlgorithm {}
157
158
impl core::fmt::Debug for SskdfDigestAlgorithm {
159
0
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
160
0
        core::fmt::Debug::fmt(&self.id, f)
161
0
    }
162
}
163
164
/// Single-step (One-step) Key Derivation Function Digest Algorithm Identifier
165
#[non_exhaustive]
166
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
167
pub enum SskdfDigestAlgorithmId {
168
    /// SSKDF with SHA224
169
    Sha224,
170
171
    /// SSKDF with SHA256
172
    Sha256,
173
174
    /// SSKDF with SHA384
175
    Sha384,
176
177
    /// SSKDF with SHA512
178
    Sha512,
179
}
180
181
/// Single-step (One-step) Key Derivation Function HMAC Algorithm Identifier
182
#[non_exhaustive]
183
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
184
pub enum SskdfHmacAlgorithmId {
185
    /// SSKDF with HMAC-SHA224
186
    Sha224,
187
188
    /// SSKDF with HMAC-SHA256
189
    Sha256,
190
191
    /// SSKDF with HMAC-SHA384
192
    Sha384,
193
194
    /// SSKDF with HMAC-SHA512
195
    Sha512,
196
}
197
198
/// # Single-step Key Derivation Function using HMAC
199
///
200
/// This algorithm may be referred to as "Single-Step KDF" or "NIST Concatenation KDF" by other
201
/// implementors.
202
///
203
/// ## Input Validation and Defaults
204
/// * `output.len()`, `secret.len()`, `info.len()` each must be <= 2^30.
205
/// * The default salt, an all zero byte string with length equal to the digest block length, is used
206
///   if `salt.len() == 0`.
207
/// * `output.len() > 0 and `secret.len() > 0`
208
///
209
/// ## Implementation Notes
210
///
211
/// This implementation adheres to the algorithm specified in Section 4 of the
212
/// NIST Special Publication 800-56C Revision 2 published on August 2020.
213
/// Using Option 2 for the auxiliary function H.
214
///
215
/// Specification is available at <https://doi.org/10.6028/NIST.SP.800-56Cr2>
216
///
217
/// # Errors
218
/// `Unspecified` is returned if input validation fails or an unexpected error occurs.
219
0
pub fn sskdf_hmac(
220
0
    algorithm: &'static SskdfHmacAlgorithm,
221
0
    secret: &[u8],
222
0
    info: &[u8],
223
0
    salt: &[u8],
224
0
    output: &mut [u8],
225
0
) -> Result<(), Unspecified> {
226
0
    let evp_md = algorithm.get_evp_md();
227
0
    let out_len = output.len();
228
0
    if 1 != unsafe {
229
0
        SSKDF_hmac(
230
0
            output.as_mut_ptr(),
231
0
            out_len,
232
0
            evp_md.as_const_ptr(),
233
0
            secret.as_ptr(),
234
0
            secret.len(),
235
0
            info.as_ptr(),
236
0
            info.len(),
237
0
            salt.as_ptr(),
238
0
            salt.len(),
239
0
        )
240
0
    } {
241
0
        return Err(Unspecified);
242
0
    }
243
0
    Ok(())
244
0
}
245
246
/// # Single-step Key Derivation Function using digest
247
///
248
/// This algorithm may be referred to as "Single-Step KDF" or "NIST Concatenation KDF" by other
249
/// implementors.
250
///
251
/// ## Input Validation and Defaults
252
/// * `output.len()`, `secret.len()`, `info.len()` each must be <= 2^30.
253
/// * `output.len() > 0 and `secret.len() > 0`
254
///
255
/// ## Implementation Notes
256
///
257
/// This implementation adheres to the algorithm specified in Section 4 of the
258
/// NIST Special Publication 800-56C Revision 2 published on August 2020.
259
/// Using Option 1 for the auxiliary function H.
260
///
261
/// Specification is available at <https://doi.org/10.6028/NIST.SP.800-56Cr2>
262
///
263
/// # Errors
264
/// `Unspecified` is returned if input validation fails or an unexpected error occurs.
265
0
pub fn sskdf_digest(
266
0
    algorithm: &'static SskdfDigestAlgorithm,
267
0
    secret: &[u8],
268
0
    info: &[u8],
269
0
    output: &mut [u8],
270
0
) -> Result<(), Unspecified> {
271
0
    let evp_md = algorithm.get_evp_md();
272
0
    let out_len = output.len();
273
0
    if 1 != unsafe {
274
0
        SSKDF_digest(
275
0
            output.as_mut_ptr(),
276
0
            out_len,
277
0
            evp_md.as_const_ptr(),
278
0
            secret.as_ptr(),
279
0
            secret.len(),
280
0
            info.as_ptr(),
281
0
            info.len(),
282
0
        )
283
0
    } {
284
0
        return Err(Unspecified);
285
0
    }
286
0
    Ok(())
287
0
}