...

Source file src/crypto/cipher/cfb.go

Documentation: crypto/cipher

		 1  // Copyright 2010 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  // CFB (Cipher Feedback) Mode.
		 6  
		 7  package cipher
		 8  
		 9  import "crypto/internal/subtle"
		10  
		11  type cfb struct {
		12  	b			 Block
		13  	next		[]byte
		14  	out		 []byte
		15  	outUsed int
		16  
		17  	decrypt bool
		18  }
		19  
		20  func (x *cfb) XORKeyStream(dst, src []byte) {
		21  	if len(dst) < len(src) {
		22  		panic("crypto/cipher: output smaller than input")
		23  	}
		24  	if subtle.InexactOverlap(dst[:len(src)], src) {
		25  		panic("crypto/cipher: invalid buffer overlap")
		26  	}
		27  	for len(src) > 0 {
		28  		if x.outUsed == len(x.out) {
		29  			x.b.Encrypt(x.out, x.next)
		30  			x.outUsed = 0
		31  		}
		32  
		33  		if x.decrypt {
		34  			// We can precompute a larger segment of the
		35  			// keystream on decryption. This will allow
		36  			// larger batches for xor, and we should be
		37  			// able to match CTR/OFB performance.
		38  			copy(x.next[x.outUsed:], src)
		39  		}
		40  		n := xorBytes(dst, src, x.out[x.outUsed:])
		41  		if !x.decrypt {
		42  			copy(x.next[x.outUsed:], dst)
		43  		}
		44  		dst = dst[n:]
		45  		src = src[n:]
		46  		x.outUsed += n
		47  	}
		48  }
		49  
		50  // NewCFBEncrypter returns a Stream which encrypts with cipher feedback mode,
		51  // using the given Block. The iv must be the same length as the Block's block
		52  // size.
		53  func NewCFBEncrypter(block Block, iv []byte) Stream {
		54  	return newCFB(block, iv, false)
		55  }
		56  
		57  // NewCFBDecrypter returns a Stream which decrypts with cipher feedback mode,
		58  // using the given Block. The iv must be the same length as the Block's block
		59  // size.
		60  func NewCFBDecrypter(block Block, iv []byte) Stream {
		61  	return newCFB(block, iv, true)
		62  }
		63  
		64  func newCFB(block Block, iv []byte, decrypt bool) Stream {
		65  	blockSize := block.BlockSize()
		66  	if len(iv) != blockSize {
		67  		// stack trace will indicate whether it was de or encryption
		68  		panic("cipher.newCFB: IV length must equal block size")
		69  	}
		70  	x := &cfb{
		71  		b:			 block,
		72  		out:		 make([]byte, blockSize),
		73  		next:		make([]byte, blockSize),
		74  		outUsed: blockSize,
		75  		decrypt: decrypt,
		76  	}
		77  	copy(x.next, iv)
		78  
		79  	return x
		80  }
		81  

View as plain text