import (
"crypto/cipher"
+ "crypto/internal/cryptotest"
"crypto/internal/fips140"
fipsaes "crypto/internal/fips140/aes"
"crypto/internal/fips140/aes/gcm"
"encoding/binary"
+ "internal/testenv"
"math"
"testing"
)
func TestGCMNoncesFIPSV2(t *testing.T) {
+ cryptotest.MustSupportFIPS140(t)
+ if !fips140.Enabled {
+ cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestGCMNoncesFIPSV2$", "-test.v")
+ cmd = testenv.CleanCmdEnv(cmd)
+ cmd.Env = append(cmd.Env, "GODEBUG=fips140=on")
+ out, err := cmd.CombinedOutput()
+ if len(out) != 0 {
+ t.Logf("\n%s", out)
+ }
+ if err != nil {
+ t.Errorf("fips140=on subprocess failed: %v", err)
+ }
+ return
+ }
+
tryNonce := func(aead cipher.AEAD, nonce []byte) bool {
fips140.ResetServiceIndicator()
aead.Seal(nil, nonce, []byte("x"), nil)
"encoding/hex"
"errors"
"fmt"
+ "internal/testenv"
"io"
"reflect"
"testing"
})
}
-func TestGCMNonces(t *testing.T) {
+func TestGCMNoncesFIPSV1(t *testing.T) {
+ cryptotest.MustSupportFIPS140(t)
+ if !fips140.Enabled {
+ cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestGCMNoncesFIPSV1$", "-test.v")
+ cmd = testenv.CleanCmdEnv(cmd)
+ cmd.Env = append(cmd.Env, "GODEBUG=fips140=on")
+ out, err := cmd.CombinedOutput()
+ if len(out) != 0 {
+ t.Logf("\n%s", out)
+ }
+ if err != nil {
+ t.Errorf("fips140=on subprocess failed: %v", err)
+ }
+ return
+ }
+
tryNonce := func(aead cipher.AEAD, nonce []byte) bool {
fips140.ResetServiceIndicator()
aead.Seal(nil, nonce, []byte("x"), nil)
panic("crypto/cipher: incorrect nonce length given to GCM")
}
- if !g.prefixReady {
- // The first invocation sets the fixed prefix.
- g.prefixReady = true
- g.prefix = byteorder.BEUint32(nonce[:4])
- }
- if g.prefix != byteorder.BEUint32(nonce[:4]) {
- panic("crypto/cipher: GCM nonce prefix changed")
- }
+ if fips140.Enabled {
+ if !g.prefixReady {
+ // The first invocation sets the fixed prefix.
+ g.prefixReady = true
+ g.prefix = byteorder.BEUint32(nonce[:4])
+ }
+ if g.prefix != byteorder.BEUint32(nonce[:4]) {
+ panic("crypto/cipher: GCM nonce prefix changed")
+ }
- counter := byteorder.BEUint64(nonce[len(nonce)-8:])
- if !g.startReady {
- // The first invocation sets the starting counter, if not fixed.
- g.startReady = true
- g.start = counter
- }
- counter -= g.start
+ counter := byteorder.BEUint64(nonce[len(nonce)-8:])
+ if !g.startReady {
+ // The first invocation sets the starting counter, if not fixed.
+ g.startReady = true
+ g.start = counter
+ }
+ counter -= g.start
- // Ensure the counter is strictly increasing.
- if counter == math.MaxUint64 {
- panic("crypto/cipher: counter exhausted")
- }
- if counter < g.next {
- panic("crypto/cipher: counter decreased or remained the same")
+ // Ensure the counter is strictly increasing.
+ if counter == math.MaxUint64 {
+ panic("crypto/cipher: counter exhausted")
+ }
+ if counter < g.next {
+ panic("crypto/cipher: counter decreased or remained the same")
+ }
+ g.next = counter + 1
}
- g.next = counter + 1
fips140.RecordApproved()
return g.g.sealAfterIndicator(dst, nonce, plaintext, data)
panic("crypto/cipher: incorrect nonce length given to GCM")
}
- counter := byteorder.BEUint64(nonce[len(nonce)-8:])
- if !g.ready {
- // In the first call, if [GCMWithXORCounterNonce.SetNoncePrefixAndMask]
- // wasn't used, we assume the counter is zero to learn the XOR mask and
- // fixed prefix.
- g.ready = true
- g.mask = counter
- g.prefix = byteorder.BEUint32(nonce[:4])
- }
- if g.prefix != byteorder.BEUint32(nonce[:4]) {
- panic("crypto/cipher: GCM nonce prefix changed")
- }
- counter ^= g.mask
+ if fips140.Enabled {
+ counter := byteorder.BEUint64(nonce[len(nonce)-8:])
+ if !g.ready {
+ // In the first call, if [GCMWithXORCounterNonce.SetNoncePrefixAndMask]
+ // wasn't used, we assume the counter is zero to learn the XOR mask and
+ // fixed prefix.
+ g.ready = true
+ g.mask = counter
+ g.prefix = byteorder.BEUint32(nonce[:4])
+ }
+ if g.prefix != byteorder.BEUint32(nonce[:4]) {
+ panic("crypto/cipher: GCM nonce prefix changed")
+ }
+ counter ^= g.mask
- // Ensure the counter is strictly increasing.
- if counter == math.MaxUint64 {
- panic("crypto/cipher: counter exhausted")
- }
- if counter < g.next {
- panic("crypto/cipher: counter decreased or remained the same")
+ // Ensure the counter is strictly increasing.
+ if counter == math.MaxUint64 {
+ panic("crypto/cipher: counter exhausted")
+ }
+ if counter < g.next {
+ panic("crypto/cipher: counter decreased or remained the same")
+ }
+ g.next = counter + 1
}
- g.next = counter + 1
fips140.RecordApproved()
return g.g.sealAfterIndicator(dst, nonce, plaintext, data)