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 // Cipher block chaining (CBC) mode.
7 // CBC provides confidentiality by xoring (chaining) each plaintext block
8 // with the previous ciphertext block before applying the block cipher.
10 // See NIST SP 800-38A, pp 10-11
21 func newCBC(b Block
, iv
[]byte) *cbc
{
24 blockSize
: b
.BlockSize(),
26 tmp
: make([]byte, b
.BlockSize()),
32 // NewCBCEncrypter returns a BlockMode which encrypts in cipher block chaining
33 // mode, using the given Block. The length of iv must be the same as the
34 // Block's block size.
35 func NewCBCEncrypter(b Block
, iv
[]byte) BlockMode
{
36 if len(iv
) != b
.BlockSize() {
37 panic("cipher.NewCBCEncrypter: IV length must equal block size")
39 return (*cbcEncrypter
)(newCBC(b
, iv
))
42 func (x
*cbcEncrypter
) BlockSize() int { return x
.blockSize
}
44 func (x
*cbcEncrypter
) CryptBlocks(dst
, src
[]byte) {
45 if len(src
)%x
.blockSize
!= 0 {
46 panic("crypto/cipher: input not full blocks")
48 if len(dst
) < len(src
) {
49 panic("crypto/cipher: output smaller than input")
52 xorBytes(x
.iv
, x
.iv
, src
[:x
.blockSize
])
53 x
.b
.Encrypt(x
.iv
, x
.iv
)
55 src
= src
[x
.blockSize
:]
56 dst
= dst
[x
.blockSize
:]
60 func (x
*cbcEncrypter
) SetIV(iv
[]byte) {
61 if len(iv
) != len(x
.iv
) {
62 panic("cipher: incorrect length IV")
69 // NewCBCDecrypter returns a BlockMode which decrypts in cipher block chaining
70 // mode, using the given Block. The length of iv must be the same as the
71 // Block's block size and must match the iv used to encrypt the data.
72 func NewCBCDecrypter(b Block
, iv
[]byte) BlockMode
{
73 if len(iv
) != b
.BlockSize() {
74 panic("cipher.NewCBCDecrypter: IV length must equal block size")
76 return (*cbcDecrypter
)(newCBC(b
, iv
))
79 func (x
*cbcDecrypter
) BlockSize() int { return x
.blockSize
}
81 func (x
*cbcDecrypter
) CryptBlocks(dst
, src
[]byte) {
82 if len(src
)%x
.blockSize
!= 0 {
83 panic("crypto/cipher: input not full blocks")
85 if len(dst
) < len(src
) {
86 panic("crypto/cipher: output smaller than input")
89 x
.b
.Decrypt(x
.tmp
, src
[:x
.blockSize
])
90 xorBytes(x
.tmp
, x
.tmp
, x
.iv
)
93 src
= src
[x
.blockSize
:]
94 dst
= dst
[x
.blockSize
:]
98 func (x
*cbcDecrypter
) SetIV(iv
[]byte) {
99 if len(iv
) != len(x
.iv
) {
100 panic("cipher: incorrect length IV")