package gcm
import (
)
func ( *[256]byte, []uint32)
func ( *[256]byte, []byte, *[16]byte)
func ( *[256]byte, , []byte, , *[16]byte, []uint32)
func ( *[256]byte, , []byte, , *[16]byte, []uint32)
func ( *[256]byte, , *[16]byte, , uint64)
var supportsAESGCM = cpu.X86HasAES && cpu.X86HasPCLMULQDQ && cpu.X86HasSSE41 && cpu.X86HasSSSE3 ||
cpu.ARM64HasAES && cpu.ARM64HasPMULL
func () {
if cpu.AMD64 {
impl.Register("gcm", "AES-NI", &supportsAESGCM)
}
if cpu.ARM64 {
impl.Register("gcm", "Armv8.0", &supportsAESGCM)
}
}
func () {
if supportsAESGCM {
panic("gcm: internal error: using generic implementation despite hardware support")
}
}
type gcmPlatformData struct {
productTable [256]byte
}
func ( *GCM) {
if !supportsAESGCM {
return
}
gcmAesInit(&.productTable, aes.EncryptionKeySchedule(&.cipher))
}
func ( []byte, *GCM, , , []byte) {
if !supportsAESGCM {
sealGeneric(, , , , )
return
}
var , [gcmBlockSize]byte
if len() == gcmStandardNonceSize {
copy([:], )
[gcmBlockSize-1] = 1
} else {
gcmAesData(&.productTable, , &)
gcmAesFinish(&.productTable, &, &, uint64(len()), uint64(0))
}
aes.EncryptBlockInternal(&.cipher, [:], [:])
var [gcmTagSize]byte
gcmAesData(&.productTable, , &)
if len() > 0 {
gcmAesEnc(&.productTable, , , &, &, aes.EncryptionKeySchedule(&.cipher))
}
gcmAesFinish(&.productTable, &, &, uint64(len()), uint64(len()))
copy([len():], [:])
}
func ( []byte, *GCM, , , []byte) error {
if !supportsAESGCM {
return openGeneric(, , , , )
}
:= [len()-.tagSize:]
= [:len()-.tagSize]
var , [gcmBlockSize]byte
if len() == gcmStandardNonceSize {
copy([:], )
[gcmBlockSize-1] = 1
} else {
gcmAesData(&.productTable, , &)
gcmAesFinish(&.productTable, &, &, uint64(len()), uint64(0))
}
aes.EncryptBlockInternal(&.cipher, [:], [:])
var [gcmTagSize]byte
gcmAesData(&.productTable, , &)
if len() > 0 {
gcmAesDec(&.productTable, , , &, &, aes.EncryptionKeySchedule(&.cipher))
}
gcmAesFinish(&.productTable, &, &, uint64(len()), uint64(len()))
if subtle.ConstantTimeCompare([:.tagSize], ) != 1 {
return errOpen
}
return nil
}