~ubuntu-branches/ubuntu/saucy/juju-core/saucy-proposed

« back to all changes in this revision

Viewing changes to src/code.google.com/p/go.crypto/openpgp/packet/ocfb.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-07-11 17:18:27 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20130711171827-vjqkg40r0dlf7ys2
Tags: 1.11.2-0ubuntu1
* New upstream release.
* Make juju-core the default juju (LP: #1190634):
  - d/control: Add virtual package juju -> juju-core.
  - d/juju-core.postinst.in: Bump priority of alternatives over that of
    python juju packages.
* Enable for all architectures (LP: #1172505):
  - d/control: Version BD on golang-go to >= 2:1.1.1 to ensure CGO
    support for non-x86 archs, make juju-core Arch: any.
  - d/README.source: Dropped - no longer required.
* d/watch: Updated for new upstream tarball naming.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
// OpenPGP CFB Mode. http://tools.ietf.org/html/rfc4880#section-13.9
 
6
 
 
7
package packet
 
8
 
 
9
import (
 
10
        "crypto/cipher"
 
11
)
 
12
 
 
13
type ocfbEncrypter struct {
 
14
        b       cipher.Block
 
15
        fre     []byte
 
16
        outUsed int
 
17
}
 
18
 
 
19
// An OCFBResyncOption determines if the "resynchronization step" of OCFB is
 
20
// performed.
 
21
type OCFBResyncOption bool
 
22
 
 
23
const (
 
24
        OCFBResync   OCFBResyncOption = true
 
25
        OCFBNoResync OCFBResyncOption = false
 
26
)
 
27
 
 
28
// NewOCFBEncrypter returns a cipher.Stream which encrypts data with OpenPGP's
 
29
// cipher feedback mode using the given cipher.Block, and an initial amount of
 
30
// ciphertext.  randData must be random bytes and be the same length as the
 
31
// cipher.Block's block size. Resync determines if the "resynchronization step"
 
32
// from RFC 4880, 13.9 step 7 is performed. Different parts of OpenPGP vary on
 
33
// this point.
 
34
func NewOCFBEncrypter(block cipher.Block, randData []byte, resync OCFBResyncOption) (cipher.Stream, []byte) {
 
35
        blockSize := block.BlockSize()
 
36
        if len(randData) != blockSize {
 
37
                return nil, nil
 
38
        }
 
39
 
 
40
        x := &ocfbEncrypter{
 
41
                b:       block,
 
42
                fre:     make([]byte, blockSize),
 
43
                outUsed: 0,
 
44
        }
 
45
        prefix := make([]byte, blockSize+2)
 
46
 
 
47
        block.Encrypt(x.fre, x.fre)
 
48
        for i := 0; i < blockSize; i++ {
 
49
                prefix[i] = randData[i] ^ x.fre[i]
 
50
        }
 
51
 
 
52
        block.Encrypt(x.fre, prefix[:blockSize])
 
53
        prefix[blockSize] = x.fre[0] ^ randData[blockSize-2]
 
54
        prefix[blockSize+1] = x.fre[1] ^ randData[blockSize-1]
 
55
 
 
56
        if resync {
 
57
                block.Encrypt(x.fre, prefix[2:])
 
58
        } else {
 
59
                x.fre[0] = prefix[blockSize]
 
60
                x.fre[1] = prefix[blockSize+1]
 
61
                x.outUsed = 2
 
62
        }
 
63
        return x, prefix
 
64
}
 
65
 
 
66
func (x *ocfbEncrypter) XORKeyStream(dst, src []byte) {
 
67
        for i := 0; i < len(src); i++ {
 
68
                if x.outUsed == len(x.fre) {
 
69
                        x.b.Encrypt(x.fre, x.fre)
 
70
                        x.outUsed = 0
 
71
                }
 
72
 
 
73
                x.fre[x.outUsed] ^= src[i]
 
74
                dst[i] = x.fre[x.outUsed]
 
75
                x.outUsed++
 
76
        }
 
77
}
 
78
 
 
79
type ocfbDecrypter struct {
 
80
        b       cipher.Block
 
81
        fre     []byte
 
82
        outUsed int
 
83
}
 
84
 
 
85
// NewOCFBDecrypter returns a cipher.Stream which decrypts data with OpenPGP's
 
86
// cipher feedback mode using the given cipher.Block. Prefix must be the first
 
87
// blockSize + 2 bytes of the ciphertext, where blockSize is the cipher.Block's
 
88
// block size. If an incorrect key is detected then nil is returned. On
 
89
// successful exit, blockSize+2 bytes of decrypted data are written into
 
90
// prefix. Resync determines if the "resynchronization step" from RFC 4880,
 
91
// 13.9 step 7 is performed. Different parts of OpenPGP vary on this point.
 
92
func NewOCFBDecrypter(block cipher.Block, prefix []byte, resync OCFBResyncOption) cipher.Stream {
 
93
        blockSize := block.BlockSize()
 
94
        if len(prefix) != blockSize+2 {
 
95
                return nil
 
96
        }
 
97
 
 
98
        x := &ocfbDecrypter{
 
99
                b:       block,
 
100
                fre:     make([]byte, blockSize),
 
101
                outUsed: 0,
 
102
        }
 
103
        prefixCopy := make([]byte, len(prefix))
 
104
        copy(prefixCopy, prefix)
 
105
 
 
106
        block.Encrypt(x.fre, x.fre)
 
107
        for i := 0; i < blockSize; i++ {
 
108
                prefixCopy[i] ^= x.fre[i]
 
109
        }
 
110
 
 
111
        block.Encrypt(x.fre, prefix[:blockSize])
 
112
        prefixCopy[blockSize] ^= x.fre[0]
 
113
        prefixCopy[blockSize+1] ^= x.fre[1]
 
114
 
 
115
        if prefixCopy[blockSize-2] != prefixCopy[blockSize] ||
 
116
                prefixCopy[blockSize-1] != prefixCopy[blockSize+1] {
 
117
                return nil
 
118
        }
 
119
 
 
120
        if resync {
 
121
                block.Encrypt(x.fre, prefix[2:])
 
122
        } else {
 
123
                x.fre[0] = prefix[blockSize]
 
124
                x.fre[1] = prefix[blockSize+1]
 
125
                x.outUsed = 2
 
126
        }
 
127
        copy(prefix, prefixCopy)
 
128
        return x
 
129
}
 
130
 
 
131
func (x *ocfbDecrypter) XORKeyStream(dst, src []byte) {
 
132
        for i := 0; i < len(src); i++ {
 
133
                if x.outUsed == len(x.fre) {
 
134
                        x.b.Encrypt(x.fre, x.fre)
 
135
                        x.outUsed = 0
 
136
                }
 
137
 
 
138
                c := src[i]
 
139
                dst[i] = x.fre[x.outUsed] ^ src[i]
 
140
                x.fre[x.outUsed] = c
 
141
                x.outUsed++
 
142
        }
 
143
}