-
Notifications
You must be signed in to change notification settings - Fork 40
Description
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.GOFIPSunset: 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=opensslcryptouses dynamic loading (akadlopen) by default, which is the current behavior. Using the platform crypto is the Microsoft Crypto Board recommendation, so we should stick to it.GOEXPERIMENT=opensslcryptouses 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
GOFIPSto 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.