github.com/mattn/go@v0.0.0-20171011075504-07f7db3ea99f/src/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 next []byte 12 out []byte 13 outUsed int 14 15 decrypt bool 16 } 17 18 func (x *cfb) XORKeyStream(dst, src []byte) { 19 for len(src) > 0 { 20 if x.outUsed == len(x.out) { 21 x.b.Encrypt(x.out, x.next) 22 x.outUsed = 0 23 } 24 25 if x.decrypt { 26 // We can precompute a larger segment of the 27 // keystream on decryption. This will allow 28 // larger batches for xor, and we should be 29 // able to match CTR/OFB performance. 30 copy(x.next[x.outUsed:], src) 31 } 32 n := xorBytes(dst, src, x.out[x.outUsed:]) 33 if !x.decrypt { 34 copy(x.next[x.outUsed:], dst) 35 } 36 dst = dst[n:] 37 src = src[n:] 38 x.outUsed += n 39 } 40 } 41 42 // NewCFBEncrypter returns a Stream which encrypts with cipher feedback mode, 43 // using the given Block. The iv must be the same length as the Block's block 44 // size. 45 func NewCFBEncrypter(block Block, iv []byte) Stream { 46 return newCFB(block, iv, false) 47 } 48 49 // NewCFBDecrypter returns a Stream which decrypts with cipher feedback mode, 50 // using the given Block. The iv must be the same length as the Block's block 51 // size. 52 func NewCFBDecrypter(block Block, iv []byte) Stream { 53 return newCFB(block, iv, true) 54 } 55 56 func newCFB(block Block, iv []byte, decrypt bool) Stream { 57 blockSize := block.BlockSize() 58 if len(iv) != blockSize { 59 // stack trace will indicate whether it was de or encryption 60 panic("cipher.newCFB: IV length must equal block size") 61 } 62 x := &cfb{ 63 b: block, 64 out: make([]byte, blockSize), 65 next: make([]byte, blockSize), 66 outUsed: blockSize, 67 decrypt: decrypt, 68 } 69 copy(x.next, iv) 70 71 return x 72 }