From 8604442dc3f5778fb02089fd74230b8cd73a82b4 Mon Sep 17 00:00:00 2001 From: toidiu Date: Wed, 1 May 2024 01:04:21 -0700 Subject: [PATCH] feat[bindings]: fips feature flag (#4527) --- .github/workflows/ci_rust.yml | 43 +++++++++++++++++-- .../rust/s2n-tls-sys/templates/Cargo.template | 1 + bindings/rust/s2n-tls/Cargo.toml | 1 + bindings/rust/s2n-tls/src/enums.rs | 27 ++++++++++++ bindings/rust/s2n-tls/src/init.rs | 20 ++++++++- bindings/rust/s2n-tls/src/testing/s2n_tls.rs | 9 ++++ 6 files changed, 97 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci_rust.yml b/.github/workflows/ci_rust.yml index 4c01534e9c4..39191005f66 100644 --- a/.github/workflows/ci_rust.yml +++ b/.github/workflows/ci_rust.yml @@ -31,6 +31,13 @@ jobs: rustup toolchain install stable rustup override set stable + # https://github.com/aws/aws-lc-rs/blob/main/aws-lc-fips-sys/README.md#build-prerequisites + # go required to build aws-lc-rs in FIPS mode + - name: Install go + uses: actions/setup-go@v4 + with: + go-version: '>=1.18' + - uses: camshaft/rust-cache@v1 - name: Generate @@ -84,7 +91,7 @@ jobs: - name: bench tests working-directory: ${{env.ROOT_PATH}}/bench run: cargo test - + s2n-tls-binding-examples: runs-on: ubuntu-latest steps: @@ -95,7 +102,7 @@ jobs: run: | rustup toolchain install stable rustup override set stable - + - name: generate bindings run: ${{env.ROOT_PATH}}/generate.sh --skip-tests @@ -150,6 +157,36 @@ jobs: working-directory: ${{env.ROOT_PATH}} run: cargo test --all-features + fips: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: true + + - name: Install Rust toolchain + id: toolchain + run: | + rustup toolchain install stable + rustup override set stable + + # https://github.com/aws/aws-lc-rs/blob/main/aws-lc-fips-sys/README.md#build-prerequisites + # go required to build aws-lc-rs in FIPS mode + - name: Install go + uses: actions/setup-go@v4 + with: + go-version: '>=1.18' + + - uses: camshaft/rust-cache@v1 + + - name: Generate + run: ./${{env.ROOT_PATH}}/generate.sh + + - name: Test fips + working-directory: ${{env.ROOT_PATH}} + run: | + cargo test --features fips + rustfmt: runs-on: ubuntu-latest steps: @@ -168,7 +205,7 @@ jobs: # We don't need to format the generated files, # but if they don't exist other code breaks. - name: Generate - run: ./${{env.ROOT_PATH}}/generate.sh + run: ./${{env.ROOT_PATH}}/generate.sh --skip-tests - name: Run cargo fmt run: | diff --git a/bindings/rust/s2n-tls-sys/templates/Cargo.template b/bindings/rust/s2n-tls-sys/templates/Cargo.template index eb29432bd9a..6d46ff15a6a 100644 --- a/bindings/rust/s2n-tls-sys/templates/Cargo.template +++ b/bindings/rust/s2n-tls-sys/templates/Cargo.template @@ -27,6 +27,7 @@ default = [] # preserve the cmake feature in case any consumers had it enabled before cmake = [] quic = [] +fips = ["aws-lc-rs/fips"] pq = [] internal = [] stacktrace = [] diff --git a/bindings/rust/s2n-tls/Cargo.toml b/bindings/rust/s2n-tls/Cargo.toml index 93154ce6255..8bd197d4052 100644 --- a/bindings/rust/s2n-tls/Cargo.toml +++ b/bindings/rust/s2n-tls/Cargo.toml @@ -13,6 +13,7 @@ default = [] unstable-fingerprint = ["s2n-tls-sys/unstable-fingerprint"] unstable-ktls = ["s2n-tls-sys/unstable-ktls"] quic = ["s2n-tls-sys/quic"] +fips = ["s2n-tls-sys/fips"] pq = ["s2n-tls-sys/pq"] testing = ["bytes"] diff --git a/bindings/rust/s2n-tls/src/enums.rs b/bindings/rust/s2n-tls/src/enums.rs index d642a7630ce..70b22019a3b 100644 --- a/bindings/rust/s2n-tls/src/enums.rs +++ b/bindings/rust/s2n-tls/src/enums.rs @@ -31,6 +31,33 @@ impl From> for CallbackResult { } } +#[non_exhaustive] +#[derive(Debug, PartialEq, Copy, Clone)] +pub enum FipsMode { + Disabled, + Enabled, +} + +impl FipsMode { + pub fn is_enabled(&self) -> bool { + matches!(self, FipsMode::Enabled) + } +} + +impl TryFrom for FipsMode { + type Error = Error; + + fn try_from(input: s2n_fips_mode::Type) -> Result { + let mode = match input { + s2n_fips_mode::FIPS_MODE_DISABLED => FipsMode::Disabled, + s2n_fips_mode::FIPS_MODE_ENABLED => FipsMode::Enabled, + _ => return Err(Error::INVALID_INPUT), + }; + + Ok(mode) + } +} + #[derive(Debug, PartialEq, Copy, Clone)] pub enum Mode { Server, diff --git a/bindings/rust/s2n-tls/src/init.rs b/bindings/rust/s2n-tls/src/init.rs index bcda62aa5da..96b5c3088d9 100644 --- a/bindings/rust/s2n-tls/src/init.rs +++ b/bindings/rust/s2n-tls/src/init.rs @@ -1,7 +1,10 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use crate::error::{Error, Fallible}; +use crate::{ + enums::FipsMode, + error::{Error, Fallible}, +}; use s2n_tls_sys::*; use std::sync::Once; @@ -40,6 +43,21 @@ pub fn init() { S2N_THREAD.with(|_| ()); } +/// Determines whether s2n-tls is operating in FIPS mode. +/// +/// It is possible to enable FIPS mode by enabling the `fips` feature flag. +/// +/// s2n-tls MUST be linked to a FIPS libcrypto and MUST be in FIPS mode in order to comply with +/// FIPS requirements. Applications desiring FIPS compliance should use this API to ensure that +/// s2n-tls has been properly linked with a FIPS libcrypto and has successfully entered FIPS mode. +pub fn fips_mode() -> Result { + let mut fips_mode = s2n_fips_mode::FIPS_MODE_DISABLED; + unsafe { + s2n_get_fips_mode(&mut fips_mode as *mut _).into_result()?; + } + fips_mode.try_into() +} + mod mem { use super::*; use alloc::alloc::{alloc, dealloc, Layout}; diff --git a/bindings/rust/s2n-tls/src/testing/s2n_tls.rs b/bindings/rust/s2n-tls/src/testing/s2n_tls.rs index 962370e57e3..4f186c3c020 100644 --- a/bindings/rust/s2n-tls/src/testing/s2n_tls.rs +++ b/bindings/rust/s2n-tls/src/testing/s2n_tls.rs @@ -961,4 +961,13 @@ mod tests { Ok(()) } + + #[cfg(feature = "fips")] + #[test] + fn test_fips_mode() { + use crate::init; + + init::init(); + assert!(init::fips_mode().unwrap().is_enabled()); + } }