libgo: Merge from revision 18783:00cce3a34d7e of master library.
[official-gcc.git] / libgo / go / crypto / cipher / cbc.go
blob9a2aece0e1b5f33020295ad6c23d931ddbac9844
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
12 package cipher
14 type cbc struct {
15 b Block
16 blockSize int
17 iv []byte
18 tmp []byte
21 func newCBC(b Block, iv []byte) *cbc {
22 return &cbc{
23 b: b,
24 blockSize: b.BlockSize(),
25 iv: dup(iv),
26 tmp: make([]byte, b.BlockSize()),
30 type cbcEncrypter cbc
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")
51 for len(src) > 0 {
52 xorBytes(x.iv, x.iv, src[:x.blockSize])
53 x.b.Encrypt(x.iv, x.iv)
54 copy(dst, 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")
64 copy(x.iv, iv)
67 type cbcDecrypter cbc
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")
88 for len(src) > 0 {
89 x.b.Decrypt(x.tmp, src[:x.blockSize])
90 xorBytes(x.tmp, x.tmp, x.iv)
91 copy(x.iv, src)
92 copy(dst, x.tmp)
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")
102 copy(x.iv, iv)