@@ -10,6 +10,7 @@ import (
10
10
"crypto/cipher"
11
11
"encoding/binary"
12
12
"io"
13
+ "math"
13
14
"sync"
14
15
)
15
16
@@ -23,28 +24,29 @@ const (
23
24
24
25
const (
25
26
// NotAuthentic is returned when the decryption of a data stream fails.
26
- // It indicates that the data is not authentic - e.g. malisously modified.
27
- NotAuthentic errorType = "data is not authentic"
27
+ // It indicates that the encrypted data is invalid - i.e. it has been
28
+ // (maliciously) modified.
29
+ NotAuthentic errorType = "sio: data is not authentic"
28
30
29
31
// ErrExceeded is returned when no more data can be encrypted /
30
32
// decrypted securely. It indicates that the data stream is too
31
33
// large to be encrypted / decrypted with a single key-nonce
32
34
// combination.
33
35
//
34
- // For BufSize this will happen after processing ~64 TiB.
35
- ErrExceeded errorType = "data limit exceeded"
36
+ // It depends on the buffer size how many bytes can be
37
+ // encrypted / decrypted securely using the same key-nonce
38
+ // combination. For BufSize the limit is ~64 TiB.
39
+ ErrExceeded errorType = "sio: data limit exceeded"
36
40
)
37
41
38
42
type errorType string
39
43
40
44
func (e errorType ) Error () string { return string (e ) }
41
45
42
46
// NewStream creates a new Stream that encrypts or decrypts data
43
- // streams with the cipher. If you don't have special requirements
44
- // just use the default BufSize.
45
- //
46
- // The returned Stream will allocate a new bufSize large buffer
47
- // when en/decrypting a data stream.
47
+ // streams with the cipher using bufSize large chunks. Therefore,
48
+ // the bufSize must be the same for encryption and decryption. If
49
+ // you don't have special requirements just use the default BufSize.
48
50
//
49
51
// The cipher must support a NonceSize() >= 4 and the
50
52
// bufSize must be between 1 (inclusive) and MaxBufSize (inclusive).
@@ -75,35 +77,53 @@ type Stream struct {
75
77
func (s * Stream ) NonceSize () int { return s .cipher .NonceSize () - 4 }
76
78
77
79
// Overhead returns the overhead added when encrypting a
78
- // data stream. It panic's if the length is either negative
79
- // or exceeds the data limit of (2³² - 1) * bufSize bytes.
80
- func (s * Stream ) Overhead (length int64 ) int64 {
81
- if length < 0 {
82
- panic ("sio: length is negative" )
80
+ // data stream. For a plaintext stream of a non-negative
81
+ // size, the size of an encrypted data stream will be:
82
+ //
83
+ // encSize = size + stream.Overhead(size) // 0 <= size <= (2³² - 1) * bufSize
84
+ // 0 = stream.Overhead(size) // size > (2³² - 1) * bufSize
85
+ // -1 = stream.Overhead(size) // size < 0
86
+ //
87
+ // In general, the size of an encrypted data stream is
88
+ // always greater than the size of the corresponding
89
+ // plaintext stream. If size is too large (i.e.
90
+ // greater than (2³² - 1) * bufSize) then Overhead
91
+ // returns 0. If size is negative Overhead returns -1.
92
+ func (s * Stream ) Overhead (size int64 ) int64 {
93
+ if size < 0 {
94
+ return - 1
83
95
}
84
- if length > int64 (s .bufSize )* ((1 << 32 )- 1 ) {
85
- panic ("sio: length exceeds data limit" )
96
+
97
+ bufSize := int64 (s .bufSize )
98
+ if size > (bufSize * math .MaxUint32 ) {
99
+ return 0
86
100
}
87
101
88
102
overhead := int64 (s .cipher .Overhead ())
89
- if length == 0 {
103
+ if size == 0 {
90
104
return overhead
91
105
}
92
106
93
- t := length / int64 ( s . bufSize )
94
- if r := length % int64 ( s . bufSize ) ; r > 0 {
107
+ t := size / bufSize
108
+ if r := size % bufSize ; r > 0 {
95
109
return (t * overhead ) + overhead
96
110
}
97
111
return t * overhead
98
112
}
99
113
100
114
// EncryptWriter returns a new EncWriter that wraps w and
101
- // encrypts and authenticates everything written to it.
102
- // The nonce must be NonceSize() bytes long and unique for
103
- // the same key (used to create cipher.AEAD). The
104
- // associatedData is authenticated but neither encrypted nor
105
- // written to w and must be provided whenever decrypting the
106
- // data again.
115
+ // encrypts and authenticates everything before writing
116
+ // it to w.
117
+ //
118
+ // The nonce must be Stream.NonceSize() bytes long and unique
119
+ // for the same key. The same nonce must be provided when
120
+ // decrypting the data stream.
121
+ //
122
+ // The associatedData is only authenticated but not encrypted
123
+ // and not written to w. Instead, the same associatedData must
124
+ // be provided when decrypting the data stream again. It is
125
+ // safe to set:
126
+ // associatedData = nil
107
127
func (s * Stream ) EncryptWriter (w io.Writer , nonce , associatedData []byte ) * EncWriter {
108
128
if len (nonce ) != s .NonceSize () {
109
129
panic ("sio: nonce has invalid length" )
@@ -124,10 +144,14 @@ func (s *Stream) EncryptWriter(w io.Writer, nonce, associatedData []byte) *EncWr
124
144
}
125
145
126
146
// DecryptWriter returns a new DecWriter that wraps w and
127
- // decrypts and verifies everything written to it. The
128
- // nonce and associatedData must match the values used
129
- // when encrypting the data. The associatedData is not
130
- // written to w.
147
+ // decrypts and verifies everything before writing
148
+ // it to w.
149
+ //
150
+ // The nonce must be Stream.NonceSize() bytes long and
151
+ // must match the value used when encrypting the data stream.
152
+ //
153
+ // The associatedData must match the value used when encrypting
154
+ // the data stream.
131
155
func (s * Stream ) DecryptWriter (w io.Writer , nonce , associatedData []byte ) * DecWriter {
132
156
if len (nonce ) != s .NonceSize () {
133
157
panic ("sio: nonce has invalid length" )
@@ -148,10 +172,17 @@ func (s *Stream) DecryptWriter(w io.Writer, nonce, associatedData []byte) *DecWr
148
172
}
149
173
150
174
// EncryptReader returns a new EncReader that wraps r and
151
- // encrypts and authenticates everything it reads. The
152
- // nonce must be NonceSize() bytes long and unique for
153
- // the same key (used to create cipher.AEAD). The
154
- // associatedData is authenticated but not encrypted.
175
+ // encrypts and authenticates it reads from r.
176
+ //
177
+ // The nonce must be Stream.NonceSize() bytes long and unique
178
+ // for the same key. The same nonce must be provided when
179
+ // decrypting the data stream.
180
+ //
181
+ // The associatedData is only authenticated but not encrypted
182
+ // and not written to w. Instead, the same associatedData must
183
+ // be provided when decrypting the data stream again. It is
184
+ // safe to set:
185
+ // associatedData = nil
155
186
func (s * Stream ) EncryptReader (r io.Reader , nonce , associatedData []byte ) * EncReader {
156
187
if len (nonce ) != s .NonceSize () {
157
188
panic ("sio: nonce has invalid length" )
@@ -174,9 +205,13 @@ func (s *Stream) EncryptReader(r io.Reader, nonce, associatedData []byte) *EncRe
174
205
}
175
206
176
207
// DecryptReader returns a new DecReader that wraps r and
177
- // decrypts and verifies everything it reads. The nonce
178
- // and associatedData must match the values used to
179
- // encrypt the data.
208
+ // decrypts and verifies everything it reads from r.
209
+ //
210
+ // The nonce must be Stream.NonceSize() bytes long and
211
+ // must match the value used when encrypting the data stream.
212
+ //
213
+ // The associatedData must match the value used when encrypting
214
+ // the data stream.
180
215
func (s * Stream ) DecryptReader (r io.Reader , nonce , associatedData []byte ) * DecReader {
181
216
if len (nonce ) != s .NonceSize () {
182
217
panic ("sio: nonce has invalid length" )
@@ -198,10 +233,14 @@ func (s *Stream) DecryptReader(r io.Reader, nonce, associatedData []byte) *DecRe
198
233
return dr
199
234
}
200
235
201
- // DecryptReaderAt returns a new DecReaderAt that wraps r and
202
- // decrypts and verifies everything it reads. The nonce
203
- // and associatedData must match the values used to
204
- // encrypt the data.
236
+ // DecryptReader returns a new DecReaderAt that wraps r and
237
+ // decrypts and verifies everything it reads from r.
238
+ //
239
+ // The nonce must be Stream.NonceSize() bytes long and
240
+ // must match the value used when encrypting the data stream.
241
+ //
242
+ // The associatedData must match the value used when encrypting
243
+ // the data stream.
205
244
func (s * Stream ) DecryptReaderAt (r io.ReaderAt , nonce , associatedData []byte ) * DecReaderAt {
206
245
if len (nonce ) != s .NonceSize () {
207
246
panic ("sio: nonce has invalid length" )
0 commit comments