1
2
3
4
5
6
7
8
9
10
11
12
13
14 package fipstest
15
16 import (
17 "bytes"
18 "crypto/internal/boring"
19 "crypto/internal/cryptotest"
20 "crypto/internal/fips140"
21 "crypto/internal/fips140/aes"
22 "crypto/internal/fips140/aes/gcm"
23 "crypto/internal/fips140/check"
24 "crypto/internal/fips140/drbg"
25 "crypto/internal/fips140/ecdh"
26 "crypto/internal/fips140/ecdsa"
27 "crypto/internal/fips140/ed25519"
28 "crypto/internal/fips140/hkdf"
29 "crypto/internal/fips140/hmac"
30 "crypto/internal/fips140/mlkem"
31 "crypto/internal/fips140/pbkdf2"
32 "crypto/internal/fips140/rsa"
33 "crypto/internal/fips140/sha256"
34 "crypto/internal/fips140/sha3"
35 "crypto/internal/fips140/sha512"
36 "crypto/internal/fips140/tls12"
37 "crypto/internal/fips140/tls13"
38 "crypto/rand"
39 "encoding/hex"
40 "runtime/debug"
41 "strings"
42 "testing"
43 )
44
45 func moduleStatus(t *testing.T) {
46 if fips140.Enabled {
47 t.Log("FIPS 140-3 mode enabled")
48 } else {
49 t.Log("FIPS 140-3 mode not enabled")
50 }
51
52 t.Logf("Module name: %s", fips140.Name())
53 t.Logf("Module version: %s", fips140.Version())
54
55 if noPAAPAI {
56 t.Log("PAA/PAI disabled")
57 } else {
58 t.Log("PAA/PAI enabled")
59 }
60
61 if check.Verified {
62 t.Log("FIPS 140-3 integrity self-check succeeded")
63 } else {
64 t.Log("FIPS 140-3 integrity self-check not succeeded")
65 }
66 }
67
68 func TestVersion(t *testing.T) {
69 bi, ok := debug.ReadBuildInfo()
70 if !ok {
71 t.Skip("no build info")
72 }
73 for _, setting := range bi.Settings {
74 if setting.Key != "GOFIPS140" {
75 continue
76 }
77 exp := setting.Value
78
79
80 exp, _, _ = strings.Cut(exp, "-")
81 if v := fips140.Version(); v != exp {
82 t.Errorf("Version is %q, expected %q", v, exp)
83 }
84 return
85 }
86
87 if v := fips140.Version(); v != "latest" {
88 t.Errorf("Version is %q, expected latest", v)
89 }
90 }
91
92 func TestFIPS140(t *testing.T) {
93 moduleStatus(t)
94 if boring.Enabled {
95 t.Skip("Go+BoringCrypto shims prevent the service indicator from being set")
96 }
97
98 aesKey := make([]byte, 128/8)
99 aesIV := make([]byte, aes.BlockSize)
100 plaintext := []byte("Go Cryptographic Module TestFIPS140 plaintext...")
101 plaintextSHA256 := decodeHex(t, "06b2614e2ef315832b23f5d0ff70294d8ddd3889527dfbe75707fe41da929325")
102 plaintextSHA384 := decodeHex(t, "ad20990965f6caec69e016072881f80f049c0687554809901ec4c0988c3fec678c0926fe5661742185be968de6c4d9b2")
103 aesBlock, err := aes.New(aesKey)
104 fatalIfErr(t, err)
105
106 testFIPS140v126(t, plaintext)
107
108 t.Run("AES-CTR", func(t *testing.T) {
109 ensureServiceIndicator(t)
110 ctr := aes.NewCTR(aesBlock, aesIV)
111 ciphertext := make([]byte, len(plaintext))
112 ctr.XORKeyStream(ciphertext, plaintext)
113 t.Logf("AES-CTR ciphertext: %x", ciphertext)
114 out := make([]byte, len(plaintext))
115 ctr = aes.NewCTR(aesBlock, aesIV)
116 ctr.XORKeyStream(out, ciphertext)
117 t.Logf("AES-CTR decrypted plaintext: %s", out)
118 if !bytes.Equal(plaintext, out) {
119 t.Errorf("AES-CTR round trip failed")
120 }
121 })
122
123 t.Run("AES-CBC", func(t *testing.T) {
124 ensureServiceIndicator(t)
125 cbcEnc := aes.NewCBCEncrypter(aesBlock, [16]byte(aesIV))
126 ciphertext := make([]byte, len(plaintext))
127 cbcEnc.CryptBlocks(ciphertext, plaintext)
128 t.Logf("AES-CBC ciphertext: %x", ciphertext)
129 cbcDec := aes.NewCBCDecrypter(aesBlock, [16]byte(aesIV))
130 out := make([]byte, len(plaintext))
131 cbcDec.CryptBlocks(out, ciphertext)
132 t.Logf("AES-CBC decrypted plaintext: %s", out)
133 if !bytes.Equal(plaintext, out) {
134 t.Errorf("AES-CBC round trip failed")
135 }
136 })
137
138 t.Run("AES-GCM", func(t *testing.T) {
139 ensureServiceIndicator(t)
140 g, err := gcm.New(aesBlock, 12, 16)
141 fatalIfErr(t, err)
142 nonce := make([]byte, 12)
143 ciphertext := make([]byte, len(plaintext)+g.Overhead())
144 gcm.SealWithRandomNonce(g, nonce, ciphertext, plaintext, nil)
145 t.Logf("AES-GCM ciphertext: %x", ciphertext)
146 out, err := g.Open(nil, nonce, ciphertext, nil)
147 fatalIfErr(t, err)
148 t.Logf("AES-GCM decrypted plaintext: %s", out)
149 if !bytes.Equal(plaintext, out) {
150 t.Errorf("AES-GCM round trip failed")
151 }
152 })
153
154 t.Run("Counter KDF", func(t *testing.T) {
155 ensureServiceIndicator(t)
156 k := gcm.NewCounterKDF(aesBlock)
157 context := [12]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
158 key := k.DeriveKey(0x01, context)
159 t.Logf("Counter KDF key: %x", key)
160 })
161
162 t.Run("KAS-ECC-SSC ephemeralUnified", func(t *testing.T) {
163 ensureServiceIndicator(t)
164 k, err := ecdh.GenerateKey(ecdh.P256(), rand.Reader)
165 fatalIfErr(t, err)
166 pk := k.PublicKey()
167 shared, err := ecdh.ECDH(ecdh.P256(), k, pk)
168 fatalIfErr(t, err)
169 t.Logf("KAS-ECC-SSC shared secret: %x", shared)
170 })
171
172 t.Run("ECDSA KeyGen, SigGen, SigVer", func(t *testing.T) {
173 ensureServiceIndicator(t)
174 k, err := ecdsa.GenerateKey(ecdsa.P256(), rand.Reader)
175 fatalIfErr(t, err)
176
177 sig, err := ecdsa.Sign(ecdsa.P256(), sha256.New, k, rand.Reader, plaintextSHA256)
178 fatalIfErr(t, err)
179 t.Logf("ECDSA signature: %x", sig)
180 err = ecdsa.Verify(ecdsa.P256(), k.PublicKey(), plaintextSHA256, sig)
181 if err != nil {
182 t.Errorf("ECDSA signature verification failed")
183 }
184
185 sig, err = ecdsa.SignDeterministic(ecdsa.P256(), sha256.New, k, plaintextSHA256)
186 fatalIfErr(t, err)
187 t.Logf("ECDSA deterministic signature: %x", sig)
188 err = ecdsa.Verify(ecdsa.P256(), k.PublicKey(), plaintextSHA256, sig)
189 if err != nil {
190 t.Errorf("ECDSA deterministic signature verification failed")
191 }
192 })
193
194 t.Run("EDDSA KeyGen, SigGen, SigVer", func(t *testing.T) {
195 ensureServiceIndicator(t)
196 k, err := ed25519.GenerateKey()
197 fatalIfErr(t, err)
198
199 sig := ed25519.Sign(k, plaintext)
200 t.Logf("EDDSA signature: %x", sig)
201
202 pk, err := ed25519.NewPublicKey(k.PublicKey())
203 fatalIfErr(t, err)
204 err = ed25519.Verify(pk, plaintext, sig)
205 if err != nil {
206 t.Errorf("EDDSA signature verification failed")
207 }
208 })
209
210 t.Run("ctrDRBG", func(t *testing.T) {
211 ensureServiceIndicator(t)
212 r := drbg.NewCounter((*[48]byte)(plaintext))
213 r.Reseed((*[48]byte)(plaintext), (*[48]byte)(plaintext))
214 out := make([]byte, 16)
215 r.Generate(out, (*[48]byte)(plaintext))
216 t.Logf("ctrDRBG output: %x", out)
217 })
218
219 t.Run("HMAC", func(t *testing.T) {
220 ensureServiceIndicator(t)
221 h := hmac.New(sha256.New, plaintext)
222 h.Write(plaintext)
223 out := h.Sum(nil)
224 t.Logf("HMAC output: %x", out)
225 })
226
227 t.Run("HMAC w/ Keccak-256 [NOT APPROVED]", func(t *testing.T) {
228 cryptotest.MustMinimumFIPS140ModuleVersion(t, "v1.28.0")
229 ensureServiceIndicatorFalse(t)
230 h := hmac.New(sha3.NewLegacyKeccak256, plaintext)
231 h.Write(plaintext)
232 out := h.Sum(nil)
233 t.Logf("HMAC w/ Keccak-256 output: %x", out)
234 })
235
236 t.Run("ML-KEM KeyGen, Encap, Decap", func(t *testing.T) {
237 ensureServiceIndicator(t)
238 k, err := mlkem.GenerateKey768()
239 fatalIfErr(t, err)
240
241 ss, c := k.EncapsulationKey().Encapsulate()
242 t.Logf("ML-KEM encapsulation: %x", c)
243
244 ss2, err := k.Decapsulate(c)
245 fatalIfErr(t, err)
246 t.Logf("ML-KEM shared secret: %x", ss)
247 if !bytes.Equal(ss, ss2) {
248 t.Errorf("ML-KEM round trip failed")
249 }
250 })
251
252 var rsaKey *rsa.PrivateKey
253 t.Run("RSA KeyGen", func(t *testing.T) {
254 ensureServiceIndicator(t)
255 var err error
256 rsaKey, err = rsa.GenerateKey(rand.Reader, 2048)
257 fatalIfErr(t, err)
258 t.Log("RSA key generated")
259 })
260
261 t.Run("RSA SigGen, SigVer PKCS 1.5", func(t *testing.T) {
262 ensureServiceIndicator(t)
263 sig, err := rsa.SignPKCS1v15(rsaKey, "SHA-256", plaintextSHA256)
264 fatalIfErr(t, err)
265 t.Logf("RSA PKCS1v15 signature: %x", sig)
266
267 err = rsa.VerifyPKCS1v15(rsaKey.PublicKey(), "SHA-256", plaintextSHA256, sig)
268 fatalIfErr(t, err)
269 })
270
271 t.Run("RSA SigGen, SigVer PSS", func(t *testing.T) {
272 ensureServiceIndicator(t)
273 sig, err := rsa.SignPSS(rand.Reader, rsaKey, sha256.New(), plaintextSHA256, 16)
274 fatalIfErr(t, err)
275 t.Logf("RSA PSS signature: %x", sig)
276
277 err = rsa.VerifyPSS(rsaKey.PublicKey(), sha256.New(), plaintextSHA256, sig)
278 fatalIfErr(t, err)
279 })
280
281 t.Run("RSA SigGen PSS w/ Keccak-256 [NOT APPROVED]", func(t *testing.T) {
282 cryptotest.MustMinimumFIPS140ModuleVersion(t, "v1.28.0")
283 ensureServiceIndicatorFalse(t)
284 sig, err := rsa.SignPSS(rand.Reader, rsaKey, sha3.NewLegacyKeccak256(), plaintextSHA256, 16)
285 fatalIfErr(t, err)
286 t.Logf("RSA PSS w/ Keccak-256 signature: %x", sig)
287 })
288
289 t.Run("RSA KeyGen w/ small key [NOT APPROVED]", func(t *testing.T) {
290 ensureServiceIndicatorFalse(t)
291 _, err := rsa.GenerateKey(rand.Reader, 512)
292 fatalIfErr(t, err)
293 t.Log("RSA key generated")
294 })
295
296 t.Run("KTS IFC OAEP", func(t *testing.T) {
297 ensureServiceIndicator(t)
298 c, err := rsa.EncryptOAEP(sha256.New(), sha256.New(), rand.Reader, rsaKey.PublicKey(), plaintextSHA256, nil)
299 fatalIfErr(t, err)
300 t.Logf("RSA OAEP ciphertext: %x", c)
301
302 out, err := rsa.DecryptOAEP(sha256.New(), sha256.New(), rsaKey, c, nil)
303 fatalIfErr(t, err)
304 t.Logf("RSA OAEP decrypted plaintext: %x", out)
305 if !bytes.Equal(plaintextSHA256, out) {
306 t.Errorf("RSA OAEP round trip failed")
307 }
308 })
309
310 t.Run("SHA2-224", func(t *testing.T) {
311 ensureServiceIndicator(t)
312 h := sha256.New224()
313 h.Write(plaintext)
314 out := h.Sum(nil)
315 t.Logf("SHA2-224 output: %x", out)
316 })
317
318 t.Run("SHA2-256", func(t *testing.T) {
319 ensureServiceIndicator(t)
320 h := sha256.New()
321 h.Write(plaintext)
322 out := h.Sum(nil)
323 t.Logf("SHA2-256 output: %x", out)
324 })
325
326 t.Run("SHA2-384", func(t *testing.T) {
327 ensureServiceIndicator(t)
328 h := sha512.New384()
329 h.Write(plaintext)
330 out := h.Sum(nil)
331 t.Logf("SHA2-384 output: %x", out)
332 })
333
334 t.Run("SHA2-512", func(t *testing.T) {
335 ensureServiceIndicator(t)
336 h := sha512.New()
337 h.Write(plaintext)
338 out := h.Sum(nil)
339 t.Logf("SHA2-512 output: %x", out)
340 })
341
342 t.Run("SHA2-512/224", func(t *testing.T) {
343 ensureServiceIndicator(t)
344 h := sha512.New512_224()
345 h.Write(plaintext)
346 out := h.Sum(nil)
347 t.Logf("SHA2-512/224 output: %x", out)
348 })
349
350 t.Run("SHA2-512/256", func(t *testing.T) {
351 ensureServiceIndicator(t)
352 h := sha512.New512_256()
353 h.Write(plaintext)
354 out := h.Sum(nil)
355 t.Logf("SHA2-512/256 output: %x", out)
356 })
357
358 t.Run("SHA3-224", func(t *testing.T) {
359 ensureServiceIndicator(t)
360 h := sha3.New224()
361 h.Write(plaintext)
362 out := h.Sum(nil)
363 t.Logf("SHA3-224 output: %x", out)
364 })
365
366 t.Run("SHA3-256", func(t *testing.T) {
367 ensureServiceIndicator(t)
368 h := sha3.New256()
369 h.Write(plaintext)
370 out := h.Sum(nil)
371 t.Logf("SHA3-256 output: %x", out)
372 })
373
374 t.Run("SHA3-384", func(t *testing.T) {
375 ensureServiceIndicator(t)
376 h := sha3.New384()
377 h.Write(plaintext)
378 out := h.Sum(nil)
379 t.Logf("SHA3-384 output: %x", out)
380 })
381
382 t.Run("SHA3-512", func(t *testing.T) {
383 ensureServiceIndicator(t)
384 h := sha3.New512()
385 h.Write(plaintext)
386 out := h.Sum(nil)
387 t.Logf("SHA3-512 output: %x", out)
388 })
389
390 t.Run("SHAKE-128", func(t *testing.T) {
391 ensureServiceIndicator(t)
392 h := sha3.NewShake128()
393 h.Write(plaintext)
394 out := make([]byte, 16)
395 h.Read(out)
396 t.Logf("SHAKE-128 output: %x", out)
397 })
398
399 t.Run("SHAKE-256", func(t *testing.T) {
400 ensureServiceIndicator(t)
401 h := sha3.NewShake256()
402 h.Write(plaintext)
403 out := make([]byte, 16)
404 h.Read(out)
405 t.Logf("SHAKE-256 output: %x", out)
406 })
407
408 t.Run("cSHAKE-128", func(t *testing.T) {
409 ensureServiceIndicator(t)
410 h := sha3.NewCShake128(nil, []byte("test"))
411 h.Write(plaintext)
412 out := make([]byte, 16)
413 h.Read(out)
414 t.Logf("cSHAKE-128 output: %x", out)
415 })
416
417 t.Run("cSHAKE-256", func(t *testing.T) {
418 ensureServiceIndicator(t)
419 h := sha3.NewCShake256(nil, []byte("test"))
420 h.Write(plaintext)
421 out := make([]byte, 16)
422 h.Read(out)
423 t.Logf("cSHAKE-256 output: %x", out)
424 })
425
426 t.Run("Keccak-256 [NOT APPROVED]", func(t *testing.T) {
427 cryptotest.MustMinimumFIPS140ModuleVersion(t, "v1.28.0")
428 ensureServiceIndicatorFalse(t)
429 h := sha3.NewLegacyKeccak256()
430 h.Write(plaintext)
431 out := h.Sum(nil)
432 t.Logf("Keccak-256 output: %x", out)
433 })
434
435 t.Run("KDA HKDF", func(t *testing.T) {
436 ensureServiceIndicator(t)
437 key := hkdf.Key(sha256.New, plaintextSHA256, []byte("salt"), "info", 16)
438 t.Logf("HKDF key: %x", key)
439 })
440
441 t.Run("KDA OneStepNoCounter", func(t *testing.T) {
442 ensureServiceIndicator(t)
443 key := hkdf.Extract(sha256.New, plaintextSHA256, []byte("salt"))
444 t.Logf("KDA OneStepNoCounter key: %x", key)
445 })
446
447 t.Run("Feedback KDF", func(t *testing.T) {
448 ensureServiceIndicator(t)
449 key := hkdf.Expand(sha256.New, plaintextSHA256, "info", 16)
450 t.Logf("Feedback KDF key: %x", key)
451 })
452
453 t.Run("PBKDF", func(t *testing.T) {
454 ensureServiceIndicator(t)
455 key, err := pbkdf2.Key(sha256.New, "password", plaintextSHA256, 2, 16)
456 fatalIfErr(t, err)
457 t.Logf("PBKDF key: %x", key)
458 })
459
460 t.Run("KDF TLS v1.2 CVL", func(t *testing.T) {
461 ensureServiceIndicator(t)
462 key := tls12.MasterSecret(sha256.New, plaintextSHA256, []byte("test"))
463 t.Logf("TLS v1.2 CVL Master Secret: %x", key)
464 })
465
466 t.Run("KDF TLS v1.2 CVL SHA-384", func(t *testing.T) {
467 cryptotest.MustMinimumFIPS140ModuleVersion(t, "v1.28.0")
468 ensureServiceIndicator(t)
469 key := tls12.MasterSecret(sha512.New384, plaintextSHA384, []byte("test"))
470 t.Logf("TLS v1.2 CVL SHA-384 Master Secret: %x", key)
471 })
472
473 t.Run("KDF TLS v1.3 CVL", func(t *testing.T) {
474 ensureServiceIndicator(t)
475 es := tls13.NewEarlySecret(sha256.New, plaintextSHA256)
476 hs := es.HandshakeSecret(plaintextSHA256)
477 ms := hs.MasterSecret()
478 client := ms.ClientApplicationTrafficSecret(sha256.New())
479 server := ms.ServerApplicationTrafficSecret(sha256.New())
480 t.Logf("TLS v1.3 CVL Application Traffic Secrets: client %x, server %x", client, server)
481 })
482 }
483
484 func ensureServiceIndicator(t *testing.T) {
485 fips140.ResetServiceIndicator()
486 t.Cleanup(func() {
487 if fips140.ServiceIndicator() {
488 t.Logf("Service indicator is set")
489 } else {
490 t.Errorf("Service indicator is not set")
491 }
492 })
493 }
494
495 func ensureServiceIndicatorFalse(t *testing.T) {
496 fips140.ResetServiceIndicator()
497 t.Cleanup(func() {
498 if !fips140.ServiceIndicator() {
499 t.Logf("Service indicator is not set")
500 } else {
501 t.Errorf("Service indicator is set")
502 }
503 })
504 }
505
506 func fatalIfErr(t *testing.T, err error) {
507 t.Helper()
508 if err != nil {
509 t.Fatal(err)
510 }
511 }
512
513 func decodeHex(t *testing.T, s string) []byte {
514 t.Helper()
515 s = strings.ReplaceAll(s, " ", "")
516 b, err := hex.DecodeString(s)
517 if err != nil {
518 t.Fatal(err)
519 }
520 return b
521 }
522
View as plain text