Skip to content

Commit a8644fa

Browse files
author
Andreas Auernhammer
committed
docs: improve Stream go docs
This commit improves the go doc documentation of Stream (w.r.t. en/decryption io.Reader and io.Writer). Further, it relaxes the restrictions on `Overhead` such that it returns -1 for a negative size and 0 for a too large size.
1 parent b0537f6 commit a8644fa

File tree

1 file changed

+79
-40
lines changed

1 file changed

+79
-40
lines changed

sio.go

Lines changed: 79 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"crypto/cipher"
1111
"encoding/binary"
1212
"io"
13+
"math"
1314
"sync"
1415
)
1516

@@ -23,28 +24,29 @@ const (
2324

2425
const (
2526
// 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"
2830

2931
// ErrExceeded is returned when no more data can be encrypted /
3032
// decrypted securely. It indicates that the data stream is too
3133
// large to be encrypted / decrypted with a single key-nonce
3234
// combination.
3335
//
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"
3640
)
3741

3842
type errorType string
3943

4044
func (e errorType) Error() string { return string(e) }
4145

4246
// 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.
4850
//
4951
// The cipher must support a NonceSize() >= 4 and the
5052
// bufSize must be between 1 (inclusive) and MaxBufSize (inclusive).
@@ -75,35 +77,53 @@ type Stream struct {
7577
func (s *Stream) NonceSize() int { return s.cipher.NonceSize() - 4 }
7678

7779
// 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
8395
}
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
86100
}
87101

88102
overhead := int64(s.cipher.Overhead())
89-
if length == 0 {
103+
if size == 0 {
90104
return overhead
91105
}
92106

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 {
95109
return (t * overhead) + overhead
96110
}
97111
return t * overhead
98112
}
99113

100114
// 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
107127
func (s *Stream) EncryptWriter(w io.Writer, nonce, associatedData []byte) *EncWriter {
108128
if len(nonce) != s.NonceSize() {
109129
panic("sio: nonce has invalid length")
@@ -124,10 +144,14 @@ func (s *Stream) EncryptWriter(w io.Writer, nonce, associatedData []byte) *EncWr
124144
}
125145

126146
// 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.
131155
func (s *Stream) DecryptWriter(w io.Writer, nonce, associatedData []byte) *DecWriter {
132156
if len(nonce) != s.NonceSize() {
133157
panic("sio: nonce has invalid length")
@@ -148,10 +172,17 @@ func (s *Stream) DecryptWriter(w io.Writer, nonce, associatedData []byte) *DecWr
148172
}
149173

150174
// 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
155186
func (s *Stream) EncryptReader(r io.Reader, nonce, associatedData []byte) *EncReader {
156187
if len(nonce) != s.NonceSize() {
157188
panic("sio: nonce has invalid length")
@@ -174,9 +205,13 @@ func (s *Stream) EncryptReader(r io.Reader, nonce, associatedData []byte) *EncRe
174205
}
175206

176207
// 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.
180215
func (s *Stream) DecryptReader(r io.Reader, nonce, associatedData []byte) *DecReader {
181216
if len(nonce) != s.NonceSize() {
182217
panic("sio: nonce has invalid length")
@@ -198,10 +233,14 @@ func (s *Stream) DecryptReader(r io.Reader, nonce, associatedData []byte) *DecRe
198233
return dr
199234
}
200235

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.
205244
func (s *Stream) DecryptReaderAt(r io.ReaderAt, nonce, associatedData []byte) *DecReaderAt {
206245
if len(nonce) != s.NonceSize() {
207246
panic("sio: nonce has invalid length")

0 commit comments

Comments
 (0)