1
2
3
4
5
6
7 package cipher
8
9 import "crypto/internal/subtle"
10
11 type ofb struct {
12 b Block
13 cipher []byte
14 out []byte
15 outUsed int
16 }
17
18
19
20
21 func NewOFB(b Block, iv []byte) Stream {
22 blockSize := b.BlockSize()
23 if len(iv) != blockSize {
24 panic("cipher.NewOFB: IV length must equal block size")
25 }
26 bufSize := streamBufferSize
27 if bufSize < blockSize {
28 bufSize = blockSize
29 }
30 x := &ofb{
31 b: b,
32 cipher: make([]byte, blockSize),
33 out: make([]byte, 0, bufSize),
34 outUsed: 0,
35 }
36
37 copy(x.cipher, iv)
38 return x
39 }
40
41 func (x *ofb) refill() {
42 bs := x.b.BlockSize()
43 remain := len(x.out) - x.outUsed
44 if remain > x.outUsed {
45 return
46 }
47 copy(x.out, x.out[x.outUsed:])
48 x.out = x.out[:cap(x.out)]
49 for remain < len(x.out)-bs {
50 x.b.Encrypt(x.cipher, x.cipher)
51 copy(x.out[remain:], x.cipher)
52 remain += bs
53 }
54 x.out = x.out[:remain]
55 x.outUsed = 0
56 }
57
58 func (x *ofb) XORKeyStream(dst, src []byte) {
59 if len(dst) < len(src) {
60 panic("crypto/cipher: output smaller than input")
61 }
62 if subtle.InexactOverlap(dst[:len(src)], src) {
63 panic("crypto/cipher: invalid buffer overlap")
64 }
65 for len(src) > 0 {
66 if x.outUsed >= len(x.out)-x.b.BlockSize() {
67 x.refill()
68 }
69 n := xorBytes(dst, src, x.out[x.outUsed:])
70 dst = dst[n:]
71 src = src[n:]
72 x.outUsed += n
73 }
74 }
75
View as plain text