github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/crypto/cipher/ofb.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // OFB (Output Feedback) Mode. 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 // NewOFB returns a Stream that encrypts or decrypts using the block cipher b 19 // in output feedback mode. The initialization vector iv's length must be equal 20 // to b's block size. 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 }