LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Cipher block chaining (CBC) mode. | 5 // Cipher block chaining (CBC) mode. |
6 | 6 |
7 // CBC provides confidentiality by xoring (chaining) each plaintext block | 7 // CBC provides confidentiality by xoring (chaining) each plaintext block |
8 // with the previous ciphertext block before applying the block cipher. | 8 // with the previous ciphertext block before applying the block cipher. |
9 | 9 |
10 // See NIST SP 800-38A, pp 10-11 | 10 // See NIST SP 800-38A, pp 10-11 |
11 | 11 |
12 package cipher | 12 package cipher |
13 | 13 |
14 type cbc struct { | 14 type cbc struct { |
15 b Block | 15 b Block |
16 blockSize int | 16 blockSize int |
17 iv []byte | 17 iv []byte |
18 tmp []byte | 18 tmp []byte |
19 } | 19 } |
20 | 20 |
21 func newCBC(b Block, iv []byte) *cbc { | 21 func newCBC(b Block, iv []byte) *cbc { |
22 return &cbc{ | 22 return &cbc{ |
23 b: b, | 23 b: b, |
24 blockSize: b.BlockSize(), | 24 blockSize: b.BlockSize(), |
25 iv: dup(iv), | 25 iv: dup(iv), |
26 tmp: make([]byte, b.BlockSize()), | 26 tmp: make([]byte, b.BlockSize()), |
27 } | 27 } |
28 } | 28 } |
29 | 29 |
30 type CBCEncrypter cbc | 30 type cbcEncrypter cbc |
31 | 31 |
32 func NewCBCEncrypter(b Block, iv []byte) *CBCEncrypter { | 32 // NewCBCEncrypter returns a BlockMode which encrypts in cipher block chaining |
33 » return (*CBCEncrypter)(newCBC(b, iv)) | 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 » return (*cbcEncrypter)(newCBC(b, iv)) |
34 } | 37 } |
35 | 38 |
36 func (x *CBCEncrypter) BlockSize() int { return x.blockSize } | 39 func (x *cbcEncrypter) BlockSize() int { return x.blockSize } |
37 | 40 |
38 func (x *CBCEncrypter) CryptBlocks(dst, src []byte) { | 41 func (x *cbcEncrypter) CryptBlocks(dst, src []byte) { |
39 for len(src) > 0 { | 42 for len(src) > 0 { |
40 for i := 0; i < x.blockSize; i++ { | 43 for i := 0; i < x.blockSize; i++ { |
41 x.iv[i] ^= src[i] | 44 x.iv[i] ^= src[i] |
42 } | 45 } |
43 x.b.Encrypt(x.iv, x.iv) | 46 x.b.Encrypt(x.iv, x.iv) |
44 for i := 0; i < x.blockSize; i++ { | 47 for i := 0; i < x.blockSize; i++ { |
45 dst[i] = x.iv[i] | 48 dst[i] = x.iv[i] |
46 } | 49 } |
47 src = src[x.blockSize:] | 50 src = src[x.blockSize:] |
48 dst = dst[x.blockSize:] | 51 dst = dst[x.blockSize:] |
49 } | 52 } |
50 } | 53 } |
51 | 54 |
52 type CBCDecrypter cbc | 55 type cbcDecrypter cbc |
53 | 56 |
54 func NewCBCDecrypter(b Block, iv []byte) *CBCDecrypter { | 57 // NewCBCDecrypter returns a BlockMode which decrypts in cipher block chaining |
55 » return (*CBCDecrypter)(newCBC(b, iv)) | 58 // mode, using the given Block. The length of iv must be the same as the |
| 59 // Block's block size as must match the iv used to encrypt the data. |
| 60 func NewCBCDecrypter(b Block, iv []byte) *cbcDecrypter { |
| 61 » return (*cbcDecrypter)(newCBC(b, iv)) |
56 } | 62 } |
57 | 63 |
58 func (x *CBCDecrypter) BlockSize() int { return x.blockSize } | 64 func (x *cbcDecrypter) BlockSize() int { return x.blockSize } |
59 | 65 |
60 func (x *CBCDecrypter) CryptBlocks(dst, src []byte) { | 66 func (x *cbcDecrypter) CryptBlocks(dst, src []byte) { |
61 for len(src) > 0 { | 67 for len(src) > 0 { |
62 x.b.Decrypt(x.tmp, src[:x.blockSize]) | 68 x.b.Decrypt(x.tmp, src[:x.blockSize]) |
63 for i := 0; i < x.blockSize; i++ { | 69 for i := 0; i < x.blockSize; i++ { |
64 x.tmp[i] ^= x.iv[i] | 70 x.tmp[i] ^= x.iv[i] |
65 x.iv[i] = src[i] | 71 x.iv[i] = src[i] |
66 dst[i] = x.tmp[i] | 72 dst[i] = x.tmp[i] |
67 } | 73 } |
68 | 74 |
69 src = src[x.blockSize:] | 75 src = src[x.blockSize:] |
70 dst = dst[x.blockSize:] | 76 dst = dst[x.blockSize:] |
71 } | 77 } |
72 } | 78 } |
LEFT | RIGHT |