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