github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/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 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 }