secio: encrypt copy
sadly, encrypting needs to copy, as the user supplied buffer must not be mangled.
Juan Batiz-Benet committed
Dec 12, 2014 at 01:44 UTC
9267f450850161d0530c957cd439e7d842c6a966
1 file changed
+26
-12
crypto/secio/rw.go
+26
-12
@@ -11,21 +11,27 @@ import (
11
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
12
proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
13
msgio "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio"
14
+ mpool "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio/mpool"
15
)
16
17
// ErrMACInvalid signals that a MAC verification failed
18
var ErrMACInvalid = errors.New("MAC verification failed")
19
20
+// BufPool is a ByteSlicePool for messages. we need buffers because (sadly)
21
+// we cannot encrypt in place-- the user needs their buffer back.
22
+var BufPool = mpool.ByteSlicePool
23
+
24
type etmWriter struct {
25
// params
21
- msg msgio.WriteCloser
22
- str cipher.Stream
23
- mac HMAC
26
+ pool mpool.Pool // for the buffers with encrypted data
27
+ msg msgio.WriteCloser // msgio for knowing where boundaries lie
28
+ str cipher.Stream // the stream cipher to encrypt with
29
+ mac HMAC // the mac to authenticate data with
30
}
31
32
// NewETMWriter Encrypt-Then-MAC
33
func NewETMWriter(w io.Writer, s cipher.Stream, mac HMAC) msgio.WriteCloser {
28
- return &etmWriter{msg: msgio.NewWriter(w), str: s, mac: mac}
34
+ return &etmWriter{msg: msgio.NewWriter(w), str: s, mac: mac, pool: BufPool}
35
}
36
37
// Write writes passed in buffer as a single message.
@@ -40,21 +46,26 @@ func (w *etmWriter) Write(b []byte) (int, error) {
46
func (w *etmWriter) WriteMsg(b []byte) error {
47
48
// encrypt.
43
- w.str.XORKeyStream(b, b)
49
+ data := w.pool.Get(uint32(len(b))).([]byte)
50
+ data = data[:len(b)] // the pool's buffer may be larger
51
+ w.str.XORKeyStream(data, b)
52
+
53
+ // log.Debugf("ENC plaintext (%d): %s %v", len(b), b, b)
54
+ // log.Debugf("ENC ciphertext (%d): %s %v", len(data), data, data)
55
56
// then, mac.
46
- if _, err := w.mac.Write(b); err != nil {
57
+ if _, err := w.mac.Write(data); err != nil {
58
return err
59
}
60
61
// Sum appends.
51
- b = w.mac.Sum(b)
62
+ data = w.mac.Sum(data)
63
w.mac.Reset()
64
// it's sad to append here. our buffers are -- hopefully -- coming from
65
// a shared buffer pool, so the append may not actually cause allocation
66
// one can only hope. i guess we'll see.
67
57
- return w.msg.WriteMsg(b)
68
+ return w.msg.WriteMsg(data)
69
}
70
71
func (w *etmWriter) Close() error {
@@ -66,9 +77,9 @@ type etmReader struct {
77
io.Closer
78
79
// params
69
- msg msgio.ReadCloser
70
- str cipher.Stream
71
- mac HMAC
80
+ msg msgio.ReadCloser // msgio for knowing where boundaries lie
81
+ str cipher.Stream // the stream cipher to encrypt with
82
+ mac HMAC // the mac to authenticate data with
83
}
84
85
// NewETMReader Encrypt-Then-MAC
@@ -137,8 +148,11 @@ func (r *etmReader) macCheckThenDecrypt(m []byte) (int, error) {
148
return 0, ErrMACInvalid
149
}
150
140
- // ok seems good. decrypt.
151
+ // ok seems good. decrypt. (can decrypt in place, yay!)
152
+ // log.Debugf("DEC ciphertext (%d): %s %v", len(data), data, data)
153
r.str.XORKeyStream(data, data)
154
+ // log.Debugf("DEC plaintext (%d): %s %v", len(data), data, data)
155
+
156
return mark, nil
157
}
158