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/fips140"
20 "crypto/internal/fips140/aes"
21 "crypto/internal/fips140/aes/gcm"
22 "crypto/internal/fips140/check"
23 "crypto/internal/fips140/drbg"
24 "crypto/internal/fips140/ecdh"
25 "crypto/internal/fips140/ecdsa"
26 "crypto/internal/fips140/ed25519"
27 "crypto/internal/fips140/hkdf"
28 "crypto/internal/fips140/hmac"
29 "crypto/internal/fips140/mlkem"
30 "crypto/internal/fips140/pbkdf2"
31 "crypto/internal/fips140/rsa"
32 "crypto/internal/fips140/sha256"
33 "crypto/internal/fips140/sha3"
34 "crypto/internal/fips140/sha512"
35 "crypto/internal/fips140/tls12"
36 "crypto/internal/fips140/tls13"
37 "crypto/rand"
38 "encoding/hex"
39 "runtime"
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 t.Logf("GOOS/GOARCH: %s/%s", runtime.GOOS, runtime.GOARCH)
55
56 if noPAAPAI {
57 t.Log("PAA/PAI disabled")
58 } else {
59 t.Log("PAA/PAI enabled")
60 }
61
62 if check.Verified {
63 t.Log("FIPS 140-3 integrity self-check succeeded")
64 } else {
65 t.Log("FIPS 140-3 integrity self-check not succeeded")
66 }
67 }
68
69 func TestVersion(t *testing.T) {
70 bi, ok := debug.ReadBuildInfo()
71 if !ok {
72 t.Skip("no build info")
73 }
74 for _, setting := range bi.Settings {
75 if setting.Key != "GOFIPS140" {
76 continue
77 }
78 exp := setting.Value
79
80
81 exp, _, _ = strings.Cut(exp, "-")
82 if v := fips140.Version(); v != exp {
83 t.Errorf("Version is %q, expected %q", v, exp)
84 }
85 return
86 }
87
88 if v := fips140.Version(); v != "latest" {
89 t.Errorf("Version is %q, expected latest", v)
90 }
91 }
92
93 func TestFIPS140(t *testing.T) {
94 moduleStatus(t)
95 if boring.Enabled {
96 t.Skip("Go+BoringCrypto shims prevent the service indicator from being set")
97 }
98
99 aesKey := make([]byte, 128/8)
100 aesIV := make([]byte, aes.BlockSize)
101 plaintext := []byte("Go Cryptographic Module TestFIPS140 plaintext...")
102 plaintextSHA256 := decodeHex(t, "06b2614e2ef315832b23f5d0ff70294d8ddd3889527dfbe75707fe41da929325")
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("ML-KEM KeyGen, Encap, Decap", func(t *testing.T) {
228 ensureServiceIndicator(t)
229 k, err := mlkem.GenerateKey768()
230 fatalIfErr(t, err)
231
232 ss, c := k.EncapsulationKey().Encapsulate()
233 t.Logf("ML-KEM encapsulation: %x", c)
234
235 ss2, err := k.Decapsulate(c)
236 fatalIfErr(t, err)
237 t.Logf("ML-KEM shared secret: %x", ss)
238 if !bytes.Equal(ss, ss2) {
239 t.Errorf("ML-KEM round trip failed")
240 }
241 })
242
243 var rsaKey *rsa.PrivateKey
244 t.Run("RSA KeyGen", func(t *testing.T) {
245 ensureServiceIndicator(t)
246 var err error
247 rsaKey, err = rsa.GenerateKey(rand.Reader, 2048)
248 fatalIfErr(t, err)
249 t.Log("RSA key generated")
250 })
251
252 t.Run("RSA SigGen, SigVer PKCS 1.5", func(t *testing.T) {
253 ensureServiceIndicator(t)
254 sig, err := rsa.SignPKCS1v15(rsaKey, "SHA-256", plaintextSHA256)
255 fatalIfErr(t, err)
256 t.Logf("RSA PKCS1v15 signature: %x", sig)
257
258 err = rsa.VerifyPKCS1v15(rsaKey.PublicKey(), "SHA-256", plaintextSHA256, sig)
259 fatalIfErr(t, err)
260 })
261
262 t.Run("RSA SigGen, SigVer PSS", func(t *testing.T) {
263 ensureServiceIndicator(t)
264 sig, err := rsa.SignPSS(rand.Reader, rsaKey, sha256.New(), plaintextSHA256, 16)
265 fatalIfErr(t, err)
266 t.Logf("RSA PSS signature: %x", sig)
267
268 err = rsa.VerifyPSS(rsaKey.PublicKey(), sha256.New(), plaintextSHA256, sig)
269 fatalIfErr(t, err)
270 })
271
272 t.Run("RSA KeyGen w/ small key [NOT APPROVED]", func(t *testing.T) {
273 ensureServiceIndicatorFalse(t)
274 _, err := rsa.GenerateKey(rand.Reader, 512)
275 fatalIfErr(t, err)
276 t.Log("RSA key generated")
277 })
278
279 t.Run("KTS IFC OAEP", func(t *testing.T) {
280 ensureServiceIndicator(t)
281 c, err := rsa.EncryptOAEP(sha256.New(), sha256.New(), rand.Reader, rsaKey.PublicKey(), plaintextSHA256, nil)
282 fatalIfErr(t, err)
283 t.Logf("RSA OAEP ciphertext: %x", c)
284
285 out, err := rsa.DecryptOAEP(sha256.New(), sha256.New(), rsaKey, c, nil)
286 fatalIfErr(t, err)
287 t.Logf("RSA OAEP decrypted plaintext: %x", out)
288 if !bytes.Equal(plaintextSHA256, out) {
289 t.Errorf("RSA OAEP round trip failed")
290 }
291 })
292
293 t.Run("SHA2-224", func(t *testing.T) {
294 ensureServiceIndicator(t)
295 h := sha256.New224()
296 h.Write(plaintext)
297 out := h.Sum(nil)
298 t.Logf("SHA2-224 output: %x", out)
299 })
300
301 t.Run("SHA2-256", func(t *testing.T) {
302 ensureServiceIndicator(t)
303 h := sha256.New()
304 h.Write(plaintext)
305 out := h.Sum(nil)
306 t.Logf("SHA2-256 output: %x", out)
307 })
308
309 t.Run("SHA2-384", func(t *testing.T) {
310 ensureServiceIndicator(t)
311 h := sha512.New384()
312 h.Write(plaintext)
313 out := h.Sum(nil)
314 t.Logf("SHA2-384 output: %x", out)
315 })
316
317 t.Run("SHA2-512", func(t *testing.T) {
318 ensureServiceIndicator(t)
319 h := sha512.New()
320 h.Write(plaintext)
321 out := h.Sum(nil)
322 t.Logf("SHA2-512 output: %x", out)
323 })
324
325 t.Run("SHA2-512/224", func(t *testing.T) {
326 ensureServiceIndicator(t)
327 h := sha512.New512_224()
328 h.Write(plaintext)
329 out := h.Sum(nil)
330 t.Logf("SHA2-512/224 output: %x", out)
331 })
332
333 t.Run("SHA2-512/256", func(t *testing.T) {
334 ensureServiceIndicator(t)
335 h := sha512.New512_256()
336 h.Write(plaintext)
337 out := h.Sum(nil)
338 t.Logf("SHA2-512/256 output: %x", out)
339 })
340
341 t.Run("SHA3-224", func(t *testing.T) {
342 ensureServiceIndicator(t)
343 h := sha3.New224()
344 h.Write(plaintext)
345 out := h.Sum(nil)
346 t.Logf("SHA3-224 output: %x", out)
347 })
348
349 t.Run("SHA3-256", func(t *testing.T) {
350 ensureServiceIndicator(t)
351 h := sha3.New256()
352 h.Write(plaintext)
353 out := h.Sum(nil)
354 t.Logf("SHA3-256 output: %x", out)
355 })
356
357 t.Run("SHA3-384", func(t *testing.T) {
358 ensureServiceIndicator(t)
359 h := sha3.New384()
360 h.Write(plaintext)
361 out := h.Sum(nil)
362 t.Logf("SHA3-384 output: %x", out)
363 })
364
365 t.Run("SHA3-512", func(t *testing.T) {
366 ensureServiceIndicator(t)
367 h := sha3.New512()
368 h.Write(plaintext)
369 out := h.Sum(nil)
370 t.Logf("SHA3-512 output: %x", out)
371 })
372
373 t.Run("SHAKE-128", func(t *testing.T) {
374 ensureServiceIndicator(t)
375 h := sha3.NewShake128()
376 h.Write(plaintext)
377 out := make([]byte, 16)
378 h.Read(out)
379 t.Logf("SHAKE-128 output: %x", out)
380 })
381
382 t.Run("SHAKE-256", func(t *testing.T) {
383 ensureServiceIndicator(t)
384 h := sha3.NewShake256()
385 h.Write(plaintext)
386 out := make([]byte, 16)
387 h.Read(out)
388 t.Logf("SHAKE-256 output: %x", out)
389 })
390
391 t.Run("cSHAKE-128", func(t *testing.T) {
392 ensureServiceIndicator(t)
393 h := sha3.NewCShake128(nil, []byte("test"))
394 h.Write(plaintext)
395 out := make([]byte, 16)
396 h.Read(out)
397 t.Logf("cSHAKE-128 output: %x", out)
398 })
399
400 t.Run("cSHAKE-256", func(t *testing.T) {
401 ensureServiceIndicator(t)
402 h := sha3.NewCShake256(nil, []byte("test"))
403 h.Write(plaintext)
404 out := make([]byte, 16)
405 h.Read(out)
406 t.Logf("cSHAKE-256 output: %x", out)
407 })
408
409 t.Run("KDA HKDF", func(t *testing.T) {
410 ensureServiceIndicator(t)
411 key := hkdf.Key(sha256.New, plaintextSHA256, []byte("salt"), "info", 16)
412 t.Logf("HKDF key: %x", key)
413 })
414
415 t.Run("KDA OneStepNoCounter", func(t *testing.T) {
416 ensureServiceIndicator(t)
417 key := hkdf.Extract(sha256.New, plaintextSHA256, []byte("salt"))
418 t.Logf("KDA OneStepNoCounter key: %x", key)
419 })
420
421 t.Run("Feedback KDF", func(t *testing.T) {
422 ensureServiceIndicator(t)
423 key := hkdf.Expand(sha256.New, plaintextSHA256, "info", 16)
424 t.Logf("Feedback KDF key: %x", key)
425 })
426
427 t.Run("PBKDF", func(t *testing.T) {
428 ensureServiceIndicator(t)
429 key, err := pbkdf2.Key(sha256.New, "password", plaintextSHA256, 2, 16)
430 fatalIfErr(t, err)
431 t.Logf("PBKDF key: %x", key)
432 })
433
434 t.Run("KDF TLS v1.2 CVL", func(t *testing.T) {
435 ensureServiceIndicator(t)
436 key := tls12.MasterSecret(sha256.New, plaintextSHA256, []byte("test"))
437 t.Logf("TLS v1.2 CVL Master Secret: %x", key)
438 })
439
440 t.Run("KDF TLS v1.3 CVL", func(t *testing.T) {
441 ensureServiceIndicator(t)
442 es := tls13.NewEarlySecret(sha256.New, plaintextSHA256)
443 hs := es.HandshakeSecret(plaintextSHA256)
444 ms := hs.MasterSecret()
445 client := ms.ClientApplicationTrafficSecret(sha256.New())
446 server := ms.ServerApplicationTrafficSecret(sha256.New())
447 t.Logf("TLS v1.3 CVL Application Traffic Secrets: client %x, server %x", client, server)
448 })
449 }
450
451 func ensureServiceIndicator(t *testing.T) {
452 fips140.ResetServiceIndicator()
453 t.Cleanup(func() {
454 if fips140.ServiceIndicator() {
455 t.Logf("Service indicator is set")
456 } else {
457 t.Errorf("Service indicator is not set")
458 }
459 })
460 }
461
462 func ensureServiceIndicatorFalse(t *testing.T) {
463 fips140.ResetServiceIndicator()
464 t.Cleanup(func() {
465 if !fips140.ServiceIndicator() {
466 t.Logf("Service indicator is not set")
467 } else {
468 t.Errorf("Service indicator is set")
469 }
470 })
471 }
472
473 func fatalIfErr(t *testing.T, err error) {
474 t.Helper()
475 if err != nil {
476 t.Fatal(err)
477 }
478 }
479
480 func decodeHex(t *testing.T, s string) []byte {
481 t.Helper()
482 s = strings.ReplaceAll(s, " ", "")
483 b, err := hex.DecodeString(s)
484 if err != nil {
485 t.Fatal(err)
486 }
487 return b
488 }
489
View as plain text