From d805e1fdfd1f8bb7968e6d327f4b19a53b05f73e Mon Sep 17 00:00:00 2001 From: Sean McGrail Date: Thu, 4 Jan 2024 17:45:14 +0000 Subject: [PATCH] Add 'fips' Cargo feature Add `rustls::crypto::default_fips_provider()` behind this feature. --- .github/workflows/build.yml | 18 ++++++++- Cargo.lock | 40 +++++++++++++++++++- rustls/Cargo.toml | 1 + rustls/examples/internal/bench_impl.rs | 5 ++- rustls/src/client/client_conn.rs | 33 ++++++++++------ rustls/src/crypto/aws_lc_rs/mod.rs | 52 ++++++++++++++++++++------ rustls/src/crypto/mod.rs | 46 ++++++++++++++++++++++- rustls/src/crypto/ring/mod.rs | 2 - rustls/src/lib.rs | 4 ++ rustls/src/server/server_conn.rs | 35 +++++++++++------ rustls/tests/api.rs | 40 ++++++++++++++------ rustls/tests/common/mod.rs | 13 +++---- 12 files changed, 228 insertions(+), 61 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 52dd189f..3127bdca 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -46,8 +46,10 @@ jobs: - name: cargo build (debug; default features) run: cargo build --locked - - name: cargo test (debug; all features) - run: cargo test --locked --all-features + # nb. feature sets that include "fips" should be --release -- + # this is required for fips on windows. + - name: cargo test (release; all features) + run: cargo test --release --locked --all-features env: RUST_BACKTRACE: 1 @@ -56,6 +58,11 @@ jobs: env: RUST_BACKTRACE: 1 + - name: cargo test (release; fips) + run: cargo test --release --no-default-features --features fips,tls12,read_buf,logging + env: + RUST_BACKTRACE: 1 + - name: cargo build (debug; rustls-provider-example) run: cargo build --locked -p rustls-provider-example @@ -111,6 +118,10 @@ jobs: run: cargo test --no-default-features --features aws_lc_rs,tls12 working-directory: rustls + - name: cargo test (debug; no default features; fips,tls12) + run: cargo test --no-default-features --features fips,tls12 + working-directory: rustls + - name: cargo test (release; no run) run: cargo test --locked --release --no-run working-directory: rustls @@ -186,6 +197,9 @@ jobs: - name: Smoke-test benchmark program (aws-lc-rs) run: cargo run -p rustls --release --locked --example bench --no-default-features --features aws_lc_rs,tls12 + - name: Smoke-test benchmark program (fips) + run: cargo run -p rustls --release --locked --example bench --no-default-features --features fips,tls12 + - name: Run micro-benchmarks run: cargo bench --locked --all-features env: diff --git a/Cargo.lock b/Cargo.lock index 8157b82a..4e028f8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -293,12 +293,27 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "aws-lc-fips-sys" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f56794bd674ee9f3d8de0e1d378ee44c72beb3506e5b747f89a632eb39adba1" +dependencies = [ + "bindgen 0.69.1", + "cmake", + "dunce", + "fs_extra", + "libc", + "paste", +] + [[package]] name = "aws-lc-rs" version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bc2aa0a35a53d7cfda07a69f74d67a918ced3ec1a607f5bce5da7c3aff6bab7" dependencies = [ + "aws-lc-fips-sys", "aws-lc-sys", "mirai-annotations", "untrusted 0.7.1", @@ -311,7 +326,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2c6f9497a1bd3bed0a28a01b8836dbe9c7a2c521e47a14b165c64c4df592331" dependencies = [ - "bindgen", + "bindgen 0.68.1", "cmake", "dunce", "fs_extra", @@ -381,6 +396,29 @@ dependencies = [ "which", ] +[[package]] +name = "bindgen" +version = "0.69.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ffcebc3849946a7170a05992aac39da343a90676ab392c51a4280981d6379c2" +dependencies = [ + "bitflags 2.4.1", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.46", + "which", +] + [[package]] name = "bitflags" version = "1.3.2" diff --git a/rustls/Cargo.toml b/rustls/Cargo.toml index f1c88c01..cc36c8d2 100644 --- a/rustls/Cargo.toml +++ b/rustls/Cargo.toml @@ -31,6 +31,7 @@ aws_lc_rs = ["dep:aws-lc-rs", "webpki/aws_lc_rs"] ring = ["dep:ring", "webpki/ring"] tls12 = [] read_buf = ["rustversion"] +fips = ["aws_lc_rs", "aws-lc-rs?/fips"] [dev-dependencies] base64 = "0.21" diff --git a/rustls/examples/internal/bench_impl.rs b/rustls/examples/internal/bench_impl.rs index b6ec58f8..160db031 100644 --- a/rustls/examples/internal/bench_impl.rs +++ b/rustls/examples/internal/bench_impl.rs @@ -173,13 +173,13 @@ impl BenchmarkParam { } static ALL_BENCHMARKS: &[BenchmarkParam] = &[ - #[cfg(feature = "tls12")] + #[cfg(all(feature = "tls12", not(feature = "fips")))] BenchmarkParam::new( KeyType::Rsa, cipher_suite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, &rustls::version::TLS12, ), - #[cfg(feature = "tls12")] + #[cfg(all(feature = "tls12", not(feature = "fips")))] BenchmarkParam::new( KeyType::EcdsaP256, cipher_suite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, @@ -209,6 +209,7 @@ static ALL_BENCHMARKS: &[BenchmarkParam] = &[ cipher_suite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, &rustls::version::TLS12, ), + #[cfg(not(feature = "fips"))] BenchmarkParam::new( KeyType::Rsa, cipher_suite::TLS13_CHACHA20_POLY1305_SHA256, diff --git a/rustls/src/client/client_conn.rs b/rustls/src/client/client_conn.rs index 6a0d6a89..a38d2b76 100644 --- a/rustls/src/client/client_conn.rs +++ b/rustls/src/client/client_conn.rs @@ -1,6 +1,8 @@ use crate::builder::ConfigBuilder; use crate::common_state::{CommonState, Protocol, Side}; use crate::conn::{ConnectionCommon, ConnectionCore, UnbufferedConnectionCommon}; +#[cfg(any(feature = "ring", feature = "fips"))] +use crate::crypto::default_provider; use crate::crypto::{CryptoProvider, SupportedKxGroup}; use crate::enums::{CipherSuite, ProtocolVersion, SignatureScheme}; use crate::error::Error; @@ -14,7 +16,7 @@ use crate::suites::{ExtractedSecrets, SupportedCipherSuite}; use crate::unbuffered::{EncryptError, TransmitTlsData}; use crate::versions; use crate::KeyLog; -#[cfg(feature = "ring")] +#[cfg(any(feature = "ring", feature = "fips"))] use crate::WantsVerifier; use crate::{verify, WantsVersions}; @@ -206,31 +208,40 @@ pub struct ClientConfig { impl ClientConfig { /// Create a builder for a client configuration with the default - /// [`CryptoProvider`]: [`crypto::ring::default_provider`] and safe ciphersuite and - /// protocol defaults. + /// [`CryptoProvider`]. + /// + /// This is: + /// + /// - [`crypto::aws_lc_rs::default_provider`] if the `fips` crate feature is + /// enabled. + /// - [`crypto::ring::default_provider`] if the `ring` crate feature is + /// enabled and the `fips` crate feature is not enabled. + /// + /// If neither of these are true, this function is not available and you + /// must use [`ClientConfig::builder_with_provider()`] instead. /// /// For more information, see the [`ConfigBuilder`] documentation. - #[cfg(feature = "ring")] + #[cfg(any(feature = "ring", feature = "fips"))] pub fn builder() -> ConfigBuilder { - // Safety: we know the *ring* provider's ciphersuites are compatible with the safe default protocol versions. - Self::builder_with_provider(crate::crypto::ring::default_provider().into()) + // Safety: we know the *ring* and aws-lc-rs providers' ciphersuites are compatible with the safe default protocol versions. + Self::builder_with_provider(default_provider().into()) .with_safe_default_protocol_versions() .unwrap() } /// Create a builder for a client configuration with the default - /// [`CryptoProvider`]: [`crypto::ring::default_provider`], safe ciphersuite defaults and - /// the provided protocol versions. + /// [`CryptoProvider`] (see [`ClientConfig::builder()`] for details), safe + /// ciphersuite defaults and the provided protocol versions. /// /// Panics if provided an empty slice of supported versions. /// /// For more information, see the [`ConfigBuilder`] documentation. - #[cfg(feature = "ring")] + #[cfg(any(feature = "ring", feature = "fips"))] pub fn builder_with_protocol_versions( versions: &[&'static versions::SupportedProtocolVersion], ) -> ConfigBuilder { - // Safety: we know the *ring* provider's ciphersuites are compatible with all protocol version choices. - Self::builder_with_provider(crate::crypto::ring::default_provider().into()) + // Safety: we know the *ring* and aws-lc-rs providers' ciphersuites are compatible with all protocol version choices. + Self::builder_with_provider(default_provider().into()) .with_protocol_versions(versions) .unwrap() } diff --git a/rustls/src/crypto/aws_lc_rs/mod.rs b/rustls/src/crypto/aws_lc_rs/mod.rs index 20168c2f..512de107 100644 --- a/rustls/src/crypto/aws_lc_rs/mod.rs +++ b/rustls/src/crypto/aws_lc_rs/mod.rs @@ -10,6 +10,7 @@ use pki_types::PrivateKeyDer; use webpki::aws_lc_rs as webpki_algs; use alloc::sync::Arc; +use alloc::vec::Vec; // aws-lc-rs has a -- roughly -- ring-compatible API, so we just reuse all that // glue here. The shared files should always use `super::ring_like` to access a @@ -35,23 +36,29 @@ pub(crate) mod tls13; /// A `CryptoProvider` backed by aws-lc-rs. pub fn default_provider() -> CryptoProvider { CryptoProvider { - // TODO: make this filtering conditional on fips feature - cipher_suites: DEFAULT_CIPHER_SUITES - .iter() - .filter(|cs| cs.fips()) - .copied() - .collect(), - kx_groups: ALL_KX_GROUPS - .iter() - .filter(|kx| kx.fips()) - .copied() - .collect(), + cipher_suites: DEFAULT_CIPHER_SUITES.to_vec(), + kx_groups: default_kx_groups(), signature_verification_algorithms: SUPPORTED_SIG_ALGS, secure_random: &AwsLcRs, key_provider: &AwsLcRs, } } +fn default_kx_groups() -> Vec<&'static dyn SupportedKxGroup> { + #[cfg(feature = "fips")] + { + ALL_KX_GROUPS + .iter() + .filter(|cs| cs.fips()) + .copied() + .collect() + } + #[cfg(not(feature = "fips"))] + { + ALL_KX_GROUPS.to_vec() + } +} + #[derive(Debug)] struct AwsLcRs; @@ -86,7 +93,26 @@ impl KeyProvider for AwsLcRs { /// /// This will be [`ALL_CIPHER_SUITES`] sans any supported cipher suites that /// shouldn't be enabled by most applications. -pub static DEFAULT_CIPHER_SUITES: &[SupportedCipherSuite] = ALL_CIPHER_SUITES; +pub static DEFAULT_CIPHER_SUITES: &[SupportedCipherSuite] = &[ + // TLS1.3 suites + tls13::TLS13_AES_256_GCM_SHA384, + tls13::TLS13_AES_128_GCM_SHA256, + #[cfg(not(feature = "fips"))] + tls13::TLS13_CHACHA20_POLY1305_SHA256, + // TLS1.2 suites + #[cfg(feature = "tls12")] + tls12::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + #[cfg(feature = "tls12")] + tls12::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + #[cfg(all(feature = "tls12", not(feature = "fips")))] + tls12::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + #[cfg(feature = "tls12")] + tls12::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + #[cfg(feature = "tls12")] + tls12::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + #[cfg(all(feature = "tls12", not(feature = "fips")))] + tls12::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, +]; /// A list of all the cipher suites supported by the rustls *ring* provider. pub static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = &[ @@ -200,6 +226,8 @@ pub mod kx_group { pub use kx::ALL_KX_GROUPS; pub use ticketer::Ticketer; +use super::SupportedKxGroup; + /// Compatibility shims between ring 0.16.x and 0.17.x API mod ring_shim { use super::ring_like; diff --git a/rustls/src/crypto/mod.rs b/rustls/src/crypto/mod.rs index 0ff72c46..8b7659d0 100644 --- a/rustls/src/crypto/mod.rs +++ b/rustls/src/crypto/mod.rs @@ -69,7 +69,7 @@ pub use crate::msgs::handshake::KeyExchangeAlgorithm; /// crate. /// - [`crypto::aws_lc_rs::default_provider`]: (behind the `aws_lc_rs` feature, /// which is optional). This provider uses the [aws-lc-rs](https://github.com/aws/aws-lc-rs) -/// crate. +/// crate. The `fips` crate feature makes this option use FIPS140-3-approved cryptography. /// /// This structure provides defaults. Everything in it can be overridden at /// runtime by replacing field values as needed. @@ -153,6 +153,12 @@ pub use crate::msgs::handshake::KeyExchangeAlgorithm; /// [provider-example/]: https://github.com/rustls/rustls/tree/main/provider-example/ /// [rust-crypto]: https://github.com/rustcrypto /// [dalek-cryptography]: https://github.com/dalek-cryptography +/// +/// # FIPS-approved cryptography +/// The `fips` crate feature enables use of the `aws-lc-rs` crate in FIPS mode. +/// +/// You can verify the configuration at runtime by checking +/// [`ServerConfig::fips()`]/[`ClientConfig::fips()`] return `true`. #[derive(Debug, Clone)] pub struct CryptoProvider { /// List of supported ciphersuites, in preference order -- the first element @@ -329,3 +335,41 @@ impl From<&[u8]> for SharedSecret { Self(source.to_vec()) } } + +#[cfg(any(feature = "ring", feature = "fips"))] +pub(crate) fn default_provider() -> CryptoProvider { + #[cfg(all(feature = "ring", not(feature = "fips")))] + { + crate::crypto::ring::default_provider() + } + #[cfg(feature = "fips")] + { + crate::crypto::aws_lc_rs::default_provider() + } +} + +/// This function returns a [`CryptoProvider`] that uses +/// FIPS140-3-approved cryptography. +/// +/// You can use this like: +/// +/// ```rust +/// # #[cfg(feature = "fips")] { +/// # let root_store = rustls::RootCertStore::empty(); +/// let config = rustls::ClientConfig::builder_with_provider( +/// rustls::crypto::default_fips_provider().into() +/// ) +/// .with_safe_default_protocol_versions() +/// .unwrap() +/// .with_root_certificates(root_store) +/// .with_no_client_auth(); +/// # } +/// ``` +/// +/// This expresses in your code that you require FIPS-approved +/// cryptography, and will not compile if you make a mistake +/// with cargo features. +#[cfg(feature = "fips")] +pub fn default_fips_provider() -> CryptoProvider { + crate::crypto::aws_lc_rs::default_provider() +} diff --git a/rustls/src/crypto/ring/mod.rs b/rustls/src/crypto/ring/mod.rs index f69c7f72..2076455e 100644 --- a/rustls/src/crypto/ring/mod.rs +++ b/rustls/src/crypto/ring/mod.rs @@ -78,13 +78,11 @@ pub static ALL_CIPHER_SUITES: &[SupportedCipherSuite] = &[ tls12::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, #[cfg(feature = "tls12")] tls12::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - #[cfg(feature = "tls12")] tls12::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, #[cfg(feature = "tls12")] tls12::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, #[cfg(feature = "tls12")] tls12::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - #[cfg(feature = "tls12")] tls12::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, ]; diff --git a/rustls/src/lib.rs b/rustls/src/lib.rs index c083db3c..6447f406 100644 --- a/rustls/src/lib.rs +++ b/rustls/src/lib.rs @@ -266,6 +266,10 @@ //! Note that aws-lc-rs has additional build-time dependencies like cmake. //! See [the documentation](https://aws.github.io/aws-lc-rs/requirements/index.html) for details. //! +//! - `fips`: enable support for FIPS140-3-approved cryptography, via the aws-lc-rs crate. +//! This feature enables the `aws_lc_rs` feature, which makes the rustls crate depend +//! on [aws-lc-rs](https://github.com/aws/aws-lc-rs). +//! //! - `tls12` (enabled by default): enable support for TLS version 1.2. Note that, due to the //! additive nature of Cargo features and because it is enabled by default, other crates //! in your dependency graph could re-enable it for your application. If you want to disable diff --git a/rustls/src/server/server_conn.rs b/rustls/src/server/server_conn.rs index 3d048e61..10846f7f 100644 --- a/rustls/src/server/server_conn.rs +++ b/rustls/src/server/server_conn.rs @@ -1,6 +1,8 @@ use crate::builder::ConfigBuilder; use crate::common_state::{CommonState, Context, Protocol, Side, State}; use crate::conn::{ConnectionCommon, ConnectionCore, UnbufferedConnectionCommon}; +#[cfg(any(feature = "ring", feature = "fips"))] +use crate::crypto::default_provider; use crate::crypto::CryptoProvider; use crate::enums::{CipherSuite, ProtocolVersion, SignatureScheme}; use crate::error::Error; @@ -12,10 +14,10 @@ use crate::msgs::message::Message; use crate::suites::ExtractedSecrets; use crate::vecbuf::ChunkVecBuffer; use crate::verify; -#[cfg(feature = "ring")] +#[cfg(any(feature = "ring", feature = "fips"))] use crate::versions; use crate::KeyLog; -#[cfg(feature = "ring")] +#[cfg(any(feature = "ring", feature = "fips"))] use crate::WantsVerifier; use crate::{sign, WantsVersions}; @@ -341,31 +343,40 @@ impl Clone for ServerConfig { impl ServerConfig { /// Create a builder for a server configuration with the default - /// [`CryptoProvider`]: [`crypto::ring::default_provider`] and safe ciphersuite and protocol - /// defaults. + /// [`CryptoProvider`]. + /// + /// This is: + /// + /// - [`crypto::aws_lc_rs::default_provider`] if the `fips` crate feature is + /// enabled. + /// - [`crypto::ring::default_provider`] if the `ring` crate feature is + /// enabled and the `fips` crate feature is not enabled. + /// + /// If neither of these are true, this function is not available and you + /// must use [`ServerConfig::builder_with_provider()`] instead. /// /// For more information, see the [`ConfigBuilder`] documentation. - #[cfg(feature = "ring")] + #[cfg(any(feature = "ring", feature = "fips"))] pub fn builder() -> ConfigBuilder { - // Safety: we know the *ring* provider's ciphersuites are compatible with the safe default protocol versions. - Self::builder_with_provider(crate::crypto::ring::default_provider().into()) + // Safety: we know the *ring* and aws-lc-rs providers' ciphersuites are compatible with the safe default protocol versions. + Self::builder_with_provider(default_provider().into()) .with_safe_default_protocol_versions() .unwrap() } /// Create a builder for a server configuration with the default - /// [`CryptoProvider`]: [`crypto::ring::default_provider`], safe ciphersuite defaults and - /// the provided protocol versions. + /// [`CryptoProvider`] (see [`ServerConfig::builder()`] for details), safe + /// ciphersuite defaults and the provided protocol versions. /// /// Panics if provided an empty slice of supported versions. /// /// For more information, see the [`ConfigBuilder`] documentation. - #[cfg(feature = "ring")] + #[cfg(any(feature = "ring", feature = "fips"))] pub fn builder_with_protocol_versions( versions: &[&'static versions::SupportedProtocolVersion], ) -> ConfigBuilder { - // Safety: we know the *ring* provider's ciphersuites are compatible with all protocol version choices. - Self::builder_with_provider(crate::crypto::ring::default_provider().into()) + // Safety: we know the *ring* and aws-lc-rs providers' ciphersuites are compatible with all protocol version choices. + Self::builder_with_provider(default_provider().into()) .with_protocol_versions(versions) .unwrap() } diff --git a/rustls/tests/api.rs b/rustls/tests/api.rs index 1c4fdcb6..4ff22749 100644 --- a/rustls/tests/api.rs +++ b/rustls/tests/api.rs @@ -473,7 +473,7 @@ fn server_can_get_client_cert_after_resumption() { } #[test] -#[cfg(feature = "ring")] +#[cfg(all(feature = "ring", not(feature = "fips")))] fn test_config_builders_debug() { let b = ServerConfig::builder_with_provider( CryptoProvider { @@ -961,7 +961,7 @@ fn check_sigalgs_reduced_by_ciphersuite( fn server_cert_resolve_reduces_sigalgs_for_rsa_ciphersuite() { check_sigalgs_reduced_by_ciphersuite( KeyType::Rsa, - CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, vec![ SignatureScheme::RSA_PSS_SHA512, SignatureScheme::RSA_PSS_SHA384, @@ -978,9 +978,9 @@ fn server_cert_resolve_reduces_sigalgs_for_rsa_ciphersuite() { fn server_cert_resolve_reduces_sigalgs_for_ecdsa_ciphersuite() { check_sigalgs_reduced_by_ciphersuite( KeyType::EcdsaP256, - CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, vec![ - #[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] + #[cfg(any(feature = "fips", all(not(feature = "ring"), feature = "aws_lc_rs")))] SignatureScheme::ECDSA_NISTP521_SHA512, SignatureScheme::ECDSA_NISTP384_SHA384, SignatureScheme::ECDSA_NISTP256_SHA256, @@ -2891,6 +2891,7 @@ fn find_suite(suite: CipherSuite) -> SupportedCipherSuite { } static TEST_CIPHERSUITES: &[(&rustls::SupportedProtocolVersion, KeyType, CipherSuite)] = &[ + #[cfg(not(feature = "fips"))] ( &rustls::version::TLS13, KeyType::Rsa, @@ -2906,13 +2907,13 @@ static TEST_CIPHERSUITES: &[(&rustls::SupportedProtocolVersion, KeyType, CipherS KeyType::Rsa, CipherSuite::TLS13_AES_128_GCM_SHA256, ), - #[cfg(feature = "tls12")] + #[cfg(all(feature = "tls12", not(feature = "fips")))] ( &rustls::version::TLS12, KeyType::EcdsaP256, CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, ), - #[cfg(feature = "tls12")] + #[cfg(all(feature = "tls12", not(feature = "fips")))] ( &rustls::version::TLS12, KeyType::Rsa, @@ -2958,7 +2959,10 @@ fn negotiated_ciphersuite_default() { #[test] fn all_suites_covered() { - assert_eq!(provider::ALL_CIPHER_SUITES.len(), TEST_CIPHERSUITES.len()); + assert_eq!( + provider::DEFAULT_CIPHER_SUITES.len(), + TEST_CIPHERSUITES.len() + ); } #[test] @@ -5299,9 +5303,11 @@ fn test_secret_extraction_enabled() { for suite in [ cipher_suite::TLS13_AES_128_GCM_SHA256, cipher_suite::TLS13_AES_256_GCM_SHA384, + #[cfg(not(feature = "fips"))] cipher_suite::TLS13_CHACHA20_POLY1305_SHA256, cipher_suite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, cipher_suite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + #[cfg(not(feature = "fips"))] cipher_suite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, ] { let version = suite.version(); @@ -5706,26 +5712,38 @@ fn test_client_removes_tls12_session_if_server_sends_undecryptable_first_message )); } -#[cfg(feature = "ring")] +#[cfg(all(feature = "ring", not(feature = "fips")))] #[test] fn test_client_fips_service_indicator() { assert!(!make_client_config(KeyType::Rsa).fips()); } -#[cfg(feature = "ring")] +#[cfg(all(feature = "ring", not(feature = "fips")))] #[test] fn test_server_fips_service_indicator() { assert!(!make_server_config(KeyType::Rsa).fips()); } -#[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] +#[cfg(feature = "fips")] #[test] fn test_client_fips_service_indicator() { assert!(make_client_config(KeyType::Rsa).fips()); } -#[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] +#[cfg(feature = "fips")] #[test] fn test_server_fips_service_indicator() { assert!(make_server_config(KeyType::Rsa).fips()); } + +#[cfg(all(not(feature = "ring"), feature = "aws_lc_rs", not(feature = "fips")))] +#[test] +fn test_client_fips_service_indicator() { + assert!(!make_client_config(KeyType::Rsa).fips()); +} + +#[cfg(all(not(feature = "ring"), feature = "aws_lc_rs", not(feature = "fips")))] +#[test] +fn test_server_fips_service_indicator() { + assert!(!make_server_config(KeyType::Rsa).fips()); +} diff --git a/rustls/tests/common/mod.rs b/rustls/tests/common/mod.rs index be483749..bdf8c0bd 100644 --- a/rustls/tests/common/mod.rs +++ b/rustls/tests/common/mod.rs @@ -18,9 +18,9 @@ use rustls::RootCertStore; use rustls::{ClientConfig, ClientConnection}; use rustls::{ConnectionCommon, ServerConfig, ServerConnection, SideData}; -#[cfg(all(not(feature = "ring"), feature = "aws_lc_rs"))] +#[cfg(all(any(not(feature = "ring"), feature = "fips"), feature = "aws_lc_rs"))] pub use rustls::crypto::aws_lc_rs as provider; -#[cfg(feature = "ring")] +#[cfg(all(feature = "ring", not(feature = "fips")))] pub use rustls::crypto::ring as provider; use rustls::crypto::CryptoProvider; @@ -344,11 +344,11 @@ impl KeyType { pub fn server_config_builder() -> rustls::ConfigBuilder { // ensure `ServerConfig::builder()` is covered, even though it is // equivalent to `builder_with_provider(provider::provider().into())`. - #[cfg(feature = "ring")] + #[cfg(any(feature = "ring", feature = "fips"))] { rustls::ServerConfig::builder() } - #[cfg(not(feature = "ring"))] + #[cfg(all(not(feature = "ring"), not(feature = "fips")))] { rustls::ServerConfig::builder_with_provider(provider::default_provider().into()) .with_safe_default_protocol_versions() @@ -374,12 +374,11 @@ pub fn server_config_builder_with_versions( pub fn client_config_builder() -> rustls::ConfigBuilder { // ensure `ClientConfig::builder()` is covered, even though it is // equivalent to `builder_with_provider(provider::provider().into())`. - #[cfg(feature = "ring")] + #[cfg(any(feature = "ring", feature = "fips"))] { rustls::ClientConfig::builder() } - - #[cfg(not(feature = "ring"))] + #[cfg(all(not(feature = "ring"), not(feature = "fips")))] { rustls::ClientConfig::builder_with_provider(provider::default_provider().into()) .with_safe_default_protocol_versions()