Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix build with "fips-link-precompiled" feature #147

Closed

Conversation

cjpatton
Copy link
Collaborator

@cjpatton cjpatton commented Aug 11, 2023

When the "fips-link-precompiled" feature is used, the build script boringSSL (boring-sys/build.sh) adds a precompiled bcm.o module provided by the user. The module is renamed to bcm-fips.o and inserted into libcrypto.a just before the bcm.o built by the script. The intent is to "shadow" the module so that, for any symbols that are provided by both, the linker picks the implementations provided by bcm-fips.o. At the same time, any sybmols in bcm.o that are not in bcm-fips.o can be used.

This configuration requires special flags in order to tell the linker how to resolve duplicate symbols (RUSTFLAGS="-Clink-args=-Wl,-zmuldefs" is sufficient). However even with these flags thare are certain symbols that don't resolve. In particular bcm-fips.o expects bcm.o to provide RAND_need_entropy.

Rather than attempt to cobble together a working version of this "shadow" build of libcrypto.a, we modify the build script so that it "replaces" bcm.o with the precompiled module provided by the user. Based on internal conversations, this appears to be sufficient for every use case for these bindings. If the shadow build is required, then the user will need to provide their own version of libcrypto.a (This is not supported as of this commit.)

One more change is required in order to build with "fips-link-precompiled". Building fails because the FFI exports a different API than the bindings expects. To fix this, it is sufficient to change the features so that "fips-link-precompiled" does not imply "fips".

.expect("`fips-link-precompiled` requires `BORING_SSL_PRECOMPILED_BCM_O` env variable to be specified");

let libcrypto_path = PathBuf::from(bssl_dir)
.join("build/crypto/libcrypto.a")
.join("build/libcrypto.a")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to mention this in the commit mesesage, but this seems to be necessary for the version of boringSSL we're building.

When the "fips-link-precompiled" feature is used, the build script for
boringSSL (`boring-sys/build.sh`) adds a precompiled `bcm.o` module
provided by the user. The module is renamed to `bcm-fips.o` and inserted
into `libcrypto.a` just before the `bcm.o` built by the script. The
intent is to "shadow" the module so that, for any symbols that are
provided by both, the linker picks the implementations provided by
`bcm-fips.o`. At the same time, any sybmols in `bcm.o` that are not in
`bcm-fips.o` can be used.

This configuration requires special flags in order to tell the linker
how to resolve duplicate symbols (RUSTFLAGS="-Clink-args=-Wl,-zmuldefs"
is sufficient). However even with these flags thare are certain symbols
that don't resolve. In particular `bcm-fips.o` expects `bcm.o` to
provide `RAND_need_entropy`.

Rather than attempt to cobble together a working version of this
"shadow" build of `libcrypto.a`, we modify the build script so that it
"replaces" `bcm.o` with the precompiled module provided by the user.
Based on internal conversations, this appears to be sufficient for every
use case for these bindings. If the shadow build is required, then the
user will need to provide their own version of `libcrypto.a` (This is
not supported as of this commit.)

One more change is required in order to build with
"fips-link-precompiled". Building fails because the FFI exports a
different API than the bindings expects. To fix this, it is sufficient
to change the features so that "fips-link-precompiled" does not imply
"fips".
.canonicalize()
.unwrap()
.display()
.to_string();

let bcm_o_dst_path = PathBuf::from(bssl_dir).join("build/bcm-fips.o");
Copy link
Collaborator Author

@cjpatton cjpatton Aug 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the critical line. The "shadow" build gives the precompiled module a distinctive name so that bcm-fips.o and bcm.o are both included in libcrypto.a. In this PR, we give the precompiled module the same name so that it replaces bcm.o.

@bwesterb
Copy link
Member

lgtm

We expect `fips::enabled()` to be set when the "fips-link-precompiled"
feature is used.
@cjpatton cjpatton marked this pull request as draft August 15, 2023 00:20
@cjpatton
Copy link
Collaborator Author

I've updated test fips::is_enabled to check for FIPS mode (FIPS_mode() != 0) when the "fips-link-precompiled" flag is set. It turns out that it is not set, as we expected. While debugging this, @bhalleycf noticed that we're not actually modifying bcm.c.o in the build script. After fixing this issue (4b8b5d3) the duplicate symbol errors are there, and we're missing RAND_need_entropy.

@cjpatton
Copy link
Collaborator Author

Closing this PR since we know it doesn't fix the "fips-link-precompiled" build on its own.

@cjpatton cjpatton closed this Aug 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants