1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // CMAC message authentication code, defined in
6 // NIST Special Publication SP 800-38B.
16 // minimal irreducible polynomial of degree b
22 k1
, k2
, ci
, digest
[]byte
23 p
int // position in ci
27 // TODO(rsc): Should this return an error instead of panic?
29 // NewCMAC returns a new instance of a CMAC message authentication code
30 // digest using the given Cipher.
31 func NewCMAC(c Cipher
) hash
.Hash
{
40 panic("crypto/block: NewCMAC: invalid cipher block size")
45 d
.k1
= make([]byte, n
)
46 d
.k2
= make([]byte, n
)
47 d
.ci
= make([]byte, n
)
48 d
.digest
= make([]byte, n
)
50 // Subkey generation, p. 7
52 if shift1(d
.k1
, d
.k1
) != 0 {
55 if shift1(d
.k2
, d
.k1
) != 0 {
62 // Reset clears the digest state, starting a new digest.
63 func (d
*cmac
) Reset() {
70 // Write adds the given data to the digest state.
71 func (d
*cmac
) Write(p
[]byte) (n
int, err os
.Error
) {
74 // If ci is full, encrypt and start over.
76 d
.c
.Encrypt(d
.ci
, d
.ci
)
85 // Sum returns the CMAC digest, one cipher block in length,
86 // of the data written with Write.
87 func (d
*cmac
) Sum() []byte {
88 // Finish last block, mix in key, encrypt.
89 // Don't edit ci, in case caller wants
90 // to keep digesting after call to Sum.
92 if d
.p
< len(d
.digest
) {
95 for i
:= 0; i
< len(d
.ci
); i
++ {
96 d
.digest
[i
] = d
.ci
[i
] ^ k
[i
]
98 if d
.p
< len(d
.digest
) {
101 d
.c
.Encrypt(d
.digest
, d
.digest
)
105 func (d
*cmac
) Size() int { return len(d
.digest
) }