Add feature "fips-no-compat"

As of boringSSL commit a430310d6563c0734ddafca7731570dfb683dc19, we no
longer need to make exceptions for the types of BufLen, ProtosLen, and
ValueLen, which means the "fips-compat" feature is no longer needed for
"fips" users.

Currently "fips" implies "fips-compat". To allow users to upgrade
without breaking API compatibility with boring version 4, add a new
feature, "fips-no-compat", that does not imply "fips-compat".

In boring 5, we should remove "fips-no-compat" and decouple
"fips-compat" from "fips".
This commit is contained in:
Christopher Patton 2025-03-14 10:57:02 -07:00 committed by Kornel
parent dde4b9ccde
commit c774afc859
8 changed files with 52 additions and 14 deletions

View File

@ -760,7 +760,7 @@ fn main() {
"des.h", "des.h",
"dtls1.h", "dtls1.h",
"hkdf.h", "hkdf.h",
#[cfg(not(feature = "fips"))] #[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
"hpke.h", "hpke.h",
"hmac.h", "hmac.h",
"hrss.h", "hrss.h",

View File

@ -19,9 +19,19 @@ rustdoc-args = ["--cfg", "docsrs"]
[features] [features]
# Controlling the build # Controlling the build
# Use a FIPS-validated version of boringssl. # Use a FIPS-validated version of BoringSSL. This feature sets "fips-compat".
fips = ["fips-compat", "boring-sys/fips"] fips = ["fips-compat", "boring-sys/fips"]
# Use a FIPS build of BoringSSL, but don't set "fips-compat".
#
# As of boringSSL commit a430310d6563c0734ddafca7731570dfb683dc19, we no longer
# need to make exceptions for the types of BufLen, ProtosLen, and ValueLen,
# which means the "fips-compat" feature is no longer needed.
#
# TODO(cjpatton) Delete this feature and modify "fips" so that it doesn't imply
# "fips-compat".
fips-no-compat = ["boring-sys/fips"]
# Build with compatibility for the BoringSSL FIPS version, without enabling the # Build with compatibility for the BoringSSL FIPS version, without enabling the
# `fips` feature itself (useful e.g. if `fips-link-precompiled` is used with an # `fips` feature itself (useful e.g. if `fips-link-precompiled` is used with an
# older BoringSSL version). # older BoringSSL version).

View File

@ -14,8 +14,16 @@ pub fn enabled() -> bool {
#[test] #[test]
fn is_enabled() { fn is_enabled() {
#[cfg(any(feature = "fips", feature = "fips-link-precompiled"))] #[cfg(any(
feature = "fips",
feature = "fips-no-compat",
feature = "fips-link-precompiled"
))]
assert!(enabled()); assert!(enabled());
#[cfg(not(any(feature = "fips", feature = "fips-link-precompiled")))] #[cfg(not(any(
feature = "fips",
feature = "fips-no-compat",
feature = "fips-link-precompiled"
)))]
assert!(!enabled()); assert!(!enabled());
} }

View File

@ -128,7 +128,7 @@ pub mod error;
pub mod ex_data; pub mod ex_data;
pub mod fips; pub mod fips;
pub mod hash; pub mod hash;
#[cfg(not(feature = "fips"))] #[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
pub mod hpke; pub mod hpke;
pub mod memcmp; pub mod memcmp;
pub mod nid; pub mod nid;

View File

@ -104,7 +104,7 @@ pub use self::async_callbacks::{
pub use self::connector::{ pub use self::connector::{
ConnectConfiguration, SslAcceptor, SslAcceptorBuilder, SslConnector, SslConnectorBuilder, ConnectConfiguration, SslAcceptor, SslAcceptorBuilder, SslConnector, SslConnectorBuilder,
}; };
#[cfg(not(feature = "fips"))] #[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
pub use self::ech::{SslEchKeys, SslEchKeysRef}; pub use self::ech::{SslEchKeys, SslEchKeysRef};
pub use self::error::{Error, ErrorCode, HandshakeError}; pub use self::error::{Error, ErrorCode, HandshakeError};
@ -112,7 +112,7 @@ mod async_callbacks;
mod bio; mod bio;
mod callbacks; mod callbacks;
mod connector; mod connector;
#[cfg(not(feature = "fips"))] #[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
mod ech; mod ech;
mod error; mod error;
mod mut_only; mod mut_only;
@ -714,7 +714,7 @@ impl SslCurve {
pub const X25519: SslCurve = SslCurve(ffi::SSL_CURVE_X25519 as _); pub const X25519: SslCurve = SslCurve(ffi::SSL_CURVE_X25519 as _);
#[cfg(not(feature = "fips"))] #[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
pub const X25519_KYBER768_DRAFT00: SslCurve = pub const X25519_KYBER768_DRAFT00: SslCurve =
SslCurve(ffi::SSL_CURVE_X25519_KYBER768_DRAFT00 as _); SslCurve(ffi::SSL_CURVE_X25519_KYBER768_DRAFT00 as _);
@ -759,7 +759,7 @@ impl SslCurve {
ffi::SSL_CURVE_SECP384R1 => Some(ffi::NID_secp384r1), ffi::SSL_CURVE_SECP384R1 => Some(ffi::NID_secp384r1),
ffi::SSL_CURVE_SECP521R1 => Some(ffi::NID_secp521r1), ffi::SSL_CURVE_SECP521R1 => Some(ffi::NID_secp521r1),
ffi::SSL_CURVE_X25519 => Some(ffi::NID_X25519), ffi::SSL_CURVE_X25519 => Some(ffi::NID_X25519),
#[cfg(not(feature = "fips"))] #[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
ffi::SSL_CURVE_X25519_KYBER768_DRAFT00 => Some(ffi::NID_X25519Kyber768Draft00), ffi::SSL_CURVE_X25519_KYBER768_DRAFT00 => Some(ffi::NID_X25519Kyber768Draft00),
#[cfg(feature = "pq-experimental")] #[cfg(feature = "pq-experimental")]
ffi::SSL_CURVE_X25519_KYBER768_DRAFT00_OLD => Some(ffi::NID_X25519Kyber768Draft00Old), ffi::SSL_CURVE_X25519_KYBER768_DRAFT00_OLD => Some(ffi::NID_X25519Kyber768Draft00Old),
@ -2010,7 +2010,7 @@ impl SslContextBuilder {
/// ECHConfigs to allow stale DNS caches to update. Unlike most `SSL_CTX` APIs, this function /// ECHConfigs to allow stale DNS caches to update. Unlike most `SSL_CTX` APIs, this function
/// is safe to call even after the `SSL_CTX` has been associated with connections on various /// is safe to call even after the `SSL_CTX` has been associated with connections on various
/// threads. /// threads.
#[cfg(not(feature = "fips"))] #[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
#[corresponds(SSL_CTX_set1_ech_keys)] #[corresponds(SSL_CTX_set1_ech_keys)]
pub fn set_ech_keys(&self, keys: &SslEchKeys) -> Result<(), ErrorStack> { pub fn set_ech_keys(&self, keys: &SslEchKeys) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_CTX_set1_ech_keys(self.as_ptr(), keys.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::SSL_CTX_set1_ech_keys(self.as_ptr(), keys.as_ptr())).map(|_| ()) }
@ -2267,7 +2267,7 @@ impl SslContextRef {
/// ECHConfigs to allow stale DNS caches to update. Unlike most `SSL_CTX` APIs, this function /// ECHConfigs to allow stale DNS caches to update. Unlike most `SSL_CTX` APIs, this function
/// is safe to call even after the `SSL_CTX` has been associated with connections on various /// is safe to call even after the `SSL_CTX` has been associated with connections on various
/// threads. /// threads.
#[cfg(not(feature = "fips"))] #[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
#[corresponds(SSL_CTX_set1_ech_keys)] #[corresponds(SSL_CTX_set1_ech_keys)]
pub fn set_ech_keys(&self, keys: &SslEchKeys) -> Result<(), ErrorStack> { pub fn set_ech_keys(&self, keys: &SslEchKeys) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::SSL_CTX_set1_ech_keys(self.as_ptr(), keys.as_ptr())).map(|_| ()) } unsafe { cvt(ffi::SSL_CTX_set1_ech_keys(self.as_ptr(), keys.as_ptr())).map(|_| ()) }

View File

@ -21,13 +21,13 @@ use crate::ssl::{
use crate::x509::verify::X509CheckFlags; use crate::x509::verify::X509CheckFlags;
use crate::x509::{X509Name, X509}; use crate::x509::{X509Name, X509};
#[cfg(not(feature = "fips"))] #[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
use super::CompliancePolicy; use super::CompliancePolicy;
mod cert_compressor; mod cert_compressor;
mod cert_verify; mod cert_verify;
mod custom_verify; mod custom_verify;
#[cfg(not(feature = "fips"))] #[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
mod ech; mod ech;
mod private_key_method; mod private_key_method;
mod server; mod server;
@ -990,7 +990,7 @@ fn test_get_ciphers() {
} }
#[test] #[test]
#[cfg(not(feature = "fips"))] #[cfg(not(any(feature = "fips", feature = "fips-no-compat")))]
fn test_set_compliance() { fn test_set_compliance() {
let mut ctx = SslContext::builder(SslMethod::tls()).unwrap(); let mut ctx = SslContext::builder(SslMethod::tls()).unwrap();
ctx.set_compliance_policy(CompliancePolicy::FIPS_202205) ctx.set_compliance_policy(CompliancePolicy::FIPS_202205)

View File

@ -23,6 +23,16 @@ runtime = ["hyper_old/runtime"]
# Use a FIPS-validated version of boringssl. # Use a FIPS-validated version of boringssl.
fips = ["tokio-boring/fips"] fips = ["tokio-boring/fips"]
# Use a FIPS build of BoringSSL, but don't set "fips-compat".
#
# As of boringSSL commit a430310d6563c0734ddafca7731570dfb683dc19, we no longer
# need to make exceptions for the types of BufLen, ProtosLen, and ValueLen,
# which means the "fips-compat" feature is no longer needed.
#
# TODO(cjpatton) Delete this feature and modify "fips" so that it doesn't imply
# "fips-compat".
fips-no-compat = ["tokio-boring/fips-no-compat"]
# Link with precompiled FIPS-validated `bcm.o` module. # Link with precompiled FIPS-validated `bcm.o` module.
fips-link-precompiled = ["tokio-boring/fips-link-precompiled"] fips-link-precompiled = ["tokio-boring/fips-link-precompiled"]

View File

@ -19,6 +19,16 @@ rustdoc-args = ["--cfg", "docsrs"]
# Use a FIPS-validated version of boringssl. # Use a FIPS-validated version of boringssl.
fips = ["boring/fips", "boring-sys/fips"] fips = ["boring/fips", "boring-sys/fips"]
# Use a FIPS build of BoringSSL, but don't set "fips-compat".
#
# As of boringSSL commit a430310d6563c0734ddafca7731570dfb683dc19, we no longer
# need to make exceptions for the types of BufLen, ProtosLen, and ValueLen,
# which means the "fips-compat" feature is no longer needed.
#
# TODO(cjpatton) Delete this feature and modify "fips" so that it doesn't imply
# "fips-compat".
fips-no-compat = ["boring/fips-no-compat"]
# Link with precompiled FIPS-validated `bcm.o` module. # Link with precompiled FIPS-validated `bcm.o` module.
fips-link-precompiled = ["boring/fips-link-precompiled", "boring-sys/fips-link-precompiled"] fips-link-precompiled = ["boring/fips-link-precompiled", "boring-sys/fips-link-precompiled"]