/rust/registry/src/index.crates.io-1949cf8c6b5b557f/aws-lc-rs-1.16.3/src/lib.rs
Line | Count | Source |
1 | | // Copyright 2015-2016 Brian Smith. |
2 | | // SPDX-License-Identifier: ISC |
3 | | // Modifications copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
4 | | // SPDX-License-Identifier: Apache-2.0 OR ISC |
5 | | #![cfg_attr(not(clippy), allow(unexpected_cfgs))] |
6 | | #![cfg_attr(not(clippy), allow(unknown_lints))] |
7 | | #![allow(clippy::doc_markdown)] |
8 | | //! A [*ring*](https://github.com/briansmith/ring)-compatible crypto library using the cryptographic |
9 | | //! operations provided by [*AWS-LC*](https://github.com/aws/aws-lc). It uses either the |
10 | | //! auto-generated [*aws-lc-sys*](https://crates.io/crates/aws-lc-sys) or |
11 | | //! [*aws-lc-fips-sys*](https://crates.io/crates/aws-lc-fips-sys) |
12 | | //! Foreign Function Interface (FFI) crates found in this repository for invoking *AWS-LC*. |
13 | | //! |
14 | | //! # Build |
15 | | //! |
16 | | //! `aws-lc-rs` is available through [crates.io](https://crates.io/crates/aws-lc-rs). It can |
17 | | //! be added to your project in the [standard way](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html) |
18 | | //! using `Cargo.toml`: |
19 | | //! |
20 | | //! ```toml |
21 | | //! [dependencies] |
22 | | //! aws-lc-rs = "1" |
23 | | //! ``` |
24 | | //! Consuming projects will need a C/C++ compiler to build. |
25 | | //! |
26 | | //! **Non-FIPS builds (default):** |
27 | | //! * CMake is **never** required |
28 | | //! * Bindgen is **never** required (pre-generated bindings are provided) |
29 | | //! * Go is **never** required |
30 | | //! |
31 | | //! **FIPS builds:** Require **CMake**, **Go**, and potentially **bindgen** depending on the target platform. |
32 | | //! |
33 | | //! See our [User Guide](https://aws.github.io/aws-lc-rs/) for guidance on installing build requirements. |
34 | | //! |
35 | | //! # Feature Flags |
36 | | //! |
37 | | //! #### alloc (default) |
38 | | //! |
39 | | //! Allows implementation to allocate values of arbitrary size. (The meaning of this feature differs |
40 | | //! from the "alloc" feature of *ring*.) Currently, this is required by the `io::writer` module. |
41 | | //! |
42 | | //! #### ring-io (default) |
43 | | //! |
44 | | //! Enable feature to access the `io` module. |
45 | | //! |
46 | | //! #### ring-sig-verify (default) |
47 | | //! |
48 | | //! Enable feature to preserve compatibility with ring's `signature::VerificationAlgorithm::verify` |
49 | | //! function. This adds a requirement on `untrusted = "0.7.1"`. |
50 | | //! |
51 | | //! #### fips |
52 | | //! |
53 | | //! Enable this feature to have aws-lc-rs use the [*aws-lc-fips-sys*](https://crates.io/crates/aws-lc-fips-sys) |
54 | | //! crate for the cryptographic implementations. The aws-lc-fips-sys crate provides bindings to the |
55 | | //! latest version of the AWS-LC-FIPS module that has completed FIPS validation testing by an |
56 | | //! accredited lab and has been submitted to NIST for certification. This will continue to be the |
57 | | //! case as we periodically submit new versions of the AWS-LC-FIPS module to NIST for certification. |
58 | | //! Currently, aws-lc-fips-sys binds to |
59 | | //! [AWS-LC-FIPS 3.0.x](https://github.com/aws/aws-lc/tree/fips-2024-09-27). |
60 | | //! |
61 | | //! Consult with your local FIPS compliance team to determine the version of AWS-LC-FIPS module that you require. Consumers |
62 | | //! needing to remain on a previous version of the AWS-LC-FIPS module should pin to specific versions of aws-lc-rs to avoid |
63 | | //! automatically being upgraded to a newer module version. |
64 | | //! (See [cargo's documentation](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html) |
65 | | //! on how to specify dependency versions.) |
66 | | //! |
67 | | //! | AWS-LC-FIPS module | aws-lc-rs | |
68 | | //! |--------------------|-----------| |
69 | | //! | 2.0.x | \<1.12.0 | |
70 | | //! | 3.0.x | *latest* | |
71 | | //! |
72 | | //! Refer to the |
73 | | //! [NIST Cryptographic Module Validation Program's Modules In Progress List](https://csrc.nist.gov/Projects/cryptographic-module-validation-program/modules-in-process/Modules-In-Process-List) |
74 | | //! for the latest status of the static or dynamic AWS-LC Cryptographic Module. Please see the |
75 | | //! [FIPS.md in the aws-lc repository](https://github.com/aws/aws-lc/blob/main/crypto/fipsmodule/FIPS.md) |
76 | | //! for relevant security policies and information on supported operating environments. |
77 | | //! We will also update our release notes and documentation to reflect any changes in FIPS certification status. |
78 | | //! |
79 | | //! #### non-fips |
80 | | //! |
81 | | //! Enable this feature to guarantee that the non-FIPS [*aws-lc-sys*](https://crates.io/crates/aws-lc-sys) |
82 | | //! crate is used for cryptographic implementations. This feature is mutually exclusive with the `fips` |
83 | | //! feature - enabling both will result in a compile-time error. Use this feature when you need a |
84 | | //! compile-time guarantee that your build is using the non-FIPS cryptographic module. |
85 | | //! |
86 | | //! #### asan |
87 | | //! |
88 | | //! Performs an "address sanitizer" build. This can be used to help detect memory leaks. See the |
89 | | //! ["Address Sanitizer" section](https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html#addresssanitizer) |
90 | | //! of the [Rust Unstable Book](https://doc.rust-lang.org/beta/unstable-book/). |
91 | | //! |
92 | | //! **Preferred alternative:** Instead of the `asan` feature flag, you can set the |
93 | | //! `AWS_LC_SYS_SANITIZER` environment variable (or `AWS_LC_FIPS_SYS_SANITIZER` for FIPS builds) |
94 | | //! to one of: `asan`, `msan`, `tsan`. This approach does not require forwarding a feature through |
95 | | //! the dependency graph and also supports MemorySanitizer and ThreadSanitizer. |
96 | | //! MSAN and TSAN require the standard library to be rebuilt with sanitizer instrumentation, so |
97 | | //! you must install the `rust-src` component and pass `-Zbuild-std` to Cargo. For example: |
98 | | //! |
99 | | //! ```bash |
100 | | //! rustup component add rust-src --toolchain nightly |
101 | | //! AWS_LC_SYS_SANITIZER=msan RUSTFLAGS="-Zsanitizer=memory -Zsanitizer-memory-track-origins" \ |
102 | | //! cargo +nightly test -Zbuild-std --target x86_64-unknown-linux-gnu |
103 | | //! ``` |
104 | | //! |
105 | | //! **Note:** MSAN is not currently supported for FIPS builds due to a missing preprocessor guard |
106 | | //! in the upstream AWS-LC `bcm.c` integrity check. |
107 | | //! |
108 | | //! #### bindgen |
109 | | //! |
110 | | //! Causes `aws-lc-sys` or `aws-lc-fips-sys` to generates fresh bindings for AWS-LC instead of using |
111 | | //! the pre-generated bindings. This feature requires `libclang` to be installed. See the |
112 | | //! [requirements](https://rust-lang.github.io/rust-bindgen/requirements.html) |
113 | | //! for [rust-bindgen](https://github.com/rust-lang/rust-bindgen) |
114 | | //! |
115 | | //! #### prebuilt-nasm |
116 | | //! |
117 | | //! Enables the use of crate provided prebuilt NASM objects under certain conditions. This only affects builds for |
118 | | //! Windows x86-64 platforms. This feature is ignored if the "fips" feature is also enabled. |
119 | | //! |
120 | | //! Use of prebuilt NASM objects is prevented if either of the following conditions are true: |
121 | | //! * The NASM assembler is detected in the build environment |
122 | | //! * `AWS_LC_SYS_PREBUILT_NASM` environment variable is set with a value of `0` |
123 | | //! |
124 | | //! Be aware that [features are additive](https://doc.rust-lang.org/cargo/reference/features.html#feature-unification); |
125 | | //! by enabling this feature, it is enabled for all crates within the same build. |
126 | | //! |
127 | | //! #### dev-tests-only |
128 | | //! |
129 | | //! Enables the `rand::unsealed` module, which re-exports the normally sealed `SecureRandom` trait. |
130 | | //! This allows consumers to provide their own implementations of `SecureRandom` (e.g., a |
131 | | //! deterministic RNG) for testing purposes. When enabled, a `mut_fill` method is also available on |
132 | | //! `SecureRandom`. |
133 | | //! |
134 | | //! This feature is restricted to **dev/debug profile builds only** — attempting to use it in a |
135 | | //! release build will result in a compile-time error. |
136 | | //! |
137 | | //! It can be enabled in two ways: |
138 | | //! * **Feature flag:** `cargo test --features dev-tests-only` |
139 | | //! * **Environment variable:** `AWS_LC_RS_DEV_TESTS_ONLY=1 cargo test` |
140 | | //! |
141 | | //! **⚠️ Warning:** This feature is intended **only** for development and testing. It must not be |
142 | | //! used in production builds. The `rand::unsealed` module and `mut_fill` method are not part of the |
143 | | //! stable public API and may change without notice. |
144 | | //! |
145 | | //! # Use of prebuilt NASM objects |
146 | | //! |
147 | | //! Prebuilt NASM objects are **only** applicable to Windows x86-64 platforms. They are **never** used on any other platform (Linux, macOS, etc.). |
148 | | //! |
149 | | //! For Windows x86 and x86-64, NASM is required for assembly code compilation. On these platforms, |
150 | | //! we recommend that you install [the NASM assembler](https://www.nasm.us/). **If NASM is |
151 | | //! detected in the build environment, it is always used** to compile the assembly files. Prebuilt NASM objects are only used as a fallback. |
152 | | //! |
153 | | //! If a NASM assembler is not available, and the "fips" feature is not enabled, then the build fails unless one of the following conditions are true: |
154 | | //! |
155 | | //! * You are building for `x86-64` and either: |
156 | | //! * The `AWS_LC_SYS_PREBUILT_NASM` environment variable is found and has a value of "1"; OR |
157 | | //! * `AWS_LC_SYS_PREBUILT_NASM` is *not found* in the environment AND the "prebuilt-nasm" feature has been enabled. |
158 | | //! |
159 | | //! If the above cases apply, then the crate provided prebuilt NASM objects will be used for the build. To prevent usage of prebuilt NASM |
160 | | //! objects, install NASM in the build environment and/or set the variable `AWS_LC_SYS_PREBUILT_NASM` to `0` in the build environment to prevent their use. |
161 | | //! |
162 | | //! ## About prebuilt NASM objects |
163 | | //! |
164 | | //! Prebuilt NASM objects are generated using automation similar to the crate provided pregenerated bindings. See the repository's |
165 | | //! [GitHub workflow configuration](https://github.com/aws/aws-lc-rs/blob/main/.github/workflows/sys-bindings-generator.yml) for more information. |
166 | | //! The prebuilt NASM objects are checked into the repository |
167 | | //! and are [available for inspection](https://github.com/aws/aws-lc-rs/tree/main/aws-lc-sys/builder/prebuilt-nasm). |
168 | | //! For each PR submitted, |
169 | | //! [CI verifies](https://github.com/aws/aws-lc-rs/blob/main/.github/workflows/tests.yml) |
170 | | //! that the NASM objects newly built from source match the NASM objects currently in the repository. |
171 | | //! |
172 | | //! # *ring*-compatibility |
173 | | //! |
174 | | //! Although this library attempts to be fully compatible with *ring* (v0.16.x), there are a few places where our |
175 | | //! behavior is observably different. |
176 | | //! |
177 | | //! * Our implementation requires the `std` library. We currently do not support a |
178 | | //! [`#![no_std]`](https://docs.rust-embedded.org/book/intro/no-std.html) build. |
179 | | //! * `aws-lc-rs` supports the platforms supported by `aws-lc-sys` and AWS-LC. See the |
180 | | //! [Platform Support](https://aws.github.io/aws-lc-rs/platform_support.html) page in our User Guide. |
181 | | //! * `Ed25519KeyPair::from_pkcs8` and `Ed25519KeyPair::from_pkcs8_maybe_unchecked` both support |
182 | | //! parsing of v1 or v2 PKCS#8 documents. If a v2 encoded key is provided to either function, |
183 | | //! public key component, if present, will be verified to match the one derived from the encoded |
184 | | //! private key. |
185 | | //! |
186 | | //! # Post-Quantum Cryptography |
187 | | //! |
188 | | //! Details on the post-quantum algorithms supported by aws-lc-rs can be found at |
189 | | //! [PQREADME](https://github.com/aws/aws-lc/tree/main/crypto/fipsmodule/PQREADME.md). |
190 | | //! |
191 | | //! # Motivation |
192 | | //! |
193 | | //! Rust developers increasingly need to deploy applications that meet US and Canadian government |
194 | | //! cryptographic requirements. We evaluated how to deliver FIPS validated cryptography in idiomatic |
195 | | //! and performant Rust, built around our AWS-LC offering. We found that the popular ring (v0.16) |
196 | | //! library fulfilled much of the cryptographic needs in the Rust community, but it did not meet the |
197 | | //! needs of developers with FIPS requirements. Our intention is to contribute a drop-in replacement |
198 | | //! for ring that provides FIPS support and is compatible with the ring API. Rust developers with |
199 | | //! prescribed cryptographic requirements can seamlessly integrate aws-lc-rs into their applications |
200 | | //! and deploy them into AWS Regions. |
201 | | |
202 | | #![warn(missing_docs)] |
203 | | #![warn(clippy::exhaustive_enums)] |
204 | | #![cfg_attr(aws_lc_rs_docsrs, feature(doc_cfg))] |
205 | | |
206 | | extern crate alloc; |
207 | | #[cfg(feature = "fips")] |
208 | | extern crate aws_lc_fips_sys as aws_lc; |
209 | | #[cfg(not(feature = "fips"))] |
210 | | extern crate aws_lc_sys as aws_lc; |
211 | | |
212 | | pub mod aead; |
213 | | pub mod agreement; |
214 | | pub mod cmac; |
215 | | pub mod constant_time; |
216 | | pub mod digest; |
217 | | pub mod error; |
218 | | pub mod hkdf; |
219 | | pub mod hmac; |
220 | | #[cfg(feature = "ring-io")] |
221 | | pub mod io; |
222 | | pub mod key_wrap; |
223 | | pub mod pbkdf2; |
224 | | pub mod pkcs8; |
225 | | pub mod rand; |
226 | | pub mod signature; |
227 | | pub mod test; |
228 | | |
229 | | mod bn; |
230 | | mod buffer; |
231 | | mod cbb; |
232 | | mod cbs; |
233 | | pub mod cipher; |
234 | | mod debug; |
235 | | mod ec; |
236 | | mod ed25519; |
237 | | pub mod encoding; |
238 | | mod endian; |
239 | | mod evp_pkey; |
240 | | mod fips; |
241 | | mod hex; |
242 | | pub mod iv; |
243 | | pub mod kdf; |
244 | | #[allow(clippy::module_name_repetitions)] |
245 | | pub mod kem; |
246 | | #[cfg(all(feature = "unstable", not(feature = "fips")))] |
247 | | mod pqdsa; |
248 | | mod ptr; |
249 | | pub mod rsa; |
250 | | pub mod tls_prf; |
251 | | pub mod unstable; |
252 | | |
253 | | pub(crate) use debug::derive_debug_via_id; |
254 | | // TODO: Uncomment when MSRV >= 1.64 |
255 | | // use core::ffi::CStr; |
256 | | use std::ffi::CStr; |
257 | | |
258 | | use crate::aws_lc::{ |
259 | | CRYPTO_library_init, ERR_error_string, ERR_get_error, FIPS_mode, ERR_GET_FUNC, ERR_GET_LIB, |
260 | | ERR_GET_REASON, |
261 | | }; |
262 | | use std::sync::Once; |
263 | | |
264 | | static START: Once = Once::new(); |
265 | | |
266 | | #[inline] |
267 | | /// Initialize the *AWS-LC* library. (This should generally not be needed.) |
268 | 0 | pub fn init() { |
269 | 0 | START.call_once(|| unsafe { |
270 | 0 | CRYPTO_library_init(); |
271 | 0 | }); |
272 | 0 | } |
273 | | |
274 | | #[cfg(feature = "fips")] |
275 | | /// Panics if the underlying implementation is not FIPS, otherwise it returns. |
276 | | /// |
277 | | /// # Panics |
278 | | /// Panics if the underlying implementation is not FIPS. |
279 | | pub fn fips_mode() { |
280 | | try_fips_mode().unwrap(); |
281 | | } |
282 | | |
283 | | /// Indicates whether the underlying implementation is FIPS. |
284 | | /// |
285 | | /// # Errors |
286 | | /// Return an error if the underlying implementation is not FIPS, otherwise Ok. |
287 | 0 | pub fn try_fips_mode() -> Result<(), &'static str> { |
288 | 0 | init(); |
289 | 0 | match unsafe { FIPS_mode() } { |
290 | 0 | 1 => Ok(()), |
291 | 0 | _ => Err("FIPS mode not enabled!"), |
292 | | } |
293 | 0 | } |
294 | | |
295 | | #[cfg(feature = "fips")] |
296 | | /// Panics if the underlying implementation is not using CPU jitter entropy, otherwise it returns. |
297 | | /// |
298 | | /// # Panics |
299 | | /// Panics if the underlying implementation is not using CPU jitter entropy. |
300 | | pub fn fips_cpu_jitter_entropy() { |
301 | | try_fips_cpu_jitter_entropy().unwrap(); |
302 | | } |
303 | | |
304 | | /// Indicates whether the underlying implementation is FIPS. |
305 | | /// |
306 | | /// # Errors |
307 | | /// Return an error if the underlying implementation is not using CPU jitter entropy, otherwise Ok. |
308 | 0 | pub fn try_fips_cpu_jitter_entropy() -> Result<(), &'static str> { |
309 | 0 | init(); |
310 | | // TODO: Delete once FIPS_is_entropy_cpu_jitter() available on FIPS branch |
311 | | // https://github.com/aws/aws-lc/pull/2088 |
312 | | #[cfg(feature = "fips")] |
313 | | if aws_lc::CFG_CPU_JITTER_ENTROPY() { |
314 | | Ok(()) |
315 | | } else { |
316 | | Err("FIPS CPU Jitter Entropy not enabled!") |
317 | | } |
318 | | #[cfg(not(feature = "fips"))] |
319 | 0 | match unsafe { aws_lc::FIPS_is_entropy_cpu_jitter() } { |
320 | 0 | 1 => Ok(()), |
321 | 0 | _ => Err("FIPS CPU Jitter Entropy not enabled!"), |
322 | | } |
323 | 0 | } |
324 | | |
325 | | #[allow(dead_code)] |
326 | 0 | unsafe fn dump_error() { |
327 | 0 | let err = ERR_get_error(); |
328 | 0 | let lib = ERR_GET_LIB(err); |
329 | 0 | let reason = ERR_GET_REASON(err); |
330 | 0 | let func = ERR_GET_FUNC(err); |
331 | 0 | let mut buffer = [0u8; 256]; |
332 | 0 | ERR_error_string(err, buffer.as_mut_ptr().cast()); |
333 | 0 | let error_msg = CStr::from_bytes_with_nul_unchecked(&buffer); |
334 | 0 | eprintln!("Raw Error -- {error_msg:?}\nErr: {err}, Lib: {lib}, Reason: {reason}, Func: {func}"); |
335 | 0 | } |
336 | | |
337 | | mod sealed { |
338 | | /// Traits that are designed to only be implemented internally in *aws-lc-rs*. |
339 | | // |
340 | | // Usage: |
341 | | // ``` |
342 | | // use crate::sealed; |
343 | | // |
344 | | // pub trait MyType: sealed::Sealed { |
345 | | // // [...] |
346 | | // } |
347 | | // |
348 | | // impl sealed::Sealed for MyType {} |
349 | | // ``` |
350 | | pub trait Sealed {} |
351 | | } |
352 | | |
353 | | #[cfg(test)] |
354 | | mod tests { |
355 | | use crate::{dump_error, init}; |
356 | | |
357 | | #[test] |
358 | | fn test_init() { |
359 | | init(); |
360 | | } |
361 | | |
362 | | #[test] |
363 | | fn test_dump() { |
364 | | unsafe { |
365 | | dump_error(); |
366 | | } |
367 | | } |
368 | | |
369 | | #[cfg(not(feature = "fips"))] |
370 | | #[test] |
371 | | fn test_fips() { |
372 | | assert!({ crate::try_fips_mode().is_err() }); |
373 | | // Re-enable with fixed test after upstream has merged RAGDOLL |
374 | | //assert!({ crate::try_fips_cpu_jitter_entropy().is_ok() }); |
375 | | } |
376 | | |
377 | | #[test] |
378 | | // FIPS mode is disabled for an ASAN build |
379 | | #[cfg(feature = "fips")] |
380 | | fn test_fips() { |
381 | | #[cfg(not(feature = "asan"))] |
382 | | crate::fips_mode(); |
383 | | if aws_lc::CFG_CPU_JITTER_ENTROPY() { |
384 | | crate::fips_cpu_jitter_entropy(); |
385 | | } |
386 | | } |
387 | | } |