libgo: Merge from revision 18783:00cce3a34d7e of master library.
[official-gcc.git] / libgo / go / crypto / cipher / ofb.go
blobe86ebcb237ee3ce2ef203c92adaaa94042d94d46
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.
5 // OFB (Output Feedback) Mode.
7 package cipher
9 type ofb struct {
10 b Block
11 cipher []byte
12 out []byte
13 outUsed int
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 return nil
24 bufSize := streamBufferSize
25 if bufSize < blockSize {
26 bufSize = blockSize
28 x := &ofb{
29 b: b,
30 cipher: make([]byte, blockSize),
31 out: make([]byte, 0, bufSize),
32 outUsed: 0,
35 copy(x.cipher, iv)
36 return x
39 func (x *ofb) refill() {
40 bs := x.b.BlockSize()
41 remain := len(x.out) - x.outUsed
42 if remain > x.outUsed {
43 return
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
52 x.out = x.out[:remain]
53 x.outUsed = 0
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()
61 n := xorBytes(dst, src, x.out[x.outUsed:])
62 dst = dst[n:]
63 src = src[n:]
64 x.outUsed += n