github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/crypto/cipher/cfb.go (about) 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 type cfb struct { 10 b Block 11 out []byte 12 outUsed int 13 decrypt bool 14 } 15 16 // NewCFBEncrypter returns a Stream which encrypts with cipher feedback mode, 17 // using the given Block. The iv must be the same length as the Block's block 18 // size. 19 func NewCFBEncrypter(block Block, iv []byte) Stream { 20 if len(iv) != block.BlockSize() { 21 panic("cipher.NewCBFEncrypter: IV length must equal block size") 22 } 23 return newCFB(block, iv, false) 24 } 25 26 // NewCFBDecrypter returns a Stream which decrypts with cipher feedback mode, 27 // using the given Block. The iv must be the same length as the Block's block 28 // size. 29 func NewCFBDecrypter(block Block, iv []byte) Stream { 30 if len(iv) != block.BlockSize() { 31 panic("cipher.NewCBFEncrypter: IV length must equal block size") 32 } 33 return newCFB(block, iv, true) 34 } 35 36 func newCFB(block Block, iv []byte, decrypt bool) Stream { 37 blockSize := block.BlockSize() 38 if len(iv) != blockSize { 39 return nil 40 } 41 42 x := &cfb{ 43 b: block, 44 out: make([]byte, blockSize), 45 outUsed: 0, 46 decrypt: decrypt, 47 } 48 block.Encrypt(x.out, iv) 49 50 return x 51 } 52 53 func (x *cfb) XORKeyStream(dst, src []byte) { 54 for i := 0; i < len(src); i++ { 55 if x.outUsed == len(x.out) { 56 x.b.Encrypt(x.out, x.out) 57 x.outUsed = 0 58 } 59 60 if x.decrypt { 61 t := src[i] 62 dst[i] = src[i] ^ x.out[x.outUsed] 63 x.out[x.outUsed] = t 64 } else { 65 x.out[x.outUsed] ^= src[i] 66 dst[i] = x.out[x.outUsed] 67 } 68 x.outUsed++ 69 } 70 }