Refactor the crypt package to support FIPS encryption #6
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is with the aim of providing a FIPS-140 compliant version of this package and related tools: #2.
The existing NaCl secretbox algorithm is not a FIPS-140 approved algorithm, so this commit adds a second AES-256-GCM option, which is.
Users can make an explicit runtime decision to use the FIPS algorithm through the new
EncryptFIPS()
method. The existingDecrypt()
method has been taught to recognise ciphertext encrypted this way using the version prefix machinery.In addition, the package can now be built with a 'fips' tag. When this occurs, we swap out the NaCl algorithm for AES-256-GCM in
Encrypt()
and all attempts to call the NaCl algorithm will result in a new error,ErrFIPS
.Since software essentially expects to be FIPS-compliant or not (there is no gray zone), a compile-time setting seems like the most coherent choice for users who are expected to operate in these environments. I've found a few other examples of this pattern in the Go ecosystem.
The crypt API now includes a global constant indicates whether the package was built in "FIPS mode", and there are also some new tests for this constant that effectively verify the build tags.
Important Caveat
This change alone cannot produce a FIPS-compliant binary, because Go's
crypto
packages are not FIPS-compilant.One must also build using the
dev.boringcrypto
Go toolchain, which swaps out thecrypto
package for one backed by BoringSSL -- itself a validated library. This is an emerging best practice for Go tools that want to be FIPS-compliant.