mirror of
https://github.com/golang/go
synced 2024-11-22 15:04:52 -07:00
crypto/internal/fips/aes/gcm: add GCMForTLS12 and GCMForTLS13
For #69536 Change-Id: I2d7b6e7b9932d0f0f582a5ab0bb871395dc2a1e8 Reviewed-on: https://go-review.googlesource.com/c/go/+/626675 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Daniel McCarney <daniel@binaryparadox.net> Reviewed-by: Roland Shoemaker <roland@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Auto-Submit: Filippo Valsorda <filippo@golang.org>
This commit is contained in:
parent
b86f770bec
commit
79c0041daf
@ -5,8 +5,11 @@
|
|||||||
package gcm
|
package gcm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/internal/fips/aes"
|
||||||
"crypto/internal/fips/alias"
|
"crypto/internal/fips/alias"
|
||||||
"crypto/internal/fips/drbg"
|
"crypto/internal/fips/drbg"
|
||||||
|
"internal/byteorder"
|
||||||
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SealWithRandomNonce encrypts plaintext to out, and writes a random nonce to
|
// SealWithRandomNonce encrypts plaintext to out, and writes a random nonce to
|
||||||
@ -36,3 +39,98 @@ func SealWithRandomNonce(g *GCM, nonce, out, plaintext, additionalData []byte) {
|
|||||||
drbg.Read(nonce)
|
drbg.Read(nonce)
|
||||||
seal(out, g, nonce, plaintext, additionalData)
|
seal(out, g, nonce, plaintext, additionalData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewGCMForTLS12 returns a new AEAD that works like GCM, but enforces the
|
||||||
|
// construction of nonces as specified in RFC 5288, Section 3 and RFC 9325,
|
||||||
|
// Section 7.2.1.
|
||||||
|
//
|
||||||
|
// This complies with FIPS 140-3 IG C.H Resolution 1.a.
|
||||||
|
func NewGCMForTLS12(cipher *aes.Block) (*GCMForTLS12, error) {
|
||||||
|
g, err := newGCM(&GCM{}, cipher, gcmStandardNonceSize, gcmTagSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &GCMForTLS12{g: *g}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type GCMForTLS12 struct {
|
||||||
|
g GCM
|
||||||
|
next uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GCMForTLS12) NonceSize() int { return gcmStandardNonceSize }
|
||||||
|
|
||||||
|
func (g *GCMForTLS12) Overhead() int { return gcmTagSize }
|
||||||
|
|
||||||
|
func (g *GCMForTLS12) Seal(dst, nonce, plaintext, data []byte) []byte {
|
||||||
|
if len(nonce) != gcmStandardNonceSize {
|
||||||
|
panic("crypto/cipher: incorrect nonce length given to GCM")
|
||||||
|
}
|
||||||
|
|
||||||
|
counter := byteorder.BeUint64(nonce[len(nonce)-8:])
|
||||||
|
|
||||||
|
// Ensure the counter is monotonically increasing.
|
||||||
|
if counter == math.MaxUint64 {
|
||||||
|
panic("crypto/cipher: counter wrapped")
|
||||||
|
}
|
||||||
|
if counter < g.next {
|
||||||
|
panic("crypto/cipher: counter decreased")
|
||||||
|
}
|
||||||
|
g.next = counter + 1
|
||||||
|
|
||||||
|
return g.g.Seal(dst, nonce, plaintext, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GCMForTLS12) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
|
||||||
|
return g.g.Open(dst, nonce, ciphertext, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGCMForTLS13 returns a new AEAD that works like GCM, but enforces the
|
||||||
|
// construction of nonces as specified in RFC 8446, Section 5.3.
|
||||||
|
func NewGCMForTLS13(cipher *aes.Block) (*GCMForTLS13, error) {
|
||||||
|
g, err := newGCM(&GCM{}, cipher, gcmStandardNonceSize, gcmTagSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &GCMForTLS13{g: *g}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type GCMForTLS13 struct {
|
||||||
|
g GCM
|
||||||
|
ready bool
|
||||||
|
mask uint64
|
||||||
|
next uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GCMForTLS13) NonceSize() int { return gcmStandardNonceSize }
|
||||||
|
|
||||||
|
func (g *GCMForTLS13) Overhead() int { return gcmTagSize }
|
||||||
|
|
||||||
|
func (g *GCMForTLS13) Seal(dst, nonce, plaintext, data []byte) []byte {
|
||||||
|
if len(nonce) != gcmStandardNonceSize {
|
||||||
|
panic("crypto/cipher: incorrect nonce length given to GCM")
|
||||||
|
}
|
||||||
|
|
||||||
|
counter := byteorder.BeUint64(nonce[len(nonce)-8:])
|
||||||
|
if !g.ready {
|
||||||
|
// In the first call, the counter is zero, so we learn the XOR mask.
|
||||||
|
g.ready = true
|
||||||
|
g.mask = counter
|
||||||
|
}
|
||||||
|
counter ^= g.mask
|
||||||
|
|
||||||
|
// Ensure the counter is monotonically increasing.
|
||||||
|
if counter == math.MaxUint64 {
|
||||||
|
panic("crypto/cipher: counter wrapped")
|
||||||
|
}
|
||||||
|
if counter < g.next {
|
||||||
|
panic("crypto/cipher: counter decreased")
|
||||||
|
}
|
||||||
|
g.next = counter + 1
|
||||||
|
|
||||||
|
return g.g.Seal(dst, nonce, plaintext, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GCMForTLS13) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
|
||||||
|
return g.g.Open(dst, nonce, ciphertext, data)
|
||||||
|
}
|
||||||
|
@ -11,6 +11,8 @@ import (
|
|||||||
"crypto/des"
|
"crypto/des"
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/internal/boring"
|
"crypto/internal/boring"
|
||||||
|
fipsaes "crypto/internal/fips/aes"
|
||||||
|
"crypto/internal/fips/aes/gcm"
|
||||||
"crypto/rc4"
|
"crypto/rc4"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
@ -521,7 +523,7 @@ func aeadAESGCM(key, noncePrefix []byte) aead {
|
|||||||
aead, err = boring.NewGCMTLS(aes)
|
aead, err = boring.NewGCMTLS(aes)
|
||||||
} else {
|
} else {
|
||||||
boring.Unreachable()
|
boring.Unreachable()
|
||||||
aead, err = cipher.NewGCM(aes)
|
aead, err = gcm.NewGCMForTLS12(aes.(*fipsaes.Block))
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -555,7 +557,7 @@ func aeadAESGCMTLS13(key, nonceMask []byte) aead {
|
|||||||
aead, err = boring.NewGCMTLS13(aes)
|
aead, err = boring.NewGCMTLS13(aes)
|
||||||
} else {
|
} else {
|
||||||
boring.Unreachable()
|
boring.Unreachable()
|
||||||
aead, err = cipher.NewGCM(aes)
|
aead, err = gcm.NewGCMForTLS13(aes.(*fipsaes.Block))
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
Loading…
Reference in New Issue
Block a user