Go 1.24+ Native FIPS Support for Easier Compliance
Go 1.24 adds built-in FIPS support, removing the need for third-party libraries and making secure, standards-compliant development much easier.
Join the DZone community and get the full member experience.
Join For FreeIn February, Go released version 1.24, introducing significant enhancements to its cryptographic libraries, particularly in achieving FIPS (Federal Information Processing Standards) compliance. This update positions Go as a superior choice for developers building applications for U.S. federal government use. By eliminating dependency on third-party libraries and integrating FIPS compliance directly into its core, Go 1.24 simplifies and streamlines development for government-regulated industries.
In this article, we’ll explore what FIPS is, why it matters, and how Go 1.24 changes the game for FIPS compliance.
FIPS
FIPS, or Federal Information Processing Standards, are a set of U.S. government security requirements for data protection and encryption. These standards are developed and maintained by the National Institute of Standards and Technology (NIST). FIPS compliance ensures that cryptographic processes used in applications meet the government’s stringent security and reliability standards.
FIPS compliance is not optional for service providers or organizations working with federal government applications. Non-compliance can result in disqualification from government contracts or even legal consequences in certain industries, such as defense or finance. To achieve FIPS compliance, two critical steps are required:
- Implementation of FIPS-Compliant Libraries: Cryptographic libraries used in the application must adhere to FIPS specifications. These libraries handle encryption, decryption, and secure data transmission.
- Certification: The libraries must be tested and certified by a Cryptographic Module Validation Program (CMVP)-accredited laboratory. This ensures that the implementation is robust and meets security standards.
Challenges Before Go 1.24
Before Go 1.24, achieving FIPS compliance in Go was not straightforward. Developers had to rely on external cryptographic libraries to meet FIPS requirements. These libraries were provided by different vendors and introduced fragmentation into the ecosystem. For example:
- Google: Provided BoringSSL, a fork of OpenSSL, to support Linux environments.
- Microsoft: Maintained separate FIPS-compliant libraries for Linux and Windows.
- Red Hat: Supplied libraries based on OpenSSL for FIPS compliance.
This fragmented approach created unnecessary complexity for Go developers. Selecting the right library for a specific operating system, ensuring compatibility with Go applications, and validating compliance were all challenging tasks.
Go CryptoGraphic Module
With Go 1.24, the language introduces native FIPS-compliant cryptographic libraries as part of its standard library. This eliminates the need for external libraries like OpenSSL or BoringSSL.
By integrating FIPS compliance directly into the Go standard library, developers gain:
- Broader compatibility across operating systems and environments.
- Elimination of reliance on external libraries.
- Simplified compliance processes.
The new cryptographic libraries are currently undergoing testing by CMVP-accredited laboratories, with Go developers committed to maintaining FIPS compliance in future versions.
Why Native FIPS Support Matters
The inclusion of native FIPS support in Go 1.24 positions the language as a leader in federal application development. Here's why:
- Simplified Compliance: Developers no longer need to validate external libraries for FIPS compliance.
- Ease of Use: Native support removes configuration complexity, allowing developers to focus on building applications.
- Future-Proofing: With Go maintaining FIPS compliance internally, upgrades to newer Go versions will be seamless.
Most languages rely on FIPS-compliant libraries from the base operating system such as OpenSSL.
For backward compatibility, Go 1.24 continues to support BoringSSL. However, this support is expected to be phased out in future releases, encouraging developers to adopt the new native cryptographic module.
Go HTTP server
Lets take a simple HTTP Server server as below and save it as "httpserver.go":
package main
import (
"fmt"
"net/http"
)
func hello(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "hello\n")
}
func headers(w http.ResponseWriter, req *http.Request) {
for name, headers := range req.Header {
for _, h := range headers {
fmt.Fprintf(w, "%v: %v\n", name, h)
}
}
}
func main() {
http.HandleFunc("/hello", hello)
http.HandleFunc("/headers", headers)
http.ListenAndServe(":8090", nil)
}
This code can be built using the following command:
go build httpserver.go
To check the FIPS libraries in use, the go tool nm module can be used:
go tool nm httpserver | grep -i fips
The output would be empty as there are no FIPS module included by default.
Using BoringSSL (Pre-1.24)
Compiling
Compiling of program for FIPS is no different from any other code other than adding the "GOEXPERIMENT=boringcrypto
" in their build command:
GOEXPERIMENT=boringcrypto go build myprogram.go
The go nm tool can also show all the FIPS enabled libraries that are part of your binary:
go tool nm myprogram.go | grep -i fips
The output of the tool should look similar to below:
go tool nm test | grep -i fips
1004bee14 B crypto/internal/boring/fipstls.required
10048d790 D crypto/tls.defaultCipherSuitesFIPS
10048d750 D crypto/tls.defaultCurvePreferencesFIPS
10048d770 D crypto/tls.defaultSupportedSignatureAlgorithmsFIPS
10048d730 D crypto/tls.defaultSupportedVersionsFIPS
The compiled binary now contain the FIPS libraries. However one of the limitations is that any dependent libraries might include a cryptographic module that is non FIPS compliant.
We can check the version of the go used to compile the binary as follows
go version httpserver
httpserver: go1.23.0
Go Support Strict Mode
The Go strict mode make the compilation fail if any of the dependent libraries are not FIPS enabled.
To enable strict FIPS mode, import crypto/tls/fipsonly
anywhere in your source code. We can modify our example as below:
package main
import (
_ "crypto/tls/fipsonly"
"fmt"
"net/http"
)
func hello(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w, "hello\n")
}
Strict mode will cause compilation to fail if incompatible libraries are used:
import _ “crypto/tls/fipsonly”
Using Go CryptoGraphy module (1.24+)
From version 1.24, FIPS support is enabled at runtime, eliminating the need for special compilation flags. Build your program using the go binary version 1.24 or later:
go build httpserver.go
Now, the FIPS libraries inclusion can be validated using:
go tool nm httpserver | grep -i fips
1004e8651 D _go:datafipsend
1004e8650 D _go:datafipsstart
1004a0140 D _go:fipsinfo
1004dc640 D _go:noptrdatafipsend
1004c4582 D _go:noptrdatafipsstart
100292a98 R _go:rodatafipsend
1002928da R _go:rodatafipsstart
100222150 T _go:textfipsend
1001e1a50 T _go:textfipsstart
1003153e0 R crypto/ecdsa..dict.publicKeyToFIPS[*crypto/internal/fips140/nistec.P224Point]
100315420 R crypto/ecdsa..dict.publicKeyToFIPS[*crypto/internal/fips140/nistec.P256Point]
100315460 R crypto/ecdsa..dict.publicKeyToFIPS[*crypto/internal/fips140/nistec.P384Point]
1003154a0 R crypto/ecdsa..dict.publicKeyToFIPS[*crypto/internal/fips140/nistec.P521Point]
100315c80 R crypto/ecdsa..dict.verifyFIPS[*crypto/internal/fips140/nistec.P224Point]
The version used to compile the go code can be validated using:
go version httpserver
httpserver: go1.24.0
To Enable FIPS Mode
To enable FIPS mode at runtime, set either GOFIPS=1
or GODEBUG=fips140=on
as environment variable:
export GOFIPS=1
export GODEBUG=fips140=on
Strict FIPS mode
Strict FIPS mode can be enabled with:
export GODEBUG=fips140=only
In strict mode, the program will fail or crash if non FIPS compliant libraries are detected.
Note: The GOFIPS=1
environment variable is expected to be deprecated in Go 1.25, so developers are encouraged to use GODEBUG
flags going forward.
Conclusion
Go 1.24 marks a significant milestone in simplifying FIPS compliance. By integrating FIPS-compliant cryptographic libraries into its standard library, Go eliminates the complexities of relying on external libraries. As Go continues to evolve, it is poised to become the go-to choice for federal application development.
Opinions expressed by DZone contributors are their own.
Comments