package gcm
import (
)
type CMAC struct {
b aes.Block
k1 [aes.BlockSize]byte
k2 [aes.BlockSize]byte
}
func ( *aes.Block) *CMAC {
:= &CMAC{b: *}
.deriveSubkeys()
return
}
func ( *CMAC) () {
aes.EncryptBlockInternal(&.b, .k1[:], .k1[:])
:= shiftLeft(&.k1)
.k1[len(.k1)-1] ^= * 0b10000111
.k2 = .k1
= shiftLeft(&.k2)
.k2[len(.k2)-1] ^= * 0b10000111
}
func ( *CMAC) ( []byte) [aes.BlockSize]byte {
fips140.RecordApproved()
_ = .b
var [aes.BlockSize]byte
if len() == 0 {
= .k2
[len()] ^= 0b10000000
aes.EncryptBlockInternal(&.b, [:], [:])
return
}
for len() >= aes.BlockSize {
subtle.XORBytes([:], [:aes.BlockSize], [:])
if len() == aes.BlockSize {
subtle.XORBytes([:], .k1[:], [:])
}
aes.EncryptBlockInternal(&.b, [:], [:])
= [aes.BlockSize:]
}
if len() > 0 {
subtle.XORBytes([:], , [:])
subtle.XORBytes([:], .k2[:], [:])
[len()] ^= 0b10000000
aes.EncryptBlockInternal(&.b, [:], [:])
}
return
}
func ( *[aes.BlockSize]byte) byte {
var byte
for := len() - 1; >= 0; -- {
, [] = []>>7, []<<1|
}
return
}