Skip to content

Commit

Permalink
Move FIPS enablement to Rust (#10433)
Browse files Browse the repository at this point in the history
  • Loading branch information
alex authored Feb 20, 2024
1 parent 8224447 commit 9db55b5
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 75 deletions.
2 changes: 0 additions & 2 deletions src/_cffi_src/build_openssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
modules=[
# This goes first so we can define some cryptography-wide symbols.
"cryptography",
# Provider comes early as well so we define OSSL_LIB_CTX
"provider",
"asn1",
"bignum",
"bio",
Expand Down
10 changes: 0 additions & 10 deletions src/_cffi_src/openssl/evp.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
static const int EVP_MAX_MD_SIZE;
static const int Cryptography_HAS_EVP_PKEY_DHX;
static const long Cryptography_HAS_300_FIPS;
"""

FUNCTIONS = """
Expand Down Expand Up @@ -60,8 +59,6 @@
int EVP_PKEY_bits(const EVP_PKEY *);
int EVP_PKEY_assign_RSA(EVP_PKEY *, RSA *);
int EVP_default_properties_enable_fips(OSSL_LIB_CTX *, int);
"""

CUSTOMIZATIONS = """
Expand All @@ -70,11 +67,4 @@
#else
const long Cryptography_HAS_EVP_PKEY_DHX = 0;
#endif
#if CRYPTOGRAPHY_OPENSSL_300_OR_GREATER
static const long Cryptography_HAS_300_FIPS = 1;
#else
static const long Cryptography_HAS_300_FIPS = 0;
int (*EVP_default_properties_enable_fips)(OSSL_LIB_CTX *, int) = NULL;
#endif
"""
36 changes: 0 additions & 36 deletions src/_cffi_src/openssl/provider.py

This file was deleted.

4 changes: 4 additions & 0 deletions src/cryptography/hazmat/bindings/_rust/openssl/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,17 @@ CRYPTOGRAPHY_IS_BORINGSSL: bool
CRYPTOGRAPHY_OPENSSL_300_OR_GREATER: bool
CRYPTOGRAPHY_OPENSSL_320_OR_GREATER: bool

class Providers: ...

_legacy_provider_loaded: bool
_providers: Providers

def openssl_version() -> int: ...
def openssl_version_text() -> str: ...
def raise_openssl_error() -> typing.NoReturn: ...
def capture_error_stack() -> list[OpenSSLError]: ...
def is_fips_enabled() -> bool: ...
def enable_fips(providers: Providers) -> None: ...

class OpenSSLError:
@property
Expand Down
15 changes: 0 additions & 15 deletions src/cryptography/hazmat/bindings/openssl/_conditional.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,6 @@ def cryptography_has_srtp() -> list[str]:
]


def cryptography_has_providers() -> list[str]:
return [
"OSSL_PROVIDER_load",
"OSSL_PROVIDER_unload",
]


def cryptography_has_op_no_renegotiation() -> list[str]:
return [
"SSL_OP_NO_RENEGOTIATION",
Expand All @@ -128,12 +121,6 @@ def cryptography_has_dtls_get_data_mtu() -> list[str]:
]


def cryptography_has_300_fips() -> list[str]:
return [
"EVP_default_properties_enable_fips",
]


def cryptography_has_ssl_cookie() -> list[str]:
return [
"SSL_OP_COOKIE_EXCHANGE",
Expand Down Expand Up @@ -191,12 +178,10 @@ def cryptography_has_get_extms_support() -> list[str]:
"Cryptography_HAS_ENGINE": cryptography_has_engine,
"Cryptography_HAS_VERIFIED_CHAIN": cryptography_has_verified_chain,
"Cryptography_HAS_SRTP": cryptography_has_srtp,
"Cryptography_HAS_PROVIDERS": cryptography_has_providers,
"Cryptography_HAS_OP_NO_RENEGOTIATION": (
cryptography_has_op_no_renegotiation
),
"Cryptography_HAS_DTLS_GET_DATA_MTU": cryptography_has_dtls_get_data_mtu,
"Cryptography_HAS_300_FIPS": cryptography_has_300_fips,
"Cryptography_HAS_SSL_COOKIE": cryptography_has_ssl_cookie,
"Cryptography_HAS_PKCS7_FUNCS": cryptography_has_pkcs7_funcs,
"Cryptography_HAS_PRIME_CHECKS": cryptography_has_prime_checks,
Expand Down
11 changes: 1 addition & 10 deletions src/cryptography/hazmat/bindings/openssl/binding.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,7 @@ def __init__(self) -> None:
self._ensure_ffi_initialized()

def _enable_fips(self) -> None:
# This function enables FIPS mode for OpenSSL 3.0.0 on installs that
# have the FIPS provider installed properly.
_openssl_assert(openssl.CRYPTOGRAPHY_OPENSSL_300_OR_GREATER)
self.lib._fips_provider = self.lib.OSSL_PROVIDER_load(
self.ffi.NULL, b"fips"
)
_openssl_assert(self.lib._fips_provider != self.ffi.NULL)

res = self.lib.EVP_default_properties_enable_fips(self.ffi.NULL, 1)
_openssl_assert(res == 1)
openssl.enable_fips(openssl._providers)

@classmethod
def _ensure_ffi_initialized(cls) -> None:
Expand Down
12 changes: 12 additions & 0 deletions src/rust/cryptography-openssl/src/fips.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

#[cfg(CRYPTOGRAPHY_OPENSSL_300_OR_GREATER)]
use crate::{cvt, OpenSSLResult};
#[cfg(all(
CRYPTOGRAPHY_OPENSSL_300_OR_GREATER,
not(any(CRYPTOGRAPHY_IS_LIBRESSL, CRYPTOGRAPHY_IS_BORINGSSL))
Expand All @@ -22,3 +24,13 @@ pub fn is_enabled() -> bool {
}
}
}

#[cfg(CRYPTOGRAPHY_OPENSSL_300_OR_GREATER)]
pub fn enable() -> OpenSSLResult<()> {
// SAFETY: No pre-conditions
unsafe {
cvt(ffi::EVP_default_properties_enable_fips(ptr::null_mut(), 1))?;
}

Ok(())
}
20 changes: 18 additions & 2 deletions src/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ pub(crate) mod types;
mod x509;

#[cfg(CRYPTOGRAPHY_OPENSSL_300_OR_GREATER)]
#[pyo3::prelude::pyclass(frozen, module = "cryptography.hazmat.bindings._rust")]
#[pyo3::prelude::pyclass(module = "cryptography.hazmat.bindings._rust")]
struct LoadedProviders {
legacy: Option<provider::Provider>,
_default: provider::Provider,

fips: Option<provider::Provider>,
}

#[pyo3::prelude::pyfunction]
Expand Down Expand Up @@ -63,7 +65,11 @@ fn _initialize_providers() -> CryptographyResult<LoadedProviders> {
None
};
let _default = provider::Provider::load(None, "default")?;
Ok(LoadedProviders { legacy, _default })
Ok(LoadedProviders {
legacy,
_default,
fips: None,
})
}

fn _legacy_provider_error(success: bool) -> pyo3::PyResult<()> {
Expand All @@ -75,6 +81,14 @@ fn _legacy_provider_error(success: bool) -> pyo3::PyResult<()> {
Ok(())
}

#[cfg(CRYPTOGRAPHY_OPENSSL_300_OR_GREATER)]
#[pyo3::prelude::pyfunction]
fn enable_fips(providers: &mut LoadedProviders) -> CryptographyResult<()> {
providers.fips = Some(provider::Provider::load(None, "fips")?);
cryptography_openssl::fips::enable()?;
Ok(())
}

#[pyo3::prelude::pymodule]
fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()> {
m.add_function(pyo3::wrap_pyfunction!(padding::check_pkcs7_padding, m)?)?;
Expand Down Expand Up @@ -124,6 +138,8 @@ fn _rust(py: pyo3::Python<'_>, m: &pyo3::types::PyModule) -> pyo3::PyResult<()>
openssl_mod.add("_legacy_provider_loaded", false)?;
}
openssl_mod.add("_providers", providers)?;

openssl_mod.add_function(pyo3::wrap_pyfunction!(enable_fips, m)?)?;
} else {
// default value for non-openssl 3+
openssl_mod.add("_legacy_provider_loaded", false)?;
Expand Down

0 comments on commit 9db55b5

Please sign in to comment.