diff options
Diffstat (limited to 'src/pkg/crypto/cipher/ofb.go')
-rw-r--r-- | src/pkg/crypto/cipher/ofb.go | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/src/pkg/crypto/cipher/ofb.go b/src/pkg/crypto/cipher/ofb.go index 85e5f02b0..e86ebcb23 100644 --- a/src/pkg/crypto/cipher/ofb.go +++ b/src/pkg/crypto/cipher/ofb.go @@ -8,6 +8,7 @@ package cipher type ofb struct { b Block + cipher []byte out []byte outUsed int } @@ -20,25 +21,46 @@ func NewOFB(b Block, iv []byte) Stream { if len(iv) != blockSize { return nil } - + bufSize := streamBufferSize + if bufSize < blockSize { + bufSize = blockSize + } x := &ofb{ b: b, - out: make([]byte, blockSize), + cipher: make([]byte, blockSize), + out: make([]byte, 0, bufSize), outUsed: 0, } - b.Encrypt(x.out, iv) + copy(x.cipher, iv) return x } +func (x *ofb) refill() { + bs := x.b.BlockSize() + remain := len(x.out) - x.outUsed + if remain > x.outUsed { + return + } + copy(x.out, x.out[x.outUsed:]) + x.out = x.out[:cap(x.out)] + for remain < len(x.out)-bs { + x.b.Encrypt(x.cipher, x.cipher) + copy(x.out[remain:], x.cipher) + remain += bs + } + x.out = x.out[:remain] + x.outUsed = 0 +} + func (x *ofb) XORKeyStream(dst, src []byte) { - for i, s := range src { - if x.outUsed == len(x.out) { - x.b.Encrypt(x.out, x.out) - x.outUsed = 0 + for len(src) > 0 { + if x.outUsed >= len(x.out)-x.b.BlockSize() { + x.refill() } - - dst[i] = s ^ x.out[x.outUsed] - x.outUsed++ + n := xorBytes(dst, src, x.out[x.outUsed:]) + dst = dst[n:] + src = src[n:] + x.outUsed += n } } |