...

Source file src/pkg/crypto/cipher/ofb.go

     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	}
    75	

View as plain text