forked from secure-io/siv-go
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathaes_cmac.go
52 lines (44 loc) · 1.56 KB
/
aes_cmac.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// Copyright (c) 2018 Andreas Auernhammer. All rights reserved.
// Use of this source code is governed by a license that can be
// found in the LICENSE file.
package siv
import (
"crypto/aes"
"crypto/cipher"
)
// NewCMAC returns a cipher.AEAD implementing AES-SIV-CMAC
// as specified in RFC 5297. The key must be twice as large
// as an AES key - so either 32, 48 or 64 bytes long.
//
// The returned cipher.AEAD accepts an empty or NonceSize()
// bytes long nonce.
func NewCMAC(key []byte) (cipher.AEAD, error) {
if k := len(key); k != 32 && k != 48 && k != 64 {
return nil, aes.KeySizeError(k)
}
return &aesSivCMac{newCMAC(key)}, nil
}
type aesSivCMac struct{ aead }
func (c *aesSivCMac) NonceSize() int { return aes.BlockSize }
func (c *aesSivCMac) Overhead() int { return aes.BlockSize }
func (c *aesSivCMac) Seal(dst, nonce, plaintext, additionalData []byte) []byte {
if n := len(nonce); n != 0 && n != c.NonceSize() {
panic("siv: incorrect nonce length given to AES-SIV-CMAC")
}
ret, ciphertext := sliceForAppend(dst, c.Overhead()+len(plaintext))
c.seal(ciphertext, nonce, plaintext, additionalData)
return ret
}
func (c *aesSivCMac) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
if n := len(nonce); n != 0 && n != c.NonceSize() {
panic("siv: incorrect nonce length given to AES-SIV-CMAC")
}
if len(ciphertext) < c.Overhead() {
return dst, errOpen
}
ret, plaintext := sliceForAppend(dst, len(ciphertext)-c.Overhead())
if err := c.open(plaintext, nonce, ciphertext, additionalData); err != nil {
return ret, err
}
return ret, nil
}