...
Run Format

Source file src/crypto/cipher/cfb.go

Documentation: crypto/cipher

  // Copyright 2010 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  // CFB (Cipher Feedback) Mode.
  
  package cipher
  
  type cfb struct {
  	b       Block
  	next    []byte
  	out     []byte
  	outUsed int
  
  	decrypt bool
  }
  
  func (x *cfb) XORKeyStream(dst, src []byte) {
  	for len(src) > 0 {
  		if x.outUsed == len(x.out) {
  			x.b.Encrypt(x.out, x.next)
  			x.outUsed = 0
  		}
  
  		if x.decrypt {
  			// We can precompute a larger segment of the
  			// keystream on decryption. This will allow
  			// larger batches for xor, and we should be
  			// able to match CTR/OFB performance.
  			copy(x.next[x.outUsed:], src)
  		}
  		n := xorBytes(dst, src, x.out[x.outUsed:])
  		if !x.decrypt {
  			copy(x.next[x.outUsed:], dst)
  		}
  		dst = dst[n:]
  		src = src[n:]
  		x.outUsed += n
  	}
  }
  
  // NewCFBEncrypter returns a Stream which encrypts with cipher feedback mode,
  // using the given Block. The iv must be the same length as the Block's block
  // size.
  func NewCFBEncrypter(block Block, iv []byte) Stream {
  	return newCFB(block, iv, false)
  }
  
  // NewCFBDecrypter returns a Stream which decrypts with cipher feedback mode,
  // using the given Block. The iv must be the same length as the Block's block
  // size.
  func NewCFBDecrypter(block Block, iv []byte) Stream {
  	return newCFB(block, iv, true)
  }
  
  func newCFB(block Block, iv []byte, decrypt bool) Stream {
  	blockSize := block.BlockSize()
  	if len(iv) != blockSize {
  		// stack trace will indicate whether it was de or encryption
  		panic("cipher.newCFB: IV length must equal block size")
  	}
  	x := &cfb{
  		b:       block,
  		out:     make([]byte, blockSize),
  		next:    make([]byte, blockSize),
  		outUsed: blockSize,
  		decrypt: decrypt,
  	}
  	copy(x.next, iv)
  
  	return x
  }
  

View as plain text