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