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 func (x *cbcEncrypter) BlockSize() int { return x.blockSize }
56
57 func (x *cbcEncrypter) CryptBlocks(dst, src []byte) {
58 if len(src)%x.blockSize != 0 {
59 panic("crypto/cipher: input not full blocks")
60 }
61 if len(dst) < len(src) {
62 panic("crypto/cipher: output smaller than input")
63 }
64 if subtle.InexactOverlap(dst[:len(src)], src) {
65 panic("crypto/cipher: invalid buffer overlap")
66 }
67
68 iv := x.iv
69
70 for len(src) > 0 {
71
72 xorBytes(dst[:x.blockSize], src[:x.blockSize], iv)
73 x.b.Encrypt(dst[:x.blockSize], dst[:x.blockSize])
74
75
76 iv = dst[:x.blockSize]
77 src = src[x.blockSize:]
78 dst = dst[x.blockSize:]
79 }
80
81
82 copy(x.iv, iv)
83 }
84
85 func (x *cbcEncrypter) SetIV(iv []byte) {
86 if len(iv) != len(x.iv) {
87 panic("cipher: incorrect length IV")
88 }
89 copy(x.iv, iv)
90 }
91
92 type cbcDecrypter cbc
93
94
95
96
97
98 type cbcDecAble interface {
99 NewCBCDecrypter(iv []byte) BlockMode
100 }
101
102
103
104
105 func NewCBCDecrypter(b Block, iv []byte) BlockMode {
106 if len(iv) != b.BlockSize() {
107 panic("cipher.NewCBCDecrypter: IV length must equal block size")
108 }
109 if cbc, ok := b.(cbcDecAble); ok {
110 return cbc.NewCBCDecrypter(iv)
111 }
112 return (*cbcDecrypter)(newCBC(b, iv))
113 }
114
115 func (x *cbcDecrypter) BlockSize() int { return x.blockSize }
116
117 func (x *cbcDecrypter) CryptBlocks(dst, src []byte) {
118 if len(src)%x.blockSize != 0 {
119 panic("crypto/cipher: input not full blocks")
120 }
121 if len(dst) < len(src) {
122 panic("crypto/cipher: output smaller than input")
123 }
124 if subtle.InexactOverlap(dst[:len(src)], src) {
125 panic("crypto/cipher: invalid buffer overlap")
126 }
127 if len(src) == 0 {
128 return
129 }
130
131
132
133 end := len(src)
134 start := end - x.blockSize
135 prev := start - x.blockSize
136
137
138 copy(x.tmp, src[start:end])
139
140
141 for start > 0 {
142 x.b.Decrypt(dst[start:end], src[start:end])
143 xorBytes(dst[start:end], dst[start:end], src[prev:start])
144
145 end = start
146 start = prev
147 prev -= x.blockSize
148 }
149
150
151 x.b.Decrypt(dst[start:end], src[start:end])
152 xorBytes(dst[start:end], dst[start:end], x.iv)
153
154
155 x.iv, x.tmp = x.tmp, x.iv
156 }
157
158 func (x *cbcDecrypter) SetIV(iv []byte) {
159 if len(iv) != len(x.iv) {
160 panic("cipher: incorrect length IV")
161 }
162 copy(x.iv, iv)
163 }
164
View as plain text