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