package gcm
import (
"crypto/internal/fips140"
"crypto/internal/fips140/aes"
"crypto/internal/fips140/subtle"
)
type CMAC struct {
b aes .Block
k1 [aes .BlockSize ]byte
k2 [aes .BlockSize ]byte
}
func NewCMAC (b *aes .Block ) *CMAC {
c := &CMAC {b : *b }
c .deriveSubkeys ()
return c
}
func (c *CMAC ) deriveSubkeys () {
c .b .Encrypt (c .k1 [:], c .k1 [:])
msb := shiftLeft (&c .k1 )
c .k1 [len (c .k1 )-1 ] ^= msb * 0b10000111
c .k2 = c .k1
msb = shiftLeft (&c .k2 )
c .k2 [len (c .k2 )-1 ] ^= msb * 0b10000111
}
func (c *CMAC ) MAC (m []byte ) [aes .BlockSize ]byte {
fips140 .RecordApproved ()
_ = c .b
var x [aes .BlockSize ]byte
if len (m ) == 0 {
x = c .k2
x [len (m )] ^= 0b10000000
c .b .Encrypt (x [:], x [:])
return x
}
for len (m ) >= aes .BlockSize {
subtle .XORBytes (x [:], m [:aes .BlockSize ], x [:])
if len (m ) == aes .BlockSize {
subtle .XORBytes (x [:], c .k1 [:], x [:])
}
c .b .Encrypt (x [:], x [:])
m = m [aes .BlockSize :]
}
if len (m ) > 0 {
subtle .XORBytes (x [:], m , x [:])
subtle .XORBytes (x [:], c .k2 [:], x [:])
x [len (m )] ^= 0b10000000
c .b .Encrypt (x [:], x [:])
}
return x
}
func shiftLeft(x *[aes .BlockSize ]byte ) byte {
var msb byte
for i := len (x ) - 1 ; i >= 0 ; i -- {
msb , x [i ] = x [i ]>>7 , x [i ]<<1 |msb
}
return msb
}
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 .