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