1
2
3
4
5 package fips140only_test
6
7 import (
8 "crypto"
9 "crypto/aes"
10 "crypto/cipher"
11 "crypto/des"
12 "crypto/dsa"
13 "crypto/ecdh"
14 "crypto/ecdsa"
15 "crypto/ed25519"
16 "crypto/elliptic"
17 "crypto/hkdf"
18 "crypto/hmac"
19 "crypto/hpke"
20 "crypto/internal/cryptotest"
21 "crypto/internal/fips140"
22 "crypto/internal/fips140only"
23 "crypto/md5"
24 "crypto/mlkem"
25 "crypto/mlkem/mlkemtest"
26 "crypto/pbkdf2"
27 "crypto/rand"
28 "crypto/rc4"
29 "crypto/rsa"
30 "crypto/sha1"
31 "crypto/sha256"
32 _ "crypto/sha3"
33 _ "crypto/sha512"
34 "crypto/x509"
35 "encoding/pem"
36 "fmt"
37 "internal/godebug"
38 "internal/testenv"
39 "io"
40 "math/big"
41 "os"
42 "strings"
43 "testing"
44
45 "golang.org/x/crypto/chacha20poly1305"
46 )
47
48 func TestFIPS140Only(t *testing.T) {
49 cryptotest.MustSupportFIPS140(t)
50 if !fips140only.Enforced() {
51 cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestFIPS140Only$", "-test.v")
52 cmd.Env = append(cmd.Environ(), "GODEBUG=fips140=only")
53 out, err := cmd.CombinedOutput()
54 t.Logf("running with GODEBUG=fips140=only:\n%s", out)
55 if err != nil {
56 t.Errorf("fips140=only subprocess failed: %v", err)
57 }
58 return
59 }
60 t.Run("cryptocustomrand=0", func(t *testing.T) {
61 t.Setenv("GODEBUG", os.Getenv("GODEBUG")+",cryptocustomrand=0")
62 testFIPS140Only(t)
63 })
64 t.Run("cryptocustomrand=1", func(t *testing.T) {
65 t.Setenv("GODEBUG", os.Getenv("GODEBUG")+",cryptocustomrand=1")
66 testFIPS140Only(t)
67 })
68 }
69
70 func testFIPS140Only(t *testing.T) {
71 if !fips140only.Enforced() {
72 t.Fatal("FIPS 140-only mode not enforced")
73 }
74 t.Logf("GODEBUG=fips140=only enabled")
75 fips140.ResetServiceIndicator()
76
77 aesBlock, err := aes.NewCipher(make([]byte, 16))
78 if err != nil {
79 t.Fatal(err)
80 }
81 notAESBlock := blockWrap{aesBlock}
82 iv := make([]byte, aes.BlockSize)
83
84 cipher.NewCBCEncrypter(aesBlock, iv)
85 expectPanic(t, func() { cipher.NewCBCEncrypter(notAESBlock, iv) })
86 cipher.NewCBCDecrypter(aesBlock, iv)
87 expectPanic(t, func() { cipher.NewCBCDecrypter(notAESBlock, iv) })
88
89 expectPanic(t, func() { cipher.NewCFBEncrypter(aesBlock, iv) })
90 expectPanic(t, func() { cipher.NewCFBDecrypter(aesBlock, iv) })
91
92 cipher.NewCTR(aesBlock, iv)
93 expectPanic(t, func() { cipher.NewCTR(notAESBlock, iv) })
94
95 expectPanic(t, func() { cipher.NewOFB(aesBlock, iv) })
96
97 expectErr(t, errRet2(cipher.NewGCM(aesBlock)))
98 expectErr(t, errRet2(cipher.NewGCMWithNonceSize(aesBlock, 12)))
99 expectErr(t, errRet2(cipher.NewGCMWithTagSize(aesBlock, 12)))
100 expectNoErr(t, errRet2(cipher.NewGCMWithRandomNonce(aesBlock)))
101
102 expectErr(t, errRet2(des.NewCipher(make([]byte, 8))))
103 expectErr(t, errRet2(des.NewTripleDESCipher(make([]byte, 24))))
104
105 expectErr(t, errRet2(rc4.NewCipher(make([]byte, 16))))
106
107 expectErr(t, errRet2(chacha20poly1305.New(make([]byte, chacha20poly1305.KeySize))))
108 expectErr(t, errRet2(chacha20poly1305.NewX(make([]byte, chacha20poly1305.KeySize))))
109
110 expectPanic(t, func() { md5.New().Sum(nil) })
111 expectErr(t, errRet2(md5.New().Write(make([]byte, 16))))
112 expectPanic(t, func() { md5.Sum([]byte("foo")) })
113
114 expectPanic(t, func() { sha1.New().Sum(nil) })
115 expectErr(t, errRet2(sha1.New().Write(make([]byte, 16))))
116 expectPanic(t, func() { sha1.Sum([]byte("foo")) })
117
118 withApprovedHash(func(h crypto.Hash) { h.New().Sum(nil) })
119 withNonApprovedHash(func(h crypto.Hash) { expectPanic(t, func() { h.New().Sum(nil) }) })
120
121 expectErr(t, errRet2(pbkdf2.Key(sha256.New, "password", make([]byte, 16), 1, 10)))
122 expectErr(t, errRet2(pbkdf2.Key(sha256.New, "password", make([]byte, 10), 1, 14)))
123 withNonApprovedHash(func(h crypto.Hash) {
124 expectErr(t, errRet2(pbkdf2.Key(h.New, "password", make([]byte, 16), 1, 14)))
125 })
126 withApprovedHash(func(h crypto.Hash) {
127 expectNoErr(t, errRet2(pbkdf2.Key(h.New, "password", make([]byte, 16), 1, 14)))
128 })
129
130 expectPanic(t, func() { hmac.New(sha256.New, make([]byte, 10)) })
131 withNonApprovedHash(func(h crypto.Hash) {
132 expectPanic(t, func() { hmac.New(h.New, make([]byte, 16)) })
133 })
134 withApprovedHash(func(h crypto.Hash) { hmac.New(h.New, make([]byte, 16)) })
135
136 expectErr(t, errRet2(hkdf.Key(sha256.New, make([]byte, 10), nil, "", 16)))
137 withNonApprovedHash(func(h crypto.Hash) {
138 expectErr(t, errRet2(hkdf.Key(h.New, make([]byte, 16), nil, "", 16)))
139 })
140 withApprovedHash(func(h crypto.Hash) {
141 expectNoErr(t, errRet2(hkdf.Key(h.New, make([]byte, 16), nil, "", 16)))
142 })
143
144 expectErr(t, errRet2(hkdf.Extract(sha256.New, make([]byte, 10), nil)))
145 withNonApprovedHash(func(h crypto.Hash) {
146 expectErr(t, errRet2(hkdf.Extract(h.New, make([]byte, 16), nil)))
147 })
148 withApprovedHash(func(h crypto.Hash) {
149 expectNoErr(t, errRet2(hkdf.Extract(h.New, make([]byte, 16), nil)))
150 })
151
152 expectErr(t, errRet2(hkdf.Expand(sha256.New, make([]byte, 10), "", 16)))
153 withNonApprovedHash(func(h crypto.Hash) {
154 expectErr(t, errRet2(hkdf.Expand(h.New, make([]byte, 16), "", 16)))
155 })
156 withApprovedHash(func(h crypto.Hash) {
157 expectNoErr(t, errRet2(hkdf.Expand(h.New, make([]byte, 16), "", 16)))
158 })
159
160 expectErr(t, errRet2(rand.Prime(rand.Reader, 10)))
161
162 expectErr(t, dsa.GenerateParameters(&dsa.Parameters{}, rand.Reader, dsa.L1024N160))
163 expectErr(t, dsa.GenerateKey(&dsa.PrivateKey{}, rand.Reader))
164 expectErr(t, errRet3(dsa.Sign(rand.Reader, &dsa.PrivateKey{}, make([]byte, 16))))
165 expectPanic(t, func() {
166 dsa.Verify(&dsa.PublicKey{}, make([]byte, 16), big.NewInt(1), big.NewInt(1))
167 })
168
169 expectErr(t, errRet2(ecdh.X25519().GenerateKey(rand.Reader)))
170 expectErr(t, errRet2(ecdh.X25519().NewPrivateKey(make([]byte, 32))))
171 expectErr(t, errRet2(ecdh.X25519().NewPublicKey(make([]byte, 32))))
172 for _, curve := range []ecdh.Curve{ecdh.P256(), ecdh.P384(), ecdh.P521()} {
173 expectErrIfCustomRand(t, errRet2(curve.GenerateKey(readerWrap{rand.Reader})))
174 k, err := curve.GenerateKey(rand.Reader)
175 if err != nil {
176 t.Fatal(err)
177 }
178 expectNoErr(t, errRet2(curve.NewPrivateKey(k.Bytes())))
179 expectNoErr(t, errRet2(curve.NewPublicKey(k.PublicKey().Bytes())))
180 }
181
182 for _, curve := range []elliptic.Curve{elliptic.P256(), elliptic.P384(), elliptic.P521()} {
183 expectErrIfCustomRand(t, errRet2(ecdsa.GenerateKey(curve, readerWrap{rand.Reader})))
184 k, err := ecdsa.GenerateKey(curve, rand.Reader)
185 if err != nil {
186 t.Fatal(err)
187 }
188
189 expectErrIfCustomRand(t, errRet2(k.Sign(readerWrap{rand.Reader}, make([]byte, 32), nil)))
190 expectErrIfCustomRand(t, errRet2(ecdsa.SignASN1(readerWrap{rand.Reader}, k, make([]byte, 32))))
191 expectErrIfCustomRand(t, errRet3(ecdsa.Sign(readerWrap{rand.Reader}, k, make([]byte, 32))))
192 expectNoErr(t, errRet2(k.Sign(rand.Reader, make([]byte, 32), nil)))
193 expectNoErr(t, errRet2(ecdsa.SignASN1(rand.Reader, k, make([]byte, 32))))
194 expectNoErr(t, errRet3(ecdsa.Sign(rand.Reader, k, make([]byte, 32))))
195
196 withNonApprovedHash(func(h crypto.Hash) {
197 expectErr(t, errRet2(k.Sign(nil, make([]byte, h.Size()), h)))
198 })
199 withApprovedHash(func(h crypto.Hash) {
200 expectNoErr(t, errRet2(k.Sign(nil, make([]byte, h.Size()), h)))
201 })
202 }
203 customCurve := &elliptic.CurveParams{Name: "custom", P: big.NewInt(1)}
204 expectErr(t, errRet2(ecdsa.GenerateKey(customCurve, rand.Reader)))
205
206 _, ed25519Key, err := ed25519.GenerateKey(rand.Reader)
207 if err != nil {
208 t.Fatal(err)
209 }
210 expectNoErr(t, errRet2(ed25519Key.Sign(nil, make([]byte, 32), crypto.Hash(0))))
211 expectNoErr(t, errRet2(ed25519Key.Sign(nil, make([]byte, 64), crypto.SHA512)))
212
213 expectErr(t, errRet2(ed25519Key.Sign(nil, make([]byte, 32), &ed25519.Options{
214 Context: "test",
215 })))
216 expectNoErr(t, errRet2(ed25519Key.Sign(nil, make([]byte, 64), &ed25519.Options{
217 Hash: crypto.SHA512, Context: "test",
218 })))
219 expectNoErr(t, errRet2(ed25519Key.Sign(nil, make([]byte, 64), &ed25519.Options{
220 Hash: crypto.SHA512,
221 })))
222
223 expectErr(t, errRet2(rsa.GenerateMultiPrimeKey(rand.Reader, 3, 2048)))
224 expectErr(t, errRet2(rsa.GenerateKey(rand.Reader, 1024)))
225 expectErr(t, errRet2(rsa.GenerateKey(rand.Reader, 2049)))
226 expectErrIfCustomRand(t, errRet2(rsa.GenerateKey(readerWrap{rand.Reader}, 2048)))
227 rsaKey, err := rsa.GenerateKey(rand.Reader, 2048)
228 expectNoErr(t, err)
229
230 smallKey := parseKey(testingKey(`-----BEGIN RSA TESTING KEY-----
231 MIICXQIBAAKBgQDMrln6XoAa3Rjts+kRi5obbP86qSf/562RcuDO+yMXeTLHfi4M
232 8ubyhoFY+UKBCGBLmmTO7ikbvQgdipkT3xVkU8nM3XTW4sxrnw0X5QXsl4PGlMo0
233 5UufxYyQxe7bbjuwFz2XnN6Jz4orpOfO0s36/KVHj9lZRl+REpr/Jy+nJQIDAQAB
234 AoGAJ9WEwGO01cWSzOwXH2mGX/EKCQ4TsUuS7XwogU/B6BcXyVhmuPFq/ecsdDbq
235 ePc62mvdU6JpELNsyWcIXKQtYsRgJHxNS+KJkCQIq6YeiAWRG0XL6q+qVj+HtT8a
236 1Qrmul9ZBd23Y9wLF8pg/xWDQYvb8DPAb/xJ0e/KEBZcWU8CQQDXFCFCGpCfwyxY
237 Cq8G/3B94D9UYwk5mK6jRIH5m8LbaX9bKKetf8+If8TWVgeuiRjjN4WEQ78lPoSg
238 3Fsz2qs3AkEA85/JCudNUf2FnY+T6h1c/2SWekZiZ1NS4lCh/C7iYuAN3oa8zGkf
239 gjjR5e0+Z8rUAcZkTukxyLLaNqy6rs9GgwJAVR6pXvEGhcQHe7yWso1LpvWl+q7L
240 StkrXIBTdEb54j4pYhl/6wFnUB1I+I7JsYCeseYaWFM7hfDtKoCrM6V6FwJBANxh
241 KmfmnJcSkw/YlaEuNrYAs+6gRNvbEBsRfba2Yqu2qlUl5Ruz7IDMDXPEjLMvU2DX
242 ql2HrTU0NRlIXwdLESkCQQDGJ54H6WK1eE1YvtxCaLm28zmogcFlvc21pym+PpM1
243 bXVL8iKLrG91IYQByUHZIn3WVAd2bfi4MfKagRt0ggd4
244 -----END RSA TESTING KEY-----`))
245
246 expectNoErr(t, errRet2(rsaKey.Sign(rand.Reader, make([]byte, 32), crypto.SHA256)))
247 expectErr(t, errRet2(smallKey.Sign(rand.Reader, make([]byte, 32), crypto.SHA256)))
248 expectErr(t, errRet2(rsaKey.Sign(rand.Reader, make([]byte, 20), crypto.SHA1)))
249
250 expectNoErr(t, errRet2(rsaKey.Sign(readerWrap{rand.Reader}, make([]byte, 32), crypto.SHA256)))
251
252 sigPKCS1v15, err := rsa.SignPKCS1v15(rand.Reader, rsaKey, crypto.SHA256, make([]byte, 32))
253 expectNoErr(t, err)
254 expectErr(t, errRet2(rsa.SignPKCS1v15(rand.Reader, smallKey, crypto.SHA256, make([]byte, 32))))
255 expectErr(t, errRet2(rsa.SignPKCS1v15(rand.Reader, rsaKey, crypto.SHA1, make([]byte, 20))))
256
257 expectNoErr(t, errRet2(rsa.SignPKCS1v15(readerWrap{rand.Reader}, rsaKey, crypto.SHA256, make([]byte, 32))))
258
259 expectNoErr(t, rsa.VerifyPKCS1v15(&rsaKey.PublicKey, crypto.SHA256, make([]byte, 32), sigPKCS1v15))
260 expectErr(t, rsa.VerifyPKCS1v15(&smallKey.PublicKey, crypto.SHA256, make([]byte, 32), sigPKCS1v15))
261 expectErr(t, rsa.VerifyPKCS1v15(&rsaKey.PublicKey, crypto.SHA1, make([]byte, 20), sigPKCS1v15))
262
263 sigPSS, err := rsa.SignPSS(rand.Reader, rsaKey, crypto.SHA256, make([]byte, 32), nil)
264 expectNoErr(t, err)
265 expectErr(t, errRet2(rsa.SignPSS(rand.Reader, smallKey, crypto.SHA256, make([]byte, 32), nil)))
266 expectErr(t, errRet2(rsa.SignPSS(rand.Reader, rsaKey, crypto.SHA1, make([]byte, 20), nil)))
267 expectErr(t, errRet2(rsa.SignPSS(readerWrap{rand.Reader}, rsaKey, crypto.SHA256, make([]byte, 32), nil)))
268
269 expectNoErr(t, rsa.VerifyPSS(&rsaKey.PublicKey, crypto.SHA256, make([]byte, 32), sigPSS, nil))
270 expectErr(t, rsa.VerifyPSS(&smallKey.PublicKey, crypto.SHA256, make([]byte, 32), sigPSS, nil))
271 expectErr(t, rsa.VerifyPSS(&rsaKey.PublicKey, crypto.SHA1, make([]byte, 20), sigPSS, nil))
272
273 k, err := mlkem.GenerateKey768()
274 expectNoErr(t, err)
275 expectErr(t, errRet3(mlkemtest.Encapsulate768(k.EncapsulationKey(), make([]byte, 32))))
276 k1024, err := mlkem.GenerateKey1024()
277 expectNoErr(t, err)
278 expectErr(t, errRet3(mlkemtest.Encapsulate1024(k1024.EncapsulationKey(), make([]byte, 32))))
279
280 for _, kem := range []hpke.KEM{
281 hpke.DHKEM(ecdh.P256()),
282 hpke.DHKEM(ecdh.P384()),
283 hpke.DHKEM(ecdh.P521()),
284 hpke.MLKEM768(),
285 hpke.MLKEM1024(),
286 hpke.MLKEM768P256(),
287 hpke.MLKEM1024P384(),
288 hpke.MLKEM768X25519(),
289 } {
290 t.Run(fmt.Sprintf("HKPE KEM %04x", kem.ID()), func(t *testing.T) {
291 k, err := kem.GenerateKey()
292 expectNoErr(t, err)
293 expectNoErr(t, errRet2(kem.DeriveKeyPair(make([]byte, 64))))
294 kb, err := k.Bytes()
295 expectNoErr(t, err)
296 expectNoErr(t, errRet2(kem.NewPrivateKey(kb)))
297 expectNoErr(t, errRet2(kem.NewPublicKey(k.PublicKey().Bytes())))
298 if fips140.Version() == "v1.0.0" {
299 t.Skip("FIPS 140-3 Module v1.0.0 does not provide HPKE GCM modes")
300 }
301 c, err := hpke.Seal(k.PublicKey(), hpke.HKDFSHA256(), hpke.AES128GCM(), nil, nil)
302 expectNoErr(t, err)
303 _, err = hpke.Open(k, hpke.HKDFSHA256(), hpke.AES128GCM(), nil, c)
304 expectNoErr(t, err)
305 })
306 }
307 expectErr(t, errRet2(hpke.DHKEM(ecdh.X25519()).GenerateKey()))
308 expectErr(t, errRet2(hpke.DHKEM(ecdh.X25519()).DeriveKeyPair(make([]byte, 64))))
309 expectErr(t, errRet2(hpke.DHKEM(ecdh.X25519()).NewPrivateKey(make([]byte, 32))))
310 expectErr(t, errRet2(hpke.DHKEM(ecdh.X25519()).NewPublicKey(make([]byte, 32))))
311 hpkeK, err := hpke.MLKEM768().GenerateKey()
312 expectNoErr(t, err)
313 expectErr(t, errRet2(hpke.Seal(hpkeK.PublicKey(), hpke.HKDFSHA256(), hpke.ChaCha20Poly1305(), nil, nil)))
314 expectErr(t, errRet2(hpke.Open(hpkeK, hpke.HKDFSHA256(), hpke.ChaCha20Poly1305(), nil, make([]byte, 2000))))
315
316
317
318 if !fips140.ServiceIndicator() {
319 t.Errorf("service indicator not set")
320 }
321 }
322
323 type blockWrap struct {
324 cipher.Block
325 }
326
327 type readerWrap struct {
328 io.Reader
329 }
330
331 func withApprovedHash(f func(crypto.Hash)) {
332 f(crypto.SHA224)
333 f(crypto.SHA256)
334 f(crypto.SHA384)
335 f(crypto.SHA512)
336 f(crypto.SHA3_224)
337 f(crypto.SHA3_256)
338 f(crypto.SHA3_384)
339 f(crypto.SHA3_512)
340 f(crypto.SHA512_224)
341 f(crypto.SHA512_256)
342 }
343
344 func withNonApprovedHash(f func(crypto.Hash)) {
345 f(crypto.MD5)
346 f(crypto.SHA1)
347 }
348
349 func expectPanic(t *testing.T, f func()) {
350 t.Helper()
351 defer func() {
352 t.Helper()
353 if err := recover(); err == nil {
354 t.Errorf("expected panic")
355 } else {
356 if s, ok := err.(string); !ok || !strings.Contains(s, "FIPS 140-only") {
357 t.Errorf("unexpected panic: %v", err)
358 }
359 }
360 }()
361 f()
362 }
363
364 var cryptocustomrand = godebug.New("cryptocustomrand")
365
366 func expectErr(t *testing.T, err error) {
367 t.Helper()
368 if err == nil {
369 t.Errorf("expected error")
370 } else if !strings.Contains(err.Error(), "FIPS 140-only") {
371 t.Errorf("unexpected error: %v", err)
372 }
373 }
374
375 func expectNoErr(t *testing.T, err error) {
376 t.Helper()
377 if err != nil {
378 t.Errorf("unexpected error: %v", err)
379 }
380 }
381
382 func expectErrIfCustomRand(t *testing.T, err error) {
383 t.Helper()
384 if cryptocustomrand.Value() == "1" {
385 expectErr(t, err)
386 } else {
387 expectNoErr(t, err)
388 }
389 }
390
391 func errRet2[T any](_ T, err error) error {
392 return err
393 }
394
395 func errRet3[T any](_, _ T, err error) error {
396 return err
397 }
398
399 func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") }
400
401 func parseKey(s string) *rsa.PrivateKey {
402 p, _ := pem.Decode([]byte(s))
403 k, err := x509.ParsePKCS1PrivateKey(p.Bytes)
404 if err != nil {
405 panic(err)
406 }
407 return k
408 }
409
View as plain text