Skip to content

OpenSSL static linking proposal #744

@qmuntal

Description

@qmuntal

Goal

Add OpenSSL static linking support to Microsoft Go OpenSSL crypto backend.

Background

We currently support OpenSSL dynamic loading by calling dlopen(libcrypto.so.X), being X a configurable version string (see docs). The supported OpenSSL versions are 1.0.2, 1.1.0, 1.1.1 and 3.

We also support portable OpenSSL, which means users can build an application using an OpenSSL version different that the one used at runtime.

One can tune the FIPS behavior by using the GOFIPS environment variable in the following ways:

  • GOFIPS=0: disable OpenSSL FIPS mode.
  • GOFIPS=1: force OpenSSL FIPS mode, panic is not enabled and can't be enabled.
  • GOFIPS unset: try to enable FIPS mode if not enabled. If can't be enabled, go on with the OpenSSL backend in non-FIPS mode.

OpenSSL static linking is not supported, although we could add this capability to go-crypto-openssl with a reasonable effort. This proposal is not about how to update go-crypto-openssl nor how is integrated with microsoft/go, but about the user experience around the different OpenSSL linking/loading modes

Why static linking

  • Deploy on distroless containers: some containers are so trimmed down that they don't even contain libcrypto.so, so embedding it into the binary facilitate running it without installing external packages.
  • Ensure OpenSSL is FIPS-compliant: we currently require the platform OpenSSL to be FIPS-compliant, which is not the case for popular containers, such as Ubuntu. CBL-Mariner does provide a FIPS-compliant OpenSSL out of the box.

Proposal

  • GOEXPERIMENT=opensslcrypto uses dynamic loading (aka dlopen) by default, which is the current behavior. Using the platform crypto is the Microsoft Crypto Board recommendation, so we should stick to it.
  • GOEXPERIMENT=opensslcrypto uses static linking when used together with -tags=opensslstatic.
    e.g., GOEXPERIMENT=opensslcrypto go build . -tags=opensslstatic.
  • Microsoft Go will provide the OpenSSL library that will be used for static linking, in a similar way as Google does for BoringSSL. This library will be FIPS-capable and vetted by Microsoft's Crypto Board. The Microsoft Go team shouldn't be responsible of maintaining this library, it should either build the source code from a trusted repository (e.g. CBL-Mariner) using a compliant build recipe or just take the pre-compiled binaries.
  • Microsoft Go won't provide multiple OpenSSL versions. This should be transparent for end users as long as OpenSSL integrates well with Go crypto.
  • Microsoft Go won't support linking against custom OpenSSL static libraries. The business case of this functionality is not clear and would complicate the implementation. This decision can be revisit later on.
  • Change GOFIPS to default to `GOFIPS=1, which means it will panic if OpenSSL cannot be used in FIPS mode. If someone is not sure whether FIPS mode will be supported at runtime they should use OpenSSL static linking, which will be warranted to support FIPS.

The most difficult part of this proposal is to agree on who provides the FIPS-capable OpenSSL sources and built recipe. This proposal is consciously vague at this point so we focus the discussion on the UX. If at the end we can't provide a FIPS-capable OpenSSL static library I would argue that we should not provide OpenSSL static linking at all.

@dagood @jaredpar @chsienki
FYI @derekparker

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions