Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libgo / go / 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 }