Skip to content

Commit

Permalink
expose new FIPS related APIs
Browse files Browse the repository at this point in the history
* Ability to instantiate the FIPS default `crypto_provider` using a new
  function `rustls_default_fips_provider()`, available only when the
  fips feature is activated.

* Ability to determine if a given `crypto_provider` is in FIPS mode
  using a new function `rustls_crypto_provider_fips()`.

* Ability to determine if a given `rustls_client_config` would create
  connections that are FIPS compatible with a new function
  `rustls_client_config_fips()`.

* Ability to determine if a given `rustls_server_config` would create
  connections that are FIPS compatible with a new function
  `rustls_server_config_fips()`.

* Ability to determine if a given `rustls_connection` was created from
  a `rustls_client_config` or `rustls_server_config` that was FIPS
  enabled with a new function `rustls_connection_fips()`.
  • Loading branch information
cpu committed Nov 25, 2024
1 parent adb3ec4 commit 9df87dc
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 1 deletion.
3 changes: 2 additions & 1 deletion cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ include = ["rustls_tls_version"]
"feature = read_buf" = "DEFINE_READ_BUF"
"feature = aws-lc-rs" = "DEFINE_AWS_LC_RS"
"feature = ring" = "DEFINE_RING"
"feature = fips" = "DEFINE_FIPS"

[parse.expand]
crates = ["rustls-ffi"]
features = ["read_buf", "aws-lc-rs", "ring"]
features = ["read_buf", "aws-lc-rs", "ring", "fips"]
13 changes: 13 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,19 @@ impl rustls_client_config_builder {
}

impl rustls_client_config {
/// Returns true if a `rustls_connection` created from the `rustls_client_config` will
/// operate in FIPS mode.
///
/// This is different from `rustls_crypto_provider_fips` which is concerned
/// only with cryptography, whereas this also covers TLS-level configuration that NIST
/// recommends, as well as ECH HPKE suites if applicable.
#[no_mangle]
pub extern "C" fn rustls_client_config_fips(config: *const rustls_client_config) -> bool {
ffi_panic_boundary! {
try_ref_from_ptr!(config).fips()
}
}

/// "Free" a `rustls_client_config` previously returned from
/// `rustls_client_config_builder_build`.
///
Expand Down
17 changes: 17 additions & 0 deletions src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,23 @@ impl rustls_connection {
}
}

/// Returns true if the `rustls_connection` was made with a `rustls_client_config`
/// or `rustls_server_config` that is FIPS compatible.
///
/// This is different from `rustls_crypto_provider_fips` which is concerned
/// only with cryptography, whereas this also covers TLS-level configuration that NIST
/// recommends, as well as ECH HPKE suites if applicable.
#[no_mangle]
pub extern "C" fn rustls_connection_fips(conn: *const rustls_connection) -> bool {
ffi_panic_boundary! {
let conn = try_ref_from_ptr!(conn);
match &conn.conn {
rustls::Connection::Client(c) => c.fips(),
rustls::Connection::Server(c) => c.fips(),
}
}
}

/// Free a rustls_connection. Calling with NULL is fine.
/// Must not be called twice with the same value.
#[no_mangle]
Expand Down
33 changes: 33 additions & 0 deletions src/crypto_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,26 @@ pub extern "C" fn rustls_aws_lc_rs_crypto_provider() -> *const rustls_crypto_pro
}
}

/// Return a `rustls_crypto_provider` that uses FIPS140-3 approved cryptography.
///
/// Using this function expresses in your code that you require FIPS-approved cryptography,
/// and will not compile if you make a mistake with cargo features.
///
/// See the upstream [rustls FIPS documentation][FIPS] for more information.
///
/// The caller owns the returned `rustls_crypto_provider` and must free it using
/// `rustls_crypto_provider_free`.
///
/// [FIPS]: https://docs.rs/rustls/latest/rustls/manual/_06_fips/index.html
#[no_mangle]
#[cfg(feature = "fips")]
pub extern "C" fn rustls_default_fips_provider() -> *const rustls_crypto_provider {
ffi_panic_boundary! {
Arc::into_raw(Arc::new(rustls::crypto::default_fips_provider()))
as *const rustls_crypto_provider
}
}

/// Retrieve a pointer to the process default `rustls_crypto_provider`.
///
/// This may return `NULL` if no process default provider has been set using
Expand Down Expand Up @@ -364,6 +384,19 @@ pub extern "C" fn rustls_crypto_provider_random(
}
}

/// Returns true if the `rustls_crypto_provider` is operating in FIPS mode.
///
/// This covers only the cryptographic parts of FIPS approval. There are also
/// TLS protocol-level recommendations made by NIST. You should prefer to call
/// `rustls_client_config_fips` or `rustls_server_config_fips` which take these
/// into account.
#[no_mangle]
pub extern "C" fn rustls_crypto_provider_fips(provider: *const rustls_crypto_provider) -> bool {
ffi_panic_boundary! {
try_ref_from_ptr!(provider).fips()
}
}

/// Frees the `rustls_crypto_provider`.
///
/// Calling with `NULL` is fine.
Expand Down
57 changes: 57 additions & 0 deletions src/rustls.h
Original file line number Diff line number Diff line change
Expand Up @@ -1758,6 +1758,16 @@ rustls_result rustls_client_config_builder_build(struct rustls_client_config_bui
*/
void rustls_client_config_builder_free(struct rustls_client_config_builder *config);

/**
* Returns true if a `rustls_connection` created from the `rustls_client_config` will
* operate in FIPS mode.
*
* This is different from `rustls_crypto_provider_fips` which is concerned
* only with cryptography, whereas this also covers TLS-level configuration that NIST
* recommends, as well as ECH HPKE suites if applicable.
*/
bool rustls_client_config_fips(const struct rustls_client_config *config);

/**
* "Free" a `rustls_client_config` previously returned from
* `rustls_client_config_builder_build`.
Expand Down Expand Up @@ -2047,6 +2057,16 @@ rustls_result rustls_connection_read_2(struct rustls_connection *conn,
size_t *out_n);
#endif

/**
* Returns true if the `rustls_connection` was made with a `rustls_client_config`
* or `rustls_server_config` that is FIPS compatible.
*
* This is different from `rustls_crypto_provider_fips` which is concerned
* only with cryptography, whereas this also covers TLS-level configuration that NIST
* recommends, as well as ECH HPKE suites if applicable.
*/
bool rustls_connection_fips(const struct rustls_connection *conn);

/**
* Free a rustls_connection. Calling with NULL is fine.
* Must not be called twice with the same value.
Expand Down Expand Up @@ -2172,6 +2192,23 @@ const struct rustls_crypto_provider *rustls_ring_crypto_provider(void);
const struct rustls_crypto_provider *rustls_aws_lc_rs_crypto_provider(void);
#endif

#if defined(DEFINE_FIPS)
/**
* Return a `rustls_crypto_provider` that uses FIPS140-3 approved cryptography.
*
* Using this function expresses in your code that you require FIPS-approved cryptography,
* and will not compile if you make a mistake with cargo features.
*
* See the upstream [rustls FIPS documentation][FIPS] for more information.
*
* The caller owns the returned `rustls_crypto_provider` and must free it using
* `rustls_crypto_provider_free`.
*
* [FIPS]: https://docs.rs/rustls/latest/rustls/manual/_06_fips/index.html
*/
const struct rustls_crypto_provider *rustls_default_fips_provider(void);
#endif

/**
* Retrieve a pointer to the process default `rustls_crypto_provider`.
*
Expand Down Expand Up @@ -2233,6 +2270,16 @@ rustls_result rustls_crypto_provider_random(const struct rustls_crypto_provider
uint8_t *buff,
size_t len);

/**
* Returns true if the `rustls_crypto_provider` is operating in FIPS mode.
*
* This covers only the cryptographic parts of FIPS approval. There are also
* TLS protocol-level recommendations made by NIST. You should prefer to call
* `rustls_client_config_fips` or `rustls_server_config_fips` which take these
* into account.
*/
bool rustls_crypto_provider_fips(const struct rustls_crypto_provider *provider);

/**
* Frees the `rustls_crypto_provider`.
*
Expand Down Expand Up @@ -2497,6 +2544,16 @@ rustls_result rustls_server_config_builder_set_certified_keys(struct rustls_serv
rustls_result rustls_server_config_builder_build(struct rustls_server_config_builder *builder,
const struct rustls_server_config **config_out);

/**
* Returns true if a `rustls_connection` created from the `rustls_server_config` will
* operate in FIPS mode.
*
* This is different from `rustls_crypto_provider_fips` which is concerned
* only with cryptography, whereas this also covers TLS-level configuration that NIST
* recommends, as well as ECH HPKE suites if applicable.
*/
bool rustls_server_config_fips(const struct rustls_server_config *config);

/**
* "Free" a rustls_server_config previously returned from
* rustls_server_config_builder_build.
Expand Down
13 changes: 13 additions & 0 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,19 @@ impl rustls_server_config_builder {
}

impl rustls_server_config {
/// Returns true if a `rustls_connection` created from the `rustls_server_config` will
/// operate in FIPS mode.
///
/// This is different from `rustls_crypto_provider_fips` which is concerned
/// only with cryptography, whereas this also covers TLS-level configuration that NIST
/// recommends, as well as ECH HPKE suites if applicable.
#[no_mangle]
pub extern "C" fn rustls_server_config_fips(config: *const rustls_server_config) -> bool {
ffi_panic_boundary! {
try_ref_from_ptr!(config).fips()
}
}

/// "Free" a rustls_server_config previously returned from
/// rustls_server_config_builder_build.
///
Expand Down

0 comments on commit 9df87dc

Please sign in to comment.