Motivation: number of components I’m working with are based on BoringSSL. In some cases it is necessary to use cryptographic primitives which are not available in BoringSSL (i.e. new features of PrivacyPass which will be based on Workers). In some cases new crypto algorithms can be up-streamed to BoringSSL, but there are cases in which up-streaming doesn’t make any sense. But I do not be limited by goals that BoringSSL tries to achieve.

One obvious solution in such situation is to link the product with a library that’s better suited than BoringSSL (for example link workers with botan or crypto++). But this may mean inclusion of a code which is hard to verify. Other solution is to use OpenSSL and try to use ENGINE, but in some cases changing TLS library is either a overkill or not an option.

Goal: Another solution is to modify BoringSSL and maintain patches. It may be interesting to make it possible to extend upstream version with additional crypto. When extending, it must be done in a way that it is easy and straight forward to merge with upstream.

Solution: Additional algorithms can be placed in the third_part/ext folder. This folder will define separated library: libcrypto_ex.a. This library will be linked with libcrypto.a from BoringSSL. Makefiles of BoringSSL need to be slightly modified in order to build and link library with extensions. But this is just 2 lines, which makes it extremely easy to maintain and sync with upstream.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index fd3532664..3c4366474 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -600,3 +600,6 @@ add_custom_target(
     WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
     DEPENDS all_tests bssl_shim handshaker
     ${MAYBE_USES_TERMINAL})
+
+# Adds crypto ex-target
+add_subdirectory(third_party/ext)
diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt
index e940f7d5f..d3d03fc26 100644
--- a/crypto/CMakeLists.txt
+++ b/crypto/CMakeLists.txt
@@ -400,6 +400,7 @@ add_library(
   ../third_party/fiat/curve25519.c
  
   $<TARGET_OBJECTS:fipsmodule>
+  $<TARGET_OBJECTS:cryptoex>
  
   ${CRYPTO_ARCH_SOURCES}
   ${CRYPTO_FIPS_OBJECTS}

All the headers with the API is placed in the third_party/public/ext/boringssl folder. Application needs to add this directory to include path and link with libcrypto.a in order to use extended crypto. Some rules need to be applied in order to make merging as easy as possible in the long term:

  • new implementation of crypto is kept only in the third_party/ext
  • tests are implemented as separated binary and kept in third_party/test
  • sources in the third_party/ext can only use API which is exported by BoringSSL (don’t use internal API, which can be modified quite often)

Example containing SHA3 and PBKDF together with test program is here: https://bitbucket.cfdata.org/users/kris/repos/boringssl/commits/f5db0057428b56a1385b507f6bd69c18f25c3ce5 I got no merge problems when syncing with HEAD.

Comments and criticism more than welcome.