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