package gcm
import (
"crypto/internal/fips140/aes"
"crypto/internal/fips140/subtle"
"crypto/internal/fips140deps/byteorder"
)
func sealGeneric(out []byte , g *GCM , nonce , plaintext , additionalData []byte ) {
var H , counter , tagMask [gcmBlockSize ]byte
g .cipher .Encrypt (H [:], H [:])
deriveCounterGeneric (&H , &counter , nonce )
gcmCounterCryptGeneric (&g .cipher , tagMask [:], tagMask [:], &counter )
gcmCounterCryptGeneric (&g .cipher , out , plaintext , &counter )
var tag [gcmTagSize ]byte
gcmAuthGeneric (tag [:], &H , &tagMask , out [:len (plaintext )], additionalData )
copy (out [len (plaintext ):], tag [:])
}
func openGeneric(out []byte , g *GCM , nonce , ciphertext , additionalData []byte ) error {
var H , counter , tagMask [gcmBlockSize ]byte
g .cipher .Encrypt (H [:], H [:])
deriveCounterGeneric (&H , &counter , nonce )
gcmCounterCryptGeneric (&g .cipher , tagMask [:], tagMask [:], &counter )
tag := ciphertext [len (ciphertext )-g .tagSize :]
ciphertext = ciphertext [:len (ciphertext )-g .tagSize ]
var expectedTag [gcmTagSize ]byte
gcmAuthGeneric (expectedTag [:], &H , &tagMask , ciphertext , additionalData )
if subtle .ConstantTimeCompare (expectedTag [:g .tagSize ], tag ) != 1 {
return errOpen
}
gcmCounterCryptGeneric (&g .cipher , out , ciphertext , &counter )
return nil
}
func deriveCounterGeneric(H , counter *[gcmBlockSize ]byte , nonce []byte ) {
if len (nonce ) == gcmStandardNonceSize {
copy (counter [:], nonce )
counter [gcmBlockSize -1 ] = 1
} else {
lenBlock := make ([]byte , 16 )
byteorder .BEPutUint64 (lenBlock [8 :], uint64 (len (nonce ))*8 )
ghash (counter , H , nonce , lenBlock )
}
}
func gcmCounterCryptGeneric(b *aes .Block , out , src []byte , counter *[gcmBlockSize ]byte ) {
var mask [gcmBlockSize ]byte
for len (src ) >= gcmBlockSize {
b .Encrypt (mask [:], counter [:])
gcmInc32 (counter )
subtle .XORBytes (out , src , mask [:])
out = out [gcmBlockSize :]
src = src [gcmBlockSize :]
}
if len (src ) > 0 {
b .Encrypt (mask [:], counter [:])
gcmInc32 (counter )
subtle .XORBytes (out , src , mask [:])
}
}
func gcmInc32(counterBlock *[gcmBlockSize ]byte ) {
ctr := counterBlock [len (counterBlock )-4 :]
byteorder .BEPutUint32 (ctr , byteorder .BEUint32 (ctr )+1 )
}
func gcmAuthGeneric(out []byte , H , tagMask *[gcmBlockSize ]byte , ciphertext , additionalData []byte ) {
checkGenericIsExpected ()
lenBlock := make ([]byte , 16 )
byteorder .BEPutUint64 (lenBlock [:8 ], uint64 (len (additionalData ))*8 )
byteorder .BEPutUint64 (lenBlock [8 :], uint64 (len (ciphertext ))*8 )
var S [gcmBlockSize ]byte
ghash (&S , H , additionalData , ciphertext , lenBlock )
subtle .XORBytes (out , S [:], tagMask [:])
}
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 .