/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 | } |