Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,10 @@ jobs:
run: rustup update ${{ matrix.rust }} --no-self-update && rustup default ${{ matrix.rust }}
shell: bash
- run: rustup target add ${{ matrix.target }}
- name: Install golang
uses: actions/setup-go@v5
with:
go-version: '>=1.22.0'
- name: Install target-specific APT dependencies
if: "matrix.apt_packages != ''"
run: sudo apt update && sudo apt install -y ${{ matrix.apt_packages }}
Expand Down Expand Up @@ -255,18 +259,10 @@ jobs:
- name: Install Rust (rustup)
run: rustup update stable --no-self-update && rustup default stable
shell: bash
- name: Install Clang-12
uses: KyleMayes/install-llvm-action@v1
with:
version: "12.0.0"
directory: ${{ runner.temp }}/llvm
- name: Install golang
uses: actions/setup-go@v5
with:
go-version: '>=1.22.0'
- name: Add clang++-12 link
working-directory: ${{ runner.temp }}/llvm/bin
run: ln -s clang clang++-12
- name: Run tests
run: cargo test --features fips
- name: Test boring-sys cargo publish (FIPS)
Expand Down Expand Up @@ -296,6 +292,10 @@ jobs:
- name: Install Rust (rustup)
run: rustup update stable --no-self-update && rustup default stable && rustup target add ${{ matrix.target }}
shell: bash
- name: Install golang
uses: actions/setup-go@v5
with:
go-version: '>=1.22.0'
- name: Install ${{ matrix.target }} toolchain
run: brew tap messense/macos-cross-toolchains && brew install ${{ matrix.target }}
- name: Set BORING_BSSL_SYSROOT
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,3 @@
path = boring-sys/deps/boringssl
url = https://github.com/google/boringssl.git
ignore = dirty
[submodule "boring-sys/deps/boringssl-fips"]
path = boring-sys/deps/boringssl-fips
url = https://github.com/google/boringssl.git
41 changes: 10 additions & 31 deletions boring-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,22 @@ include = [
"/*.toml",
"/LICENSE-MIT",
"/cmake/*.cmake",
# boringssl (non-FIPS)
"/deps/boringssl/src/util/32-bit-toolchain.cmake",
"/deps/boringssl/**/*.[chS]",
"/deps/boringssl/**/*.asm",
"/deps/boringssl/sources.json",
"/deps/boringssl/src/crypto/obj/obj_mac.num",
"/deps/boringssl/src/crypto/obj/objects.txt",
"/deps/boringssl/**/*.pl",
"/deps/boringssl/**/*.go",
"/deps/boringssl/**/*.cmake",
"/deps/boringssl/**/go.mod",
"/deps/boringssl/**/go.sum",
"/deps/boringssl/crypto/obj/obj_mac.num",
"/deps/boringssl/crypto/obj/objects.txt",
"/deps/boringssl/crypto/err/*.errordata",
"/deps/boringssl/**/*.bzl",
"/deps/boringssl/src/**/*.cc",
"/deps/boringssl/**/*.cc",
"/deps/boringssl/**/CMakeLists.txt",
"/deps/boringssl/**/sources.cmake",
"/deps/boringssl/**/util/go_tests.txt",
"/deps/boringssl/LICENSE",
# boringssl (FIPS)
"/deps/boringssl-fips/src/util/32-bit-toolchain.cmake",
"/deps/boringssl-fips/**/*.[chS]",
"/deps/boringssl-fips/**/*.asm",
"/deps/boringssl-fips/**/*.pl",
"/deps/boringssl-fips/**/*.go",
"/deps/boringssl-fips/**/go.mod",
"/deps/boringssl-fips/**/go.sum",
"/deps/boringssl-fips/sources.json",
"/deps/boringssl-fips/crypto/obj/obj_mac.num",
"/deps/boringssl-fips/crypto/obj/objects.txt",
"/deps/boringssl-fips/crypto/err/*.errordata",
"/deps/boringssl-fips/**/*.bzl",
"/deps/boringssl-fips/**/*.cc",
"/deps/boringssl-fips/**/CMakeLists.txt",
"/deps/boringssl-fips/**/sources.cmake",
"/deps/boringssl-fips/LICENSE",
"/build/*",
"/src",
"/patches",
Expand All @@ -66,14 +53,6 @@ rustdoc-args = ["--cfg", "docsrs"]
# for instructions and more details on the boringssl FIPS flag.
fips = []

# Use a precompiled FIPS-validated version of BoringSSL. Meant to be used with
# FIPS-20230428 or newer. Users must set `BORING_BSSL_FIPS_PATH` to use this
# feature, or else the build will fail.
fips-precompiled = []

# Link with precompiled FIPS-validated `bcm.o` module.
fips-link-precompiled = []

# Enables Raw public key API (https://datatracker.ietf.org/doc/html/rfc7250)
rpk = []

Expand Down
24 changes: 1 addition & 23 deletions boring-sys/build/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ pub(crate) struct Config {

pub(crate) struct Features {
pub(crate) fips: bool,
pub(crate) fips_precompiled: bool,
pub(crate) fips_link_precompiled: bool,
pub(crate) pq_experimental: bool,
pub(crate) rpk: bool,
pub(crate) underscore_wildcards: bool,
Expand All @@ -27,7 +25,6 @@ pub(crate) struct Env {
pub(crate) path: Option<PathBuf>,
pub(crate) include_path: Option<PathBuf>,
pub(crate) source_path: Option<PathBuf>,
pub(crate) precompiled_bcm_o: Option<PathBuf>,
pub(crate) assume_patched: bool,
pub(crate) sysroot: Option<PathBuf>,
pub(crate) compiler_external_toolchain: Option<PathBuf>,
Expand Down Expand Up @@ -81,10 +78,6 @@ impl Config {
panic!("`fips` and `rpk` features are mutually exclusive");
}

if self.features.fips_precompiled && self.features.rpk {
panic!("`fips-precompiled` and `rpk` features are mutually exclusive");
}

let is_precompiled_native_lib = self.env.path.is_some();
let is_external_native_lib_source =
!is_precompiled_native_lib && self.env.source_path.is_none();
Expand All @@ -107,40 +100,26 @@ impl Config {
"cargo:warning=precompiled BoringSSL was provided, so patches will be ignored"
);
}

// todo(rmehra): should this even be a restriction? why not let people link a custom bcm.o?
// precompiled boringssl will include libcrypto.a
if is_precompiled_native_lib && self.features.fips_link_precompiled {
panic!("precompiled BoringSSL was provided, so FIPS configuration can't be applied");
}

if !is_precompiled_native_lib && self.features.fips_precompiled {
panic!("`fips-precompiled` feature requires `BORING_BSSL_FIPS_PATH` to be set");
}
}
}

impl Features {
fn from_env() -> Self {
let fips = env::var_os("CARGO_FEATURE_FIPS").is_some();
let fips_precompiled = env::var_os("CARGO_FEATURE_FIPS_PRECOMPILED").is_some();
let fips_link_precompiled = env::var_os("CARGO_FEATURE_FIPS_LINK_PRECOMPILED").is_some();
let pq_experimental = env::var_os("CARGO_FEATURE_PQ_EXPERIMENTAL").is_some();
let rpk = env::var_os("CARGO_FEATURE_RPK").is_some();
let underscore_wildcards = env::var_os("CARGO_FEATURE_UNDERSCORE_WILDCARDS").is_some();

Self {
fips,
fips_precompiled,
fips_link_precompiled,
pq_experimental,
rpk,
underscore_wildcards,
}
}

pub(crate) fn is_fips_like(&self) -> bool {
self.fips || self.fips_precompiled || self.fips_link_precompiled
self.fips
}
}

Expand Down Expand Up @@ -175,7 +154,6 @@ impl Env {
path: boringssl_var("BORING_BSSL_PATH").map(PathBuf::from),
include_path: boringssl_var("BORING_BSSL_INCLUDE_PATH").map(PathBuf::from),
source_path: boringssl_var("BORING_BSSL_SOURCE_PATH").map(PathBuf::from),
precompiled_bcm_o: boringssl_var("BORING_BSSL_PRECOMPILED_BCM_O").map(PathBuf::from),
assume_patched: boringssl_var("BORING_BSSL_ASSUME_PATCHED")
.is_some_and(|v| !v.is_empty()),
sysroot: boringssl_var("BORING_BSSL_SYSROOT").map(PathBuf::from),
Expand Down
120 changes: 8 additions & 112 deletions boring-sys/build/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,23 @@ const CMAKE_PARAMS_APPLE: &[(&str, &[(&str, &str)])] = &[
&[
("CMAKE_OSX_ARCHITECTURES", "arm64"),
("CMAKE_OSX_SYSROOT", "iphoneos"),
("CMAKE_MACOSX_BUNDLE", "OFF"),
],
),
(
"aarch64-apple-ios-sim",
&[
("CMAKE_OSX_ARCHITECTURES", "arm64"),
("CMAKE_OSX_SYSROOT", "iphonesimulator"),
("CMAKE_MACOSX_BUNDLE", "OFF"),
],
),
(
"x86_64-apple-ios",
&[
("CMAKE_OSX_ARCHITECTURES", "x86_64"),
("CMAKE_OSX_SYSROOT", "iphonesimulator"),
("CMAKE_MACOSX_BUNDLE", "OFF"),
],
),
// macOS
Expand Down Expand Up @@ -114,11 +117,7 @@ fn get_boringssl_source_path(config: &Config) -> &PathBuf {
static SOURCE_PATH: OnceLock<PathBuf> = OnceLock::new();

SOURCE_PATH.get_or_init(|| {
let submodule_dir = if config.features.fips {
"boringssl-fips"
} else {
"boringssl"
};
let submodule_dir = "boringssl";

let src_path = config.out_dir.join(submodule_dir);

Expand Down Expand Up @@ -304,7 +303,7 @@ fn get_boringssl_cmake_config(config: &Config) -> cmake::Config {
config
.manifest_dir
.join(src_path)
.join("src/util/32-bit-toolchain.cmake")
.join("util/32-bit-toolchain.cmake")
.as_os_str(),
);
}
Expand Down Expand Up @@ -340,55 +339,6 @@ fn get_boringssl_cmake_config(config: &Config) -> cmake::Config {
boringssl_cmake
}

/// Verify that the toolchains match <https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp3678.pdf>
/// See "Installation Instructions" under section 12.1.
// TODO: maybe this should also verify the Go and Ninja versions? But those haven't been an issue in practice ...
fn verify_fips_clang_version() -> (&'static str, &'static str) {
fn version(tool: &str) -> Option<String> {
let output = match Command::new(tool).arg("--version").output() {
Ok(o) => o,
Err(e) => {
println!("cargo:warning=missing {tool}, trying other compilers: {e}");
// NOTE: hard-codes that the loop below checks the version
return None;
}
};
if !output.status.success() {
return Some(String::new());
}
let output = std::str::from_utf8(&output.stdout).expect("invalid utf8 output");
Some(output.lines().next().expect("empty output").to_string())
}

const REQUIRED_CLANG_VERSION: &str = "12.0.0";
for (cc, cxx) in [
("clang-12", "clang++-12"),
("clang", "clang++"),
("cc", "c++"),
] {
let (Some(cc_version), Some(cxx_version)) = (version(cc), version(cxx)) else {
continue;
};

if cc_version.contains(REQUIRED_CLANG_VERSION) {
assert!(
cxx_version.contains(REQUIRED_CLANG_VERSION),
"mismatched versions of cc and c++"
);
return (cc, cxx);
} else if cc == "cc" {
panic!(
"unsupported clang version \"{cc_version}\": FIPS requires clang {REQUIRED_CLANG_VERSION}"
);
} else if !cc_version.is_empty() {
println!(
"cargo:warning=FIPS requires clang version {REQUIRED_CLANG_VERSION}, skipping incompatible version \"{cc_version}\""
);
}
}
unreachable!()
}

fn pick_best_android_ndk_toolchain(toolchains_dir: &Path) -> std::io::Result<OsString> {
let toolchains = std::fs::read_dir(toolchains_dir)?.collect::<Result<Vec<_>, _>>()?;
// First look for one of the toolchains that Google has documented.
Expand Down Expand Up @@ -591,66 +541,17 @@ fn built_boring_source_path(config: &Config) -> &PathBuf {
}

if config.features.fips {
let (clang, clangxx) = verify_fips_clang_version();
cfg.define("CMAKE_C_COMPILER", clang)
.define("CMAKE_CXX_COMPILER", clangxx)
.define("CMAKE_ASM_COMPILER", clang)
cfg.define("CMAKE_C_COMPILER", "clang")
.define("CMAKE_CXX_COMPILER", "clang++")
.define("CMAKE_ASM_COMPILER", "clang")
.define("FIPS", "1");
}

if config.features.fips_link_precompiled {
cfg.define("FIPS", "1");
}

cfg.build_target("ssl").build();
cfg.build_target("crypto").build()
})
}

fn link_in_precompiled_bcm_o(config: &Config) {
println!("cargo:warning=linking in precompiled `bcm.o` module");

let bssl_dir = built_boring_source_path(config);
let bcm_o_src_path = config.env.precompiled_bcm_o.as_ref()
.expect("`fips-link-precompiled` requires `BORING_BSSL_FIPS_PRECOMPILED_BCM_O` env variable to be specified");

let libcrypto_path = bssl_dir
.join("build/crypto/libcrypto.a")
.canonicalize()
.unwrap();

let bcm_o_dst_path = bssl_dir.join("build/bcm-fips.o");

fs::copy(bcm_o_src_path, &bcm_o_dst_path).unwrap();

// check that fips module is named as expected
let out = run_command(
Command::new("ar")
.arg("t")
.arg(&libcrypto_path)
.arg("bcm.o"),
)
.unwrap();

assert_eq!(
String::from_utf8(out.stdout).unwrap().trim(),
"bcm.o",
"failed to verify FIPS module name"
);

// insert fips bcm.o before bcm.o into libcrypto.a,
// so for all duplicate symbols the older fips bcm.o is used
// (this causes the need for extra linker flags to deal with duplicate symbols)
// (as long as the newer module does not define new symbols, one may also remove it,
// but once there are new symbols it would cause missing symbols at linking stage)
run_command(
Command::new("ar")
.args(["rb", "bcm.o"])
.args([&libcrypto_path, &bcm_o_dst_path]),
)
.unwrap();
}

fn get_cpp_runtime_lib(config: &Config) -> Option<String> {
if let Some(ref cpp_lib) = config.env.cpp_runtime_lib {
return cpp_lib.clone().into_string().ok();
Expand Down Expand Up @@ -709,10 +610,6 @@ fn emit_link_directives(config: &Config) {
);
}

if config.features.fips_link_precompiled {
link_in_precompiled_bcm_o(config);
}

if let Some(cpp_lib) = get_cpp_runtime_lib(config) {
println!("cargo:rustc-link-lib={cpp_lib}");
}
Expand Down Expand Up @@ -785,7 +682,6 @@ fn generate_bindings(config: &Config) {
"des.h",
"dtls1.h",
"hkdf.h",
#[cfg(not(feature = "fips"))]
"hpke.h",
"hmac.h",
"hrss.h",
Expand Down
2 changes: 1 addition & 1 deletion boring-sys/deps/boringssl
Submodule boringssl updated 9548 files
1 change: 0 additions & 1 deletion boring-sys/deps/boringssl-fips
Submodule boringssl-fips deleted from 853ca1
Loading
Loading