Add symbol prefixing feature for BoringSSL
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 generateboringssl_prefix_symbols.hwithmake_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 Binutilsobjcopytool, 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):
- List static libraries to prefix symbols in (
libssl.aandlibcrypto.a). - Use
nmto list all exported symbols in these static libraries. - Generate a mapping file and use
objcopyto prefix all symbols. - 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