"crypto/hmac"
"encoding/binary"
"errors"
+ "fmt"
)
+var InvalidTag = errors.New("gogost/mgm: invalid authentication tag")
+
type Mul interface {
Mul(x, y []byte) []byte
}
func NewMGM(cipher cipher.Block, tagSize int) (cipher.AEAD, error) {
blockSize := cipher.BlockSize()
if !(blockSize == 8 || blockSize == 16) {
- return nil, errors.New("gogost/mgm: only 64/128 blocksizes allowed")
+ return nil, errors.New("gogost/mgm: only {64|128} blocksizes allowed")
}
if tagSize < 4 || tagSize > blockSize {
- return nil, errors.New("gogost/mgm: invalid tag size")
+ return nil, fmt.Errorf("gogost/mgm: invalid tag size (4<=%d<=%d)", tagSize, blockSize)
}
mgm := MGM{
MaxSize: uint64(1<<uint(blockSize*8/2) - 1),
return ret
}
+// Open the authenticated ciphertext. If authentication tag is invalid,
+// then InvalidTag error is returned.
func (mgm *MGM) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
mgm.validateNonce(nonce)
mgm.validateSizes(ciphertext, additionalData)
if len(ciphertext) < mgm.TagSize {
- return nil, errors.New("ciphertext is too short")
+ return nil, fmt.Errorf("ciphertext is too short (%d<%d)", len(ciphertext), mgm.TagSize)
}
if uint64(len(ciphertext)-mgm.TagSize) > mgm.MaxSize {
panic("ciphertext is too big")
copy(mgm.icn, nonce)
mgm.auth(mgm.sum, ct, additionalData)
if !hmac.Equal(mgm.sum[:mgm.TagSize], ciphertext[len(ciphertext)-mgm.TagSize:]) {
- return nil, errors.New("gogost/mgm: invalid authentication tag")
+ return nil, InvalidTag
}
mgm.crypt(out, ct)
return ret, nil