Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto: obtain a FIPS 140-3 validation #69536

Open
FiloSottile opened this issue Sep 19, 2024 · 84 comments
Open

crypto: obtain a FIPS 140-3 validation #69536

FiloSottile opened this issue Sep 19, 2024 · 84 comments
Assignees
Labels
Milestone

Comments

@FiloSottile
Copy link
Contributor

Background

FIPS 140 is a set of U.S. Government requirements for cryptographic modules. A number of companies must comply with them, for example as part of a broader FedRAMP compliance posture. (If that's not you, you can ignore this. Run!)

Current solutions for Go program compliance are based on cgo, and replace some of the crypto packages internals with FIPS 140 validated non-memory safe modules. These solutions come with varying levels of support (for example the Go+BoringCrypto solution is not officially supported and its compliance profile is left to the user to assess), introduce memory unsafe code, sometimes delay Go version updates, can have performance issues, affect the developer experience (for example inhibiting cross-compilation), and their compliance profile is debatable. As Go is adopted more and more in regulated settings, this is going to affect Go's adoption and developer experience.

The Go FIPS module

We plan to pursue a FIPS 140-3 validation for the NIST approved components of the Go standard library. The resulting module will be distributed as part of the standard library under the same license as the rest of the Go project, and will be transparently used by the relevant standard library packages with no API changes (wherever possible).

Users will be able to select the module to use at build time, for example choosing between a certified version, a version in the In Process list, or the latest unvalidated update. Moreover, we'll provide some mechanism for applications to disable the use of non-approved algorithms and modes at runtime.

Further planning details

The goal is shipping the module as part of Go 1.24, assuming our validation strategy is successful. This is the first time as far as we know that a Go library (or any non-Java memory safe library) is validated.

Unless completely unavoidable, we'll not compromise on security to achieve compliance. For example, we will inject random bytes from the kernel as additional input per SP 800-90Ar1, Section 8.7.2, every time we use the mandatory DRBG, and we'll use a dedicated DRBG for ECDSA to implement a "hedged" nonce generation equivalent to what crypto/ecdsa does now (safer than both NIST options of fully random and deterministic). Also, we'll try to add minimal complexity to regular non-FIPS builds.

NIST approved packages will be prioritized in being moved to the standard library (#65269) to get validated along the rest.

We'll test at least on Linux on amd64 and arm64. Further details will be available later in the process. (If you have specific requirements, please inquire about becoming a sponsor, see below.)

We aim to deprecate and hopefully remove Go+BoringCrypto once the module lands.

After the initial validation, we plan to revalidate at least every year, and every time a CVE affects the module with no standard library-side mitigation.

All work will be done on Gerrit, tracked in the issue tracker, and the testing harnesses will be committed in the tree.

This is an umbrella issue to track related issues and CLs, and to provide updates to the community. We'll file separate proposals for the exact build-time settings, for the FIPS-only policy mechanism, for any new APIs, and for any behavior changes.

We have started working with a CMVP testing laboratory, and contracted @cpu to help. This is an industry-sponsored effort that I (@FiloSottile) am leading as an independent maintainer, not a Google or Go team project (although it is coordinated with the Go team and @golang/security). We're funded by a few major stakeholders, and we're available to accept sponsorships and offer commercial support (reach out to [email protected] if interested).

@FiloSottile FiloSottile added this to the Go1.24 milestone Sep 19, 2024
@FiloSottile FiloSottile self-assigned this Sep 19, 2024
@gabyhelp
Copy link

Related Issues and Documentation

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

@DejeroDaniel
Copy link

I was just about to ask a question regarding Ed25519 usage in the other ticket when this was posted. Exciting news!
Is Ed25519 support planned to be certified in this new native implementation?

@FiloSottile
Copy link
Contributor Author

Is Ed25519 support planned to be certified in this new native implementation?

Yes, we'll post a full list of algorithms once we are close to finalizing it, but it approximates to "everything that's NIST approved and not frozen, deprecated, or legacy-use".

@mateusz834
Copy link
Member

Users will be able to select the module to use at build time, for example choosing between a certified version, a version in the In Process list, or the latest unvalidated update.

How this is going to be achieved? Build tags?
The default is going to be non-FIPS validated?

@FiloSottile
Copy link
Contributor Author

How this is going to be achieved? Build tags?

Probably something more explicit, such as a go build flag. I suspect build tags won't be flexible enough, but I might be wrong! We'll bring up a dedicated proposal to discuss that.

The default is going to be non-FIPS validated?

Yes.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/614495 mentions this issue: crypto/sha256,crypto/sha512: make assembly structure consistent

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/614656 mentions this issue: crypto/sha256,crypto/sha512: test fallback implementations

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/615235 mentions this issue: crypto/sha256,crypto/sha512: move implementation to crypto/internal/fips

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/615816 mentions this issue: crypto/internal: add FIPS module test wrapper

@manistal
Copy link

Out of curiosity, how will Go natively handle the key zeroization requirements of FIPS?

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/616636 mentions this issue: crypto/hmac: move implementation to crypto/internal/fips

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/616717 mentions this issue: crypto/internal/fips/sha3: import x/crypto/sha3

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/616716 mentions this issue: crypto/internal/fips/subtle: provide XORBytes

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/616715 mentions this issue: internal/cpu: add ARM64.HasSHA3

cpu pushed a commit to cpu/go that referenced this issue Oct 1, 2024
Ensure separate implementations are implemented in different functions
called from Go, and that they can be turned off from a GODEBUG.

This will be necessary to test implementations separately for golang#69536.

Change-Id: I3e081deb7abb01b0665265e39c72fd4037dd48b3
Cq-Include-Trybots: luci.golang.try:gotip-linux-arm64-longtest,gotip-linux-amd64-longtest,gotip-linux-ppc64le_power8,gotip-linux-ppc64_power8
cpu pushed a commit to cpu/go that referenced this issue Oct 1, 2024
This will be required for golang#69536 but is also good hygiene and required
by go.dev/wiki/AssemblyPolicy.

> The code must be tested in our CI. This means there need to be
> builders that support the instructions, and if there are multiple (or
> fallback) paths they must be tested separately.

The new crypto/internal/impl registry lets us select alternative
implementations from both the same package and importers (such as
crypto/sha256 tests once we have crypto/internal/fips/sha256, or
crypto/hmac).

Updates golang#69592
Updates golang#69593

Change-Id: Ifea22a9fc9ccffcaf4924ff6bd08da7c9bd39e99
Cq-Include-Trybots: luci.golang.try:gotip-linux-arm64-longtest,gotip-linux-amd64-longtest,gotip-linux-ppc64le_power8,gotip-linux-ppc64_power8
cpu pushed a commit to cpu/go that referenced this issue Oct 1, 2024
For golang#69536

Change-Id: I1efa916e6e9fcddeffa52bc3d23286e6465dae54
cpu pushed a commit to cpu/go that referenced this issue Oct 1, 2024
For golang#69536

Change-Id: I38508a8de4ac321554a2c12ac70bcf9e25fad1aa
cpu pushed a commit to cpu/go that referenced this issue Oct 1, 2024
For golang#69536

Change-Id: If237226ba03e282443b4fc90484968c903198cb1
cpu pushed a commit to cpu/go that referenced this issue Oct 1, 2024
This is needed from inside the module, and we generally don't want to
import the crypto tree from it.

For golang#69536

Change-Id: I69e91e4df89ecac0016c671ccd28e733a7131533
cpu pushed a commit to cpu/go that referenced this issue Oct 1, 2024
For now just internally, pending a dedicated proposal for the exposed
package API.

In this CL the code is copied verbatim, for ease of review. Only the
imports were replaced with the corresponding internal ones, and
crypto.RegisterHash calls were disabled.

DO NOT SUBMIT until CL 616635 is submitted, and this CL is synced, then
specify here what commit was imported.

Updates golang#65269
For golang#69536

Change-Id: Ia4735b50c99b9573a5c4889733c4a119930fe658
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/632215 mentions this issue: crypto/internal/fips140/rsa: add Miller-Rabin test

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/632415 mentions this issue: crypto/internal/fips140/bigmod: add Inverse and gcd

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/632479 mentions this issue: crypto/internal/fips140/rsa: do trial divisions in key generation

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/632478 mentions this issue: crypto/x509: keep RSA CRT values in ParsePKCS1PrivateKey

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/632476 mentions this issue: crypto/rsa: move precomputation to crypto/internal/fips140/rsa

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/632477 mentions this issue: crypto/rsa: move key generation to crypto/internal/fips140/rsa

gopherbot pushed a commit that referenced this issue Nov 30, 2024
A following CL will move key generation to crypto/internal/fips140/rsa.

Updates #69799
For #69536

Change-Id: Icdf9b8424da20453939c6587af7dc922aad9e0ca
Reviewed-on: https://go-review.googlesource.com/c/go/+/632215
Auto-Submit: Filippo Valsorda <[email protected]>
Reviewed-by: Roland Shoemaker <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Russ Cox <[email protected]>
Reviewed-by: Daniel McCarney <[email protected]>
gopherbot pushed a commit that referenced this issue Nov 30, 2024
Will be needed for RSA key generation.

We now require Modulus to be > 1 because we don't want to worry about 1
being out of range. There is no use for a Modulus of 1 anyway, and we
already return an error from NewModulus.

Ported from https://cs.opensource.google/boringssl/boringssl/+/master:crypto/fipsmodule/bn/gcd_extra.cc.inc;drc=5813c2c10c73d800f1b0d890a7d74ff973abbffc.

Updates #69799
For #69536

Change-Id: I9850bcc461565b23fa7186a09c65355f7da3e5ba
Reviewed-on: https://go-review.googlesource.com/c/go/+/632415
Auto-Submit: Filippo Valsorda <[email protected]>
Reviewed-by: Daniel McCarney <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Roland Shoemaker <[email protected]>
Reviewed-by: Russ Cox <[email protected]>
gopherbot pushed a commit that referenced this issue Nov 30, 2024
We are severely limited by the crypto/rsa API in a few ways:

 - Precompute doesn't return an error, but is the only function allowed
   to modify a PrivateKey.

 - Clients presumably expect the PrecomputedValues big.Ints to be
   populated after Precompute.

 - MarshalPKCS1PrivateKey requires the precomputed values, and doesn't
   have an error return.

 - PrivateKeys with only N, e, and D have worked so far, so they might
   have to keep working.

To move precomputation to the FIPS module, we focus on the happy path of
a PrivateKey with two primes where Precompute is called before anything
else, which match ParsePKCS1PrivateKey and GenerateKey.

There is a significant slowdown in the Parse benchmark due to the
constant-time inversion of qInv. This will be addressed in a follow-up
CL that will use (and check) the value in the ASN.1.

Note that the prime product check now moved to checkPrivateKey is broken
(Π should start at 1 not 0) and fixed in CL 632478.

Updates #69799
For #69536

Change-Id: I95a8bc1244755c6d15d7c4eb179135a15608ddd6
Reviewed-on: https://go-review.googlesource.com/c/go/+/632476
LUCI-TryBot-Result: Go LUCI <[email protected]>
Auto-Submit: Filippo Valsorda <[email protected]>
Reviewed-by: Roland Shoemaker <[email protected]>
Reviewed-by: Russ Cox <[email protected]>
gopherbot pushed a commit that referenced this issue Nov 30, 2024
It's about 2x slower, but we'll recover that by implementing trial
divisions in a follow-up CL.

Updates #69799
For #69536

Change-Id: Icc02f5a268b658d629bbe7fdaf2a42ad3b259e2c
Reviewed-on: https://go-review.googlesource.com/c/go/+/632477
Auto-Submit: Filippo Valsorda <[email protected]>
Reviewed-by: Russ Cox <[email protected]>
Reviewed-by: Roland Shoemaker <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
gopherbot pushed a commit that referenced this issue Nov 30, 2024
Turns out that recomputing them (and qInv in particular) in constant
time is expensive, so let's not throw them away when they are available.
They are much faster to check, so we now do that on precompute.

Also, thanks to the opaque crypto/internal/fips140/rsa.PrivateKey type,
we now have some assurance that the values we use are always ones we
checked.

Recovers most of the performance loss since CL 630516 in the happy path.
Also, since now we always use the CRT, if necessary by running a
throwaway Precompute, which is now cheap if PrecomputedValues is filled
out, we effectively fixed the JSON round-trip slowdown (#59695).

goos: darwin
goarch: arm64
pkg: crypto/rsa
cpu: Apple M2
                            │ 3b42687  │          f017604bc6-dirty           │
                            │   sec/op    │   sec/op     vs base                │
ParsePKCS8PrivateKey/2048-8   26.76µ ± 1%   65.99µ ± 1%  +146.64% (p=0.002 n=6)

Fixes #59695
Updates #69799
For #69536

Change-Id: I507f8c5a32e69ab28990a3bf78959836b9b08cc9
Reviewed-on: https://go-review.googlesource.com/c/go/+/632478
Auto-Submit: Filippo Valsorda <[email protected]>
Reviewed-by: Russ Cox <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Roland Shoemaker <[email protected]>
gopherbot pushed a commit that referenced this issue Nov 30, 2024
This is optimized to be cheap in terms of extra code and complexity,
rather than performance, so we reuse the GCD we have for inverting d.

Recovers most of the performance loss since CL 630516, although
benchmarking key generation is by nature extremely noisy.

goos: darwin
goarch: arm64
pkg: crypto/rsa
cpu: Apple M2
                   │ 3b42687  │           b3d018a1e8-dirty           │
                   │   sec/op    │    sec/op     vs base                │
GenerateKey/2048-8   104.1m ± 7%   139.7m ± 20%  +34.10% (p=0.000 n=20)

Updates #69799
For #69536

Change-Id: I00347610935db8feb0597529a301ad7ace5b2f22
Reviewed-on: https://go-review.googlesource.com/c/go/+/632479
Reviewed-by: Roland Shoemaker <[email protected]>
Auto-Submit: Filippo Valsorda <[email protected]>
Reviewed-by: Daniel McCarney <[email protected]>
Reviewed-by: Russ Cox <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/632535 mentions this issue: crypto/rsa: minor FIPS 186-5 compliance fixes

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/632537 mentions this issue: crypto/internal/fips140/rsa: add Pairwise Consistency Test

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/632536 mentions this issue: crypto/rsa: allow keys larger than 16384 bits in FIPS mode

gopherbot pushed a commit that referenced this issue Dec 3, 2024
None of these checks actually matter, and indeed we didn't have them
before, but they are required by FIPS 186-5.

Fixes #69799
For #69536

Change-Id: I5e866962a1b2a31a753053e5b9ec50a3f4c87394
Reviewed-on: https://go-review.googlesource.com/c/go/+/632535
Auto-Submit: Filippo Valsorda <[email protected]>
Reviewed-by: Roland Shoemaker <[email protected]>
Reviewed-by: Russ Cox <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
gopherbot pushed a commit that referenced this issue Dec 3, 2024
Nothing in the standard enforces an upper limit, and we can try
documenting an open range in the Security Policy. Worst case, this is
easy to revert.

For #69536

Change-Id: Id3082e73556fdcd6d2e6c2054c512516e9156c5c
Reviewed-on: https://go-review.googlesource.com/c/go/+/632536
Auto-Submit: Filippo Valsorda <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Michael Knyszek <[email protected]>
Reviewed-by: Russ Cox <[email protected]>
gopherbot pushed a commit that referenced this issue Dec 3, 2024
For #69536

Change-Id: I2cbb03fc942f5542b8a26347213304c2a3cb5268
Reviewed-on: https://go-review.googlesource.com/c/go/+/632537
Auto-Submit: Filippo Valsorda <[email protected]>
Reviewed-by: Russ Cox <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Michael Knyszek <[email protected]>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/634775 mentions this issue: crypto/internal/fips140/ecdsa: fix reseed_counter check for HMAC_DRBG_Generate_algorithm

gopherbot pushed a commit that referenced this issue Dec 10, 2024
…_Generate_algorithm

SP 800-90A Rev. 1 10.1.2.5 step 7 requires
	reseed_counter = reseed_counter + 1
as the final step before returning SUCCESS.

This increment of reseedCounter was missing, meaning the reseed interval
check at the start of Generate wasn't actually functional.

Given how it's used, and that it has a reseed interval of 2^48, this
condition will never actually occur but the check is still required by
the standard.

For #69536

Change-Id: I314a7eee5852e6d0fa1a0a04842003553cd803e7
Reviewed-on: https://go-review.googlesource.com/c/go/+/634775
Reviewed-by: Carlos Amedee <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Auto-Submit: Filippo Valsorda <[email protected]>
Reviewed-by: Filippo Valsorda <[email protected]>
Reviewed-by: Michael Knyszek <[email protected]>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/636558 mentions this issue: crypto/internal/fips140: add Name and Version

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/636775 mentions this issue: crypto/internal/fips140/aes: mark AES-ECB as not approved

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/636795 mentions this issue: crypto/cipher: block non-AES CTR and CBC in fips140=only mode

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants