boringssl.bzl (220 lines of code) (raw):

# Copyright 2021 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. load("@bazel_gazelle//internal:go_repository_cache.bzl", _read_go_env = "read_cache_env") _BSSL_FIPS_BUILD_FILE_TEMPLATE = """ load("@rules_cc//cc:defs.bzl", "cc_library") load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake") filegroup( name = "bssl_sources", srcs = glob(["src/**"]), ) cmake( name = "bssl_fips", targets = ["crypto", "ssl"], lib_source = ":bssl_sources", out_include_dir = "", out_lib_dir = "", out_static_libs = [ "crypto/libcrypto.a", "ssl/libssl.a", ], install_prefix = ".", generate_args = ["-GNinja"], cache_entries = { "CMAKE_BUILD_TYPE": "Release", "FIPS": "1", "GO_EXECUTABLE": "$GOROOT/bin/go", }, env = %CMAKE_ENV%, ) filegroup( name = "bssl_fips_gen", srcs = [":bssl_fips"], output_group = "gen_dir", ) genrule( name = "bssl_fips_static_libs", srcs = [":bssl_fips_gen"], cmd = "cp $(location bssl_fips_gen)/crypto/libcrypto.a $(@D); " + "cp $(location bssl_fips_gen)/ssl/libssl.a $(@D)", outs = ["libcrypto.a", "libssl.a"], ) # This list from https://github.com/google/boringssl/blob/ae223d6138807a13006342edfeef32e813246b39/util/generate_build_files.py#L424 _ssl_headers = [ "src/include/openssl/ssl.h", "src/include/openssl/tls1.h", "src/include/openssl/ssl3.h", "src/include/openssl/dtls1.h", "src/include/openssl/srtp.h", ] _crypto_headers = glob( include = ["src/include/openssl/*.h"], exclude = _ssl_headers, ) cc_library( name = "crypto", srcs = ["libcrypto.a"], hdrs = _crypto_headers, strip_include_prefix = "src/include", linkstatic = True, visibility = ["//visibility:public"], ) cc_library( name = "ssl", srcs = ["libssl.a"], hdrs = _ssl_headers, deps = [":crypto"], strip_include_prefix = "src/include", linkstatic = True, visibility = ["//visibility:public"], ) """ _OPENSSL_BUILD_FILE_CONTENT = """ load("@rules_cc//cc:defs.bzl", "cc_library") cc_library( name = "crypto", hdrs = glob(["openssl/*.h"]), linkopts = ["-lcrypto"], visibility = ["//visibility:public"], ) cc_library( name = "ssl", hdrs = glob(["openssl/*.h"]), deps = [":crypto"], linkopts = ["-lssl"], visibility = ["//visibility:public"], ) cc_library( name = "openssl_compat", hdrs = ["compat/openssl/libcrypto-compat.h"], srcs = ["compat/openssl/libcrypto-compat.c"], strip_include_prefix = "compat", deps = [":crypto"], visibility = ["//visibility:public"], ) """ def _must_succeed(operation, result): if (result.return_code != 0): error_msg = ( "{operation} failed, " + "return code {code}, stderr: {err}, stdout: {out}" ).format( operation = operation, code = result.return_code, err = result.stderr, out = result.stdout, ) fail(error_msg) def _crypto_library_impl(repo_ctx): library = repo_ctx.os.environ.get("KMSP11_CRYPTO_LIBRARY", default = "boringssl") if library not in ["boringssl", "boringssl_fips", "openssl"]: fail("KMSP11_CRYPTO_LIBRARY='%s' is not supported" % (library)) if library == "boringssl": repo_ctx.download_and_extract( # 2023-09-12 url = "https://github.com/google/boringssl/archive/48a16fed0bf57f3d04f856a17490b5935458eb99.tar.gz", sha256 = "5e475b54e1f7a7536c66fb777aeac97943d032b46bbff4c646dfcd337828ff87", stripPrefix = "boringssl-48a16fed0bf57f3d04f856a17490b5935458eb99", ) return if library == "openssl": include_dir = repo_ctx.os.environ.get( "OPENSSL_INCLUDE_DIR", default = "/usr/include/openssl", ) repo_ctx.symlink(include_dir, "openssl") # See https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes#Backward_compatibility repo_ctx.download_and_extract( url = "https://wiki.openssl.org/images/e/ed/Openssl-compat.tar.gz", sha256 = "2d75ffb10b2e3138a9c4e3c130fede955c5b8e326e6a860b718a99e41df58abb", output = "compat/openssl", ) repo_ctx.patch(Label("//:third_party/openssl_compat.patch")) repo_ctx.file( "BUILD", content = _OPENSSL_BUILD_FILE_CONTENT, ) return # Proceeding to set up BoringSSL + FIPS config # 853ca1ea1168dff08011e5d42d94609cc0ca2e27 is the latest FIPS-validated version. # https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4407 repo_ctx.download_and_extract( url = "https://github.com/google/boringssl/archive/853ca1ea1168dff08011e5d42d94609cc0ca2e27.tar.gz", stripPrefix = "boringssl-853ca1ea1168dff08011e5d42d94609cc0ca2e27", sha256 = "61e85d6eaecf1706be0420a9104b66ff01bd04301b5fad323970685f942108ed", output = "src", ) fips_patches = [ # Specific to our builds. Needed to ensure that symbols are exposed # transitively within the Bazel ecosystem. Label("//:third_party/bssl_visibility.patch"), ] for patch in fips_patches: _must_succeed( "patch for bssl fips", repo_ctx.execute([ "patch", "-d", "src", "-i", repo_ctx.path(patch), "-E", "-p1", ]), ) repo_ctx.file( "BUILD.tmpl", content = _BSSL_FIPS_BUILD_FILE_TEMPLATE, executable = False, ) go_env = _read_go_env(repo_ctx, str(repo_ctx.path(repo_ctx.attr._go_cache))) build_env = { "GOROOT": go_env["GOROOT"], "GOPATH": go_env["GOPATH"], "GOCACHE": "$BUILD_TMPDIR/cache", "SYSTEM_NAME": repo_ctx.os.name, } # Download dependencies from go.mod _must_succeed("go get", repo_ctx.execute( [go_env["GOROOT"] + "/bin/go", "get", "-u", "..."], working_directory = "src", environment = build_env, )) repo_ctx.template( "BUILD", "BUILD.tmpl", substitutions = { "%CMAKE_ENV%": str(build_env), }, executable = False, ) crypto_library = repository_rule( implementation = _crypto_library_impl, attrs = { "_go_cache": attr.label( default = Label("@bazel_gazelle_go_repository_cache//:go.env"), allow_single_file = True, ), }, environ = [ "KMSP11_CRYPTO_LIBRARY", "OPENSSL_INCLUDE_DIR", ], ) def select_crypto_library(): if native.existing_rule("boringssl"): return # Our crypto repository will always be named 'boringssl' so that our # gRPC stack uses it as well. crypto_library(name = "boringssl")