1
2
3
4
5
6
7
8
9
10
11
12 package cipher
13
14 import (
15 "bytes"
16 "crypto/internal/alias"
17 "crypto/subtle"
18 )
19
20 type cbc struct {
21 b Block
22 blockSize int
23 iv []byte
24 tmp []byte
25 }
26
27 func newCBC(b Block, iv []byte) *cbc {
28 return &cbc{
29 b: b,
30 blockSize: b.BlockSize(),
31 iv: bytes.Clone(iv),
32 tmp: make([]byte, b.BlockSize()),
33 }
34 }
35
36 type cbcEncrypter cbc
37
38
39
40
41
42 type cbcEncAble interface {
43 NewCBCEncrypter(iv []byte) BlockMode
44 }
45
46
47
48
49 func NewCBCEncrypter(b Block, iv []byte) BlockMode {
50 if len(iv) != b.BlockSize() {
51 panic("cipher.NewCBCEncrypter: IV length must equal block size")
52 }
53 if cbc, ok := b.(cbcEncAble); ok {
54 return cbc.NewCBCEncrypter(iv)
55 }
56 return (*cbcEncrypter)(newCBC(b, iv))
57 }
58
59
60
61
62
63 func newCBCGenericEncrypter(b Block, iv []byte) BlockMode {
64 if len(iv) != b.BlockSize() {
65 panic("cipher.NewCBCEncrypter: IV length must equal block size")
66 }
67 return (*cbcEncrypter)(newCBC(b, iv))
68 }
69
70 func (x *cbcEncrypter) BlockSize() int { return x.blockSize }
71
72 func (x *cbcEncrypter) CryptBlocks(dst, src []byte) {
73 if len(src)%x.blockSize != 0 {
74 panic("crypto/cipher: input not full blocks")
75 }
76 if len(dst) < len(src) {
77 panic("crypto/cipher: output smaller than input")
78 }
79 if alias.InexactOverlap(dst[:len(src)], src) {
80 panic("crypto/cipher: invalid buffer overlap")
81 }
82
83 iv := x.iv
84
85 for len(src) > 0 {
86
87 subtle.XORBytes(dst[:x.blockSize], src[:x.blockSize], iv)
88 x.b.Encrypt(dst[:x.blockSize], dst[:x.blockSize])
89
90
91 iv = dst[:x.blockSize]
92 src = src[x.blockSize:]
93 dst = dst[x.blockSize:]
94 }
95
96
97 copy(x.iv, iv)
98 }
99
100 func (x *cbcEncrypter) SetIV(iv []byte) {
101 if len(iv) != len(x.iv) {
102 panic("cipher: incorrect length IV")
103 }
104 copy(x.iv, iv)
105 }
106
107 type cbcDecrypter cbc
108
109
110
111
112
113 type cbcDecAble interface {
114 NewCBCDecrypter(iv []byte) BlockMode
115 }
116
117
118
119
120 func NewCBCDecrypter(b Block, iv []byte) BlockMode {
121 if len(iv) != b.BlockSize() {
122 panic("cipher.NewCBCDecrypter: IV length must equal block size")
123 }
124 if cbc, ok := b.(cbcDecAble); ok {
125 return cbc.NewCBCDecrypter(iv)
126 }
127 return (*cbcDecrypter)(newCBC(b, iv))
128 }
129
130
131
132
133
134 func newCBCGenericDecrypter(b Block, iv []byte) BlockMode {
135 if len(iv) != b.BlockSize() {
136 panic("cipher.NewCBCDecrypter: IV length must equal block size")
137 }
138 return (*cbcDecrypter)(newCBC(b, iv))
139 }
140
141 func (x *cbcDecrypter) BlockSize() int { return x.blockSize }
142
143 func (x *cbcDecrypter) CryptBlocks(dst, src []byte) {
144 if len(src)%x.blockSize != 0 {
145 panic("crypto/cipher: input not full blocks")
146 }
147 if len(dst) < len(src) {
148 panic("crypto/cipher: output smaller than input")
149 }
150 if alias.InexactOverlap(dst[:len(src)], src) {
151 panic("crypto/cipher: invalid buffer overlap")
152 }
153 if len(src) == 0 {
154 return
155 }
156
157
158
159 end := len(src)
160 start := end - x.blockSize
161 prev := start - x.blockSize
162
163
164 copy(x.tmp, src[start:end])
165
166
167 for start > 0 {
168 x.b.Decrypt(dst[start:end], src[start:end])
169 subtle.XORBytes(dst[start:end], dst[start:end], src[prev:start])
170
171 end = start
172 start = prev
173 prev -= x.blockSize
174 }
175
176
177 x.b.Decrypt(dst[start:end], src[start:end])
178 subtle.XORBytes(dst[start:end], dst[start:end], x.iv)
179
180
181 x.iv, x.tmp = x.tmp, x.iv
182 }
183
184 func (x *cbcDecrypter) SetIV(iv []byte) {
185 if len(iv) != len(x.iv) {
186 panic("cipher: incorrect length IV")
187 }
188 copy(x.iv, iv)
189 }
190
View as plain text