Skip to content

Commit

Permalink
Build embedded BoringSSL with symbol prefix (#702)
Browse files Browse the repository at this point in the history
* Build embedded BoringSSL with symbol prefix

When building with ENGINE=boringssl, Soter embeds BoringSSL into its
libraries, including static ones. This enables the users to link only
against libthemis.a and libsoter.a, without having to salvage the
BoringSSL binaries from the build directory (which are *not* included
into packages).

What is the issue here?
-----------------------

However, embedding BoringSSL has a side effect. Due to the way static
linkage works, all BoringSSL symbols from "libsoter.a" are
indistinguishable from Soter symbols for exporting purposes. That is,
any binary linked against "libsoter.a" will by default include and
export all BoringSSL symbols. This is problematic because it can cause
symbol conflicts. Dynamic libraries are not affected by this because
we control what symbols are exported. That way BoringSSL stays inside
Soter library and does not cause conflicts.

In order to avoid conflicts, start using BoringSSL's symbol renaming
facility. EVP_sha256() will be renamed into SOTER_0_14_0_EVP_sha256()
and all call sites from Soter will refer to this new symbol instead.
This makes Soter's BoringSSL copy independent of any WhateverSSL is
there in the binary.

How renaming works
------------------

Bad news here is that renaming requires building BoringSSL twice. First
we build it to enumerate the symbols to rename, then it is built again,
now with renamed symbols. All symbols need to be renamed, not only those
used by Soter, because the entire BoringSSL library is embedded into
Soter. We cannot simply enumerate and hardcode what we use.

After building BoringSSL with renamed symbols, Soter needs to use them
in renamed form. For that it needs to be built with BORINGSSL_PREFIX
define and <boringssl_prefix_symbols.h> in its include path. That header
will perform actual renaming using C preprocessor.

Other build details
-------------------

Previously Soter did not care about build order, but now BoringSSL needs
to be built (possibly renamed) before Soter can be built.

Note that extracting symbols with BoringSSL tool requires Go. BoringSSL
build itself requires Go so this is not a new dependency.

* Disable BoringSSL renaming for certain systems

Enable BoringSSL symbol renaming by default for Linux and macOS desktop
builds and disable it for WebAssembly builds.

AndroidThemis also uses BoringSSL, but it does not use Themis Makefile
for that. It does not use renaming either.

Renaming is important only for the case of static libraries, and only
desktop systems provide them in packages. Mobile systems use dynamic
linkage for the most part and avoid symbol conflicts.

The default can be overridden from the command line:

    make ENGINE=boringssl RENAME_BORINGSSL_SYMBOLS=no

or "yes" to enable it.
  • Loading branch information
ilammy committed Aug 18, 2020
1 parent 35ac93e commit 4ae325d
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 4 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -8,7 +8,7 @@ _Code:_

- **Core**

- Include embedded BoringSSL into Soter for convenience ([#681](https://github.com/cossacklabs/themis/pull/681)).
- Include embedded BoringSSL into Soter for convenience ([#681](https://github.com/cossacklabs/themis/pull/681), [#702](https://github.com/cossacklabs/themis/pull/702)).
- `make deb` and `make rpm` with `ENGINE=boringssl` will now produce `libthemis-boringssl` packages with embedded BoringSSL ([#683](https://github.com/cossacklabs/themis/pull/683), [#686](https://github.com/cossacklabs/themis/pull/686)).
- `secure_session_create()` now allows only EC keys, returning an error for RSA ([#693](https://github.com/cossacklabs/themis/pull/693)).

Expand All @@ -34,6 +34,7 @@ _Infrastructure:_
- Optimized dependencies of `libthemis` DEB and RPM packages ([#682](https://github.com/cossacklabs/themis/pull/682), [#686](https://github.com/cossacklabs/themis/pull/686)).
- `make deb` and `make rpm` with `ENGINE=boringssl` will now produce `libthemis-boringssl` packages with embedded BoringSSL ([#683](https://github.com/cossacklabs/themis/pull/683), [#686](https://github.com/cossacklabs/themis/pull/686)).
- Build system and tests now respect the `PATH` settings ([#685](https://github.com/cossacklabs/themis/pull/685)).
- Rename embedded BoringSSL symbols by default to avoid conflicts with system OpenSSL ([#702](https://github.com/cossacklabs/themis/pull/702)).
- Started phasing out CircleCI in favour of GitHub Actions ([#709](https://github.com/cossacklabs/themis/pull/709)).

## [0.13.2](https://github.com/cossacklabs/themis/releases/tag/0.13.2), August 14th 2020
Expand Down
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -49,6 +49,7 @@ LIBRARY_SO_VERSION = 0
#----- Toolchain ---------------------------------------------------------------

CMAKE ?= cmake
GO ?= go

CLANG_FORMAT ?= clang-format
CLANG_TIDY ?= clang-tidy
Expand Down
44 changes: 41 additions & 3 deletions src/soter/boringssl/soter.mk
Expand Up @@ -36,12 +36,50 @@ CRYPTO_ENGINE_LDFLAGS += -lcrypto -ldecrepit -lpthread
SOTER_ENGINE_CMAKE_FLAGS += -DCMAKE_BUILD_TYPE=Release
SOTER_ENGINE_CMAKE_FLAGS += -DCMAKE_C_FLAGS="-fpic"

ifdef IS_LINUX
RENAME_BORINGSSL_SYMBOLS = yes
endif
ifdef IS_MACOS
RENAME_BORINGSSL_SYMBOLS = yes
endif
ifdef IS_EMSCRIPTEN
RENAME_BORINGSSL_SYMBOLS = no
SOTER_ENGINE_CMAKE_FLAGS += -DOPENSSL_NO_ASM=1
endif

ifeq ($(RENAME_BORINGSSL_SYMBOLS),yes)
# The prefix must be a valid C identifier. Replace invalid characters.
SOTER_BORINGSSL_PREFIX := $(shell echo "SOTER_$(VERSION)" | tr '.-' '_')

SOTER_CRYPTO_ENGINE_CFLAGS += -DBORINGSSL_PREFIX=$(SOTER_BORINGSSL_PREFIX)
SOTER_CRYPTO_ENGINE_CFLAGS += -I$(BIN_PATH)/boringssl/stage-2/symbol_prefix_include
endif

$(BIN_PATH)/boringssl/crypto/libcrypto.a $(BIN_PATH)/boringssl/decrepit/libdecrepit.a:
@echo "building embedded BoringSSL..."
@mkdir -p $(BIN_PATH)/boringssl
@cd $(BIN_PATH)/boringssl && $(CMAKE) $(SOTER_ENGINE_CMAKE_FLAGS) $(abspath third_party/boringssl/src)
@$(MAKE) -C $(BIN_PATH)/boringssl crypto decrepit
@mkdir -p $(BIN_PATH)/boringssl/stage-1
@cd $(BIN_PATH)/boringssl/stage-1 && \
$(CMAKE) $(SOTER_ENGINE_CMAKE_FLAGS) $(abspath third_party/boringssl/src)
@$(MAKE) -C $(BIN_PATH)/boringssl/stage-1 crypto decrepit
@mkdir -p $(BIN_PATH)/boringssl/crypto $(BIN_PATH)/boringssl/decrepit
@cp $(BIN_PATH)/boringssl/stage-1/crypto/libcrypto.a $(BIN_PATH)/boringssl/crypto/libcrypto.a
@cp $(BIN_PATH)/boringssl/stage-1/decrepit/libdecrepit.a $(BIN_PATH)/boringssl/decrepit/libdecrepit.a
ifeq ($(RENAME_BORINGSSL_SYMBOLS),yes)
@cd third_party/boringssl/src && \
$(GO) run util/read_symbols.go -out $(abspath $(BIN_PATH)/boringssl/symbols.txt) \
$(abspath $(BIN_PATH)/boringssl/stage-1/crypto/libcrypto.a) \
$(abspath $(BIN_PATH)/boringssl/stage-1/decrepit/libdecrepit.a)
@# Path to symbols must be a relative one (relative to the build directory)
@# because absolute paths confuse BoringSSL's make.
@echo "building embedded BoringSSL again with renamed symbols..."
@mkdir -p $(BIN_PATH)/boringssl/stage-2
@cd $(BIN_PATH)/boringssl/stage-2 && \
$(CMAKE) $(SOTER_ENGINE_CMAKE_FLAGS) \
-DBORINGSSL_PREFIX=$(SOTER_BORINGSSL_PREFIX) \
-DBORINGSSL_PREFIX_SYMBOLS=../symbols.txt \
$(abspath third_party/boringssl/src)
@$(MAKE) -C $(BIN_PATH)/boringssl/stage-2 crypto decrepit
@mkdir -p $(BIN_PATH)/boringssl/crypto $(BIN_PATH)/boringssl/decrepit
@cp $(BIN_PATH)/boringssl/stage-2/crypto/libcrypto.a $(BIN_PATH)/boringssl/crypto/libcrypto.a
@cp $(BIN_PATH)/boringssl/stage-2/decrepit/libdecrepit.a $(BIN_PATH)/boringssl/decrepit/libdecrepit.a
endif
6 changes: 6 additions & 0 deletions src/soter/soter.mk
Expand Up @@ -58,6 +58,7 @@ FMT_CHECK += $(patsubst %,$(OBJ_PATH)/%.fmt_check, $(SOTER_FMT_SRC))
SOTER_STATIC = $(BIN_PATH)/$(LIBSOTER_A)

$(SOTER_OBJ): CFLAGS += -DSOTER_EXPORT
$(SOTER_OBJ): CFLAGS += $(SOTER_CRYPTO_ENGINE_CFLAGS)

# First build Soter library, then merge embedded crypto engine libs into it.
# On macOS this may cause warnings about files with no symbols in BoringSSL,
Expand All @@ -66,6 +67,11 @@ $(BIN_PATH)/$(LIBSOTER_A): CMD = $(AR) rcs $@ $(filter %.o, $^) \
&& scripts/merge-static-libs.sh $@ $(filter %.a, $^) \
$(if $(IS_MACOS),> >(grep -v 'has no symbols$$'))

# Make sure to build dependencies before objects. This is important in case
# of embedded BoringSSL with renamed symbols: they need to be renamed before
# Soter's objects are built against them.
$(SOTER_OBJ): $(SOTER_ENGINE_DEPS)

$(BIN_PATH)/$(LIBSOTER_A): $(SOTER_OBJ) $(SOTER_ENGINE_DEPS)
@mkdir -p $(@D)
@echo -n "link "
Expand Down

0 comments on commit 4ae325d

Please sign in to comment.