Coverage Report

Created: 2026-05-16 07:06

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