Source file src/pkg/crypto/cipher/ctr.go
1 // Copyright 2009 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 // Counter (CTR) mode.
6
7 // CTR converts a block cipher into a stream cipher by
8 // repeatedly encrypting an incrementing counter and
9 // xoring the resulting stream of data with the input.
10
11 // See NIST SP 800-38A, pp 13-15
12
13 package cipher
14
15 type ctr struct {
16 b Block
17 ctr []byte
18 out []byte
19 outUsed int
20 }
21
22 // NewCTR returns a Stream which encrypts/decrypts using the given Block in
23 // counter mode. The length of iv must be the same as the Block's block size.
24 func NewCTR(block Block, iv []byte) Stream {
25 if len(iv) != block.BlockSize() {
26 panic("cipher.NewCTR: iv length must equal block size")
27 }
28
29 return &ctr{
30 b: block,
31 ctr: dup(iv),
32 out: make([]byte, len(iv)),
33 outUsed: len(iv),
34 }
35 }
36
37 func (x *ctr) XORKeyStream(dst, src []byte) {
38 for i := 0; i < len(src); i++ {
39 if x.outUsed == len(x.ctr) {
40 x.b.Encrypt(x.out, x.ctr)
41 x.outUsed = 0
42
43 // Increment counter
44 for i := len(x.ctr) - 1; i >= 0; i-- {
45 x.ctr[i]++
46 if x.ctr[i] != 0 {
47 break
48 }
49 }
50 }
51
52 dst[i] = src[i] ^ x.out[x.outUsed]
53 x.outUsed++
54 }
55 }