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