boring icon indicating copy to clipboard operation
boring copied to clipboard

Add symbol prefixing feature for BoringSSL

Open BarbossHack opened this issue 4 months ago • 4 comments

Goal

Add a prefix to all symbols in libcrypto and libssl to prevent conflicts with other OpenSSL or BoringSSL versions that might be linked in the same process.

Why?

When statically linking both OpenSSL and BoringSSL in the same project, we encountered duplicate symbols, for example:

rust-lld: error: duplicate symbol: AES_encrypt
>>> defined at aes-x86_64.s:328 (crypto/aes/aes-x86_64.s:328)
>>>            libcrypto-lib-aes-x86_64.o:(AES_encrypt) in archive /home/user/debug/target/debug/deps/libopenssl_sys-aa966f6339bd703d.rlib
>>> defined at aes.c:62 (/home/user/debug/target/debug/build/boring-sys-daeba9923fc21b33/out/boringssl/src/crypto/fipsmodule/aes/aes.c:62)
 >>>            bcm.c.o:(.text.AES_encrypt+0x0) in archive /home/user/debug/target/debug/deps/libboring_sys-b3f993188e8b17ea.rlib

How?

The first approach was to use the BoringSSL-provided Go script make_prefix_headers.go. It mostly worked, but:

  • It required two compilation steps: first to build the static libraries and extract symbols with read_symbols.go, then to generate boringssl_prefix_symbols.h with make_prefix_headers.go, and finally rebuild again the static libraries with this header. (We could have prebuilt it like gRPC does, but I preferred a fully automated workflow.)
  • Some ASM/Perl-generated symbols were missed (even if present in boringssl_prefix_symbols.h), which I ended up fixing with the Binutils objcopy tool, not very straightforward.
  • It required Go to run.

Therefore, I decided to use only the Binutils tools nm and objcopy to fully automate the symbol prefixing.

Steps (build.rs):

  1. List static libraries to prefix symbols in (libssl.a and libcrypto.a).
  2. Use nm to list all exported symbols in these static libraries.
  3. Generate a mapping file and use objcopy to prefix all symbols.
  4. Update the generated bindings (bindings.rs) with #[link_name] where necessary.

Cross-compilation

Currently, this workflow is tested for Linux and Android only.

For Android, the target-specific nm and objcopy from the NDK are used.

macOS/iOS and Windows toolchains are not tested. I currently don’t have access to a macOS environment and have limited experience with Windows toolchains.

Usage

I've added an opt-in feature prefix-symbols, as it is not tested on macOS/iOS/Windows yet.

cargo add boring --features prefix-symbols

BarbossHack avatar Oct 14 '25 18:10 BarbossHack