提交 9267f450 作者: Juan Batiz-Benet

secio: encrypt copy

sadly, encrypting needs to copy, as the user supplied buffer
must not be mangled.
上级 8d961fc0
...@@ -11,21 +11,27 @@ import ( ...@@ -11,21 +11,27 @@ import (
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context" context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto" proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
msgio "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio" msgio "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio"
mpool "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-msgio/mpool"
) )
// ErrMACInvalid signals that a MAC verification failed // ErrMACInvalid signals that a MAC verification failed
var ErrMACInvalid = errors.New("MAC verification failed") var ErrMACInvalid = errors.New("MAC verification failed")
// BufPool is a ByteSlicePool for messages. we need buffers because (sadly)
// we cannot encrypt in place-- the user needs their buffer back.
var BufPool = mpool.ByteSlicePool
type etmWriter struct { type etmWriter struct {
// params // params
msg msgio.WriteCloser pool mpool.Pool // for the buffers with encrypted data
str cipher.Stream msg msgio.WriteCloser // msgio for knowing where boundaries lie
mac HMAC str cipher.Stream // the stream cipher to encrypt with
mac HMAC // the mac to authenticate data with
} }
// NewETMWriter Encrypt-Then-MAC // NewETMWriter Encrypt-Then-MAC
func NewETMWriter(w io.Writer, s cipher.Stream, mac HMAC) msgio.WriteCloser { func NewETMWriter(w io.Writer, s cipher.Stream, mac HMAC) msgio.WriteCloser {
return &etmWriter{msg: msgio.NewWriter(w), str: s, mac: mac} return &etmWriter{msg: msgio.NewWriter(w), str: s, mac: mac, pool: BufPool}
} }
// Write writes passed in buffer as a single message. // Write writes passed in buffer as a single message.
...@@ -40,21 +46,26 @@ func (w *etmWriter) Write(b []byte) (int, error) { ...@@ -40,21 +46,26 @@ func (w *etmWriter) Write(b []byte) (int, error) {
func (w *etmWriter) WriteMsg(b []byte) error { func (w *etmWriter) WriteMsg(b []byte) error {
// encrypt. // encrypt.
w.str.XORKeyStream(b, b) data := w.pool.Get(uint32(len(b))).([]byte)
data = data[:len(b)] // the pool's buffer may be larger
w.str.XORKeyStream(data, b)
// log.Debugf("ENC plaintext (%d): %s %v", len(b), b, b)
// log.Debugf("ENC ciphertext (%d): %s %v", len(data), data, data)
// then, mac. // then, mac.
if _, err := w.mac.Write(b); err != nil { if _, err := w.mac.Write(data); err != nil {
return err return err
} }
// Sum appends. // Sum appends.
b = w.mac.Sum(b) data = w.mac.Sum(data)
w.mac.Reset() w.mac.Reset()
// it's sad to append here. our buffers are -- hopefully -- coming from // it's sad to append here. our buffers are -- hopefully -- coming from
// a shared buffer pool, so the append may not actually cause allocation // a shared buffer pool, so the append may not actually cause allocation
// one can only hope. i guess we'll see. // one can only hope. i guess we'll see.
return w.msg.WriteMsg(b) return w.msg.WriteMsg(data)
} }
func (w *etmWriter) Close() error { func (w *etmWriter) Close() error {
...@@ -66,9 +77,9 @@ type etmReader struct { ...@@ -66,9 +77,9 @@ type etmReader struct {
io.Closer io.Closer
// params // params
msg msgio.ReadCloser msg msgio.ReadCloser // msgio for knowing where boundaries lie
str cipher.Stream str cipher.Stream // the stream cipher to encrypt with
mac HMAC mac HMAC // the mac to authenticate data with
} }
// NewETMReader Encrypt-Then-MAC // NewETMReader Encrypt-Then-MAC
...@@ -137,8 +148,11 @@ func (r *etmReader) macCheckThenDecrypt(m []byte) (int, error) { ...@@ -137,8 +148,11 @@ func (r *etmReader) macCheckThenDecrypt(m []byte) (int, error) {
return 0, ErrMACInvalid return 0, ErrMACInvalid
} }
// ok seems good. decrypt. // ok seems good. decrypt. (can decrypt in place, yay!)
// log.Debugf("DEC ciphertext (%d): %s %v", len(data), data, data)
r.str.XORKeyStream(data, data) r.str.XORKeyStream(data, data)
// log.Debugf("DEC plaintext (%d): %s %v", len(data), data, data)
return mark, nil return mark, nil
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论