Source file src/pkg/crypto/cipher/cfb.go
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 return newCFB(block, iv, false)
21 }
22
23 // NewCFBDecrypter returns a Stream which decrypts with cipher feedback mode,
24 // using the given Block. The iv must be the same length as the Block's block
25 // size.
26 func NewCFBDecrypter(block Block, iv []byte) Stream {
27 return newCFB(block, iv, true)
28 }
29
30 func newCFB(block Block, iv []byte, decrypt bool) Stream {
31 blockSize := block.BlockSize()
32 if len(iv) != blockSize {
33 return nil
34 }
35
36 x := &cfb{
37 b: block,
38 out: make([]byte, blockSize),
39 outUsed: 0,
40 decrypt: decrypt,
41 }
42 block.Encrypt(x.out, iv)
43
44 return x
45 }
46
47 func (x *cfb) XORKeyStream(dst, src []byte) {
48 for i := 0; i < len(src); i++ {
49 if x.outUsed == len(x.out) {
50 x.b.Encrypt(x.out, x.out)
51 x.outUsed = 0
52 }
53
54 if x.decrypt {
55 t := src[i]
56 dst[i] = src[i] ^ x.out[x.outUsed]
57 x.out[x.outUsed] = t
58 } else {
59 x.out[x.outUsed] ^= src[i]
60 dst[i] = x.out[x.outUsed]
61 }
62 x.outUsed++
63 }
64 }