package gcm
import (
"crypto/internal/fips140"
"crypto/internal/fips140/aes"
"crypto/internal/fips140/alias"
"crypto/internal/fips140/drbg"
"crypto/internal/fips140deps/byteorder"
"math"
)
func SealWithRandomNonce (g *GCM , nonce , out , plaintext , additionalData []byte ) {
if uint64 (len (plaintext )) > uint64 ((1 <<32 )-2 )*gcmBlockSize {
panic ("crypto/cipher: message too large for GCM" )
}
if len (nonce ) != gcmStandardNonceSize {
panic ("crypto/cipher: incorrect nonce length given to GCMWithRandomNonce" )
}
if len (out ) != len (plaintext )+gcmTagSize {
panic ("crypto/cipher: incorrect output length given to GCMWithRandomNonce" )
}
if alias .InexactOverlap (out , plaintext ) {
panic ("crypto/cipher: invalid buffer overlap of output and input" )
}
if alias .AnyOverlap (out , additionalData ) {
panic ("crypto/cipher: invalid buffer overlap of output and additional data" )
}
fips140 .RecordApproved ()
drbg .Read (nonce )
seal (out , g , nonce , plaintext , additionalData )
}
func NewGCMWithCounterNonce (cipher *aes .Block ) (*GCMWithCounterNonce , error ) {
g , err := newGCM (&GCM {}, cipher , gcmStandardNonceSize , gcmTagSize )
if err != nil {
return nil , err
}
return &GCMWithCounterNonce {g : *g }, nil
}
type GCMWithCounterNonce struct {
g GCM
ready bool
fixedName uint32
start uint64
next uint64
}
func (g *GCMWithCounterNonce ) NonceSize () int { return gcmStandardNonceSize }
func (g *GCMWithCounterNonce ) Overhead () int { return gcmTagSize }
func (g *GCMWithCounterNonce ) 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 {
g .ready = true
g .start = counter
g .fixedName = byteorder .BEUint32 (nonce [:4 ])
}
if g .fixedName != byteorder .BEUint32 (nonce [:4 ]) {
panic ("crypto/cipher: incorrect module name given to GCMWithCounterNonce" )
}
counter -= g .start
if counter == math .MaxUint64 {
panic ("crypto/cipher: counter wrapped" )
}
if counter < g .next {
panic ("crypto/cipher: counter decreased" )
}
g .next = counter + 1
fips140 .RecordApproved ()
return g .g .sealAfterIndicator (dst , nonce , plaintext , data )
}
func (g *GCMWithCounterNonce ) Open (dst , nonce , ciphertext , data []byte ) ([]byte , error ) {
fips140 .RecordApproved ()
return g .g .Open (dst , nonce , ciphertext , data )
}
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 :])
if counter == math .MaxUint64 {
panic ("crypto/cipher: counter wrapped" )
}
if counter < g .next {
panic ("crypto/cipher: counter decreased" )
}
g .next = counter + 1
fips140 .RecordApproved ()
return g .g .sealAfterIndicator (dst , nonce , plaintext , data )
}
func (g *GCMForTLS12 ) Open (dst , nonce , ciphertext , data []byte ) ([]byte , error ) {
fips140 .RecordApproved ()
return g .g .Open (dst , nonce , ciphertext , data )
}
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 {
g .ready = true
g .mask = counter
}
counter ^= g .mask
if counter == math .MaxUint64 {
panic ("crypto/cipher: counter wrapped" )
}
if counter < g .next {
panic ("crypto/cipher: counter decreased" )
}
g .next = counter + 1
fips140 .RecordApproved ()
return g .g .sealAfterIndicator (dst , nonce , plaintext , data )
}
func (g *GCMForTLS13 ) Open (dst , nonce , ciphertext , data []byte ) ([]byte , error ) {
fips140 .RecordApproved ()
return g .g .Open (dst , nonce , ciphertext , data )
}
func NewGCMForSSH (cipher *aes .Block ) (*GCMForSSH , error ) {
g , err := newGCM (&GCM {}, cipher , gcmStandardNonceSize , gcmTagSize )
if err != nil {
return nil , err
}
return &GCMForSSH {g : *g }, nil
}
type GCMForSSH struct {
g GCM
ready bool
start uint64
next uint64
}
func (g *GCMForSSH ) NonceSize () int { return gcmStandardNonceSize }
func (g *GCMForSSH ) Overhead () int { return gcmTagSize }
func (g *GCMForSSH ) 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 {
g .ready = true
g .start = counter
}
counter -= g .start
if counter == math .MaxUint64 {
panic ("crypto/cipher: counter wrapped" )
}
if counter < g .next {
panic ("crypto/cipher: counter decreased" )
}
g .next = counter + 1
fips140 .RecordApproved ()
return g .g .sealAfterIndicator (dst , nonce , plaintext , data )
}
func (g *GCMForSSH ) Open (dst , nonce , ciphertext , data []byte ) ([]byte , error ) {
fips140 .RecordApproved ()
return g .g .Open (dst , nonce , ciphertext , data )
}
The pages are generated with Golds v0.7.3-preview . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .