github.com/mattn/go@v0.0.0-20171011075504-07f7db3ea99f/src/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 type ofb struct { 10 b Block 11 cipher []byte 12 out []byte 13 outUsed int 14 } 15 16 // NewOFB returns a Stream that encrypts or decrypts using the block cipher b 17 // in output feedback mode. The initialization vector iv's length must be equal 18 // to b's block size. 19 func NewOFB(b Block, iv []byte) Stream { 20 blockSize := b.BlockSize() 21 if len(iv) != blockSize { 22 panic("cipher.NewOFB: IV length must equal block size") 23 } 24 bufSize := streamBufferSize 25 if bufSize < blockSize { 26 bufSize = blockSize 27 } 28 x := &ofb{ 29 b: b, 30 cipher: make([]byte, blockSize), 31 out: make([]byte, 0, bufSize), 32 outUsed: 0, 33 } 34 35 copy(x.cipher, iv) 36 return x 37 } 38 39 func (x *ofb) refill() { 40 bs := x.b.BlockSize() 41 remain := len(x.out) - x.outUsed 42 if remain > x.outUsed { 43 return 44 } 45 copy(x.out, x.out[x.outUsed:]) 46 x.out = x.out[:cap(x.out)] 47 for remain < len(x.out)-bs { 48 x.b.Encrypt(x.cipher, x.cipher) 49 copy(x.out[remain:], x.cipher) 50 remain += bs 51 } 52 x.out = x.out[:remain] 53 x.outUsed = 0 54 } 55 56 func (x *ofb) XORKeyStream(dst, src []byte) { 57 for len(src) > 0 { 58 if x.outUsed >= len(x.out)-x.b.BlockSize() { 59 x.refill() 60 } 61 n := xorBytes(dst, src, x.out[x.outUsed:]) 62 dst = dst[n:] 63 src = src[n:] 64 x.outUsed += n 65 } 66 }