@cryptotaxi247 / kubo / commits / 9267f4508

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