diff --git a/CHANGELOG.md b/CHANGELOG.md index fce7d6ee3..6629c56a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -317,6 +317,14 @@ BUG FIXES - [cmd] Set GenesisTime during `tendermint init` - [consensus] fix ValidBlock rules +## 0.20.0 (TBD) + +BREAKING: + +- [p2p] Change the key/nonce derivation in secret connection to use hkdf instead of a raw hash function. + + + ## 0.19.2 (April 30th, 2018) FEATURES: diff --git a/Gopkg.lock b/Gopkg.lock index 676751f14..796d81752 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -143,6 +143,7 @@ ".", "hcl/ast", "hcl/parser", + "hcl/printer", "hcl/scanner", "hcl/strconv", "hcl/token", @@ -194,11 +195,9 @@ [[projects]] branch = "master" - digest = "1:5ab79470a1d0fb19b041a624415612f8236b3c06070161a910562f2b2d064355" name = "github.com/mitchellh/mapstructure" packages = ["."] - pruneopts = "UT" - revision = "f15292f7a699fcc1a38a80977f80a046874ba8ac" + revision = "bb74f1db0675b241733089d5a1faa5dd8b0ef57b" [[projects]] digest = "1:95741de3af260a92cc5c7f3f3061e85273f5a81b5db20d4bd68da74bd521675e" @@ -382,13 +381,8 @@ digest = "1:df132ec33d5acb4a1ab58d637f1bc3557be49456ca59b9198f5c1e7fa32e0d31" name = "golang.org/x/crypto" packages = [ - "bcrypt", - "blowfish", - "chacha20poly1305", "curve25519", "hkdf", - "internal/chacha20", - "internal/subtle", "nacl/box", "nacl/secretbox", "openpgp/armor", @@ -463,25 +457,17 @@ packages = [ ".", "balancer", - "balancer/base", - "balancer/roundrobin", "codes", "connectivity", "credentials", - "encoding", - "encoding/proto", + "grpclb/grpc_lb_v1/messages", "grpclog", "internal", - "internal/backoff", - "internal/channelz", - "internal/grpcrand", "keepalive", "metadata", "naming", "peer", "resolver", - "resolver/dns", - "resolver/passthrough", "stats", "status", "tap", diff --git a/p2p/conn/secret_connection.go b/p2p/conn/secret_connection.go index a2cbe008d..7762515d5 100644 --- a/p2p/conn/secret_connection.go +++ b/p2p/conn/secret_connection.go @@ -17,18 +17,16 @@ import ( "time" "golang.org/x/crypto/nacl/box" - "golang.org/x/crypto/nacl/secretbox" - "golang.org/x/crypto/ripemd160" "github.com/tendermint/tendermint/crypto" cmn "github.com/tendermint/tendermint/libs/common" + "golang.org/x/crypto/hkdf" ) // 4 + 1024 == 1028 total frame size const dataLenSize = 4 const dataMaxSize = 1024 const totalFrameSize = dataMaxSize + dataLenSize -const sealedFrameSize = totalFrameSize + secretbox.Overhead // Implements net.Conn type SecretConnection struct { @@ -124,14 +122,18 @@ func (sc *SecretConnection) Write(data []byte) (n int, err error) { binary.BigEndian.PutUint32(frame, uint32(chunkLength)) copy(frame[dataLenSize:], chunk) + aead, err := xchacha20poly1305.New(sc.shrSecret[:]) + if err != nil { + return n, errors.New("Invalid SecretConnection Key") + } // encrypt the frame - var sealedFrame = make([]byte, sealedFrameSize) - secretbox.Seal(sealedFrame[:0], frame, sc.sendNonce, sc.shrSecret) + var sealedFrame = make([]byte, aead.Overhead()+totalFrameSize) + aead.Seal(sealedFrame[:0], sc.sendNonce[:], frame, nil) // fmt.Printf("secretbox.Seal(sealed:%X,sendNonce:%X,shrSecret:%X\n", sealedFrame, sc.sendNonce, sc.shrSecret) incr2Nonce(sc.sendNonce) // end encryption - _, err := sc.conn.Write(sealedFrame) + _, err = sc.conn.Write(sealedFrame) if err != nil { return n, err } @@ -148,7 +150,11 @@ func (sc *SecretConnection) Read(data []byte) (n int, err error) { return } - sealedFrame := make([]byte, sealedFrameSize) + aead, err := xchacha20poly1305.New(sc.shrSecret[:]) + if err != nil { + return n, errors.New("Invalid SecretConnection Key") + } + sealedFrame := make([]byte, totalFrameSize+aead.Overhead()) _, err = io.ReadFull(sc.conn, sealedFrame) if err != nil { return @@ -157,8 +163,8 @@ func (sc *SecretConnection) Read(data []byte) (n int, err error) { // decrypt the frame var frame = make([]byte, totalFrameSize) // fmt.Printf("secretbox.Open(sealed:%X,recvNonce:%X,shrSecret:%X\n", sealedFrame, sc.recvNonce, sc.shrSecret) - _, ok := secretbox.Open(frame[:0], sealedFrame, sc.recvNonce, sc.shrSecret) - if !ok { + _, err = aead.Open(frame[:0], sc.recvNonce[:], sealedFrame, nil) + if err != nil { return n, errors.New("Failed to decrypt SecretConnection") } incr2Nonce(sc.recvNonce) @@ -317,22 +323,19 @@ func shareAuthSignature(sc *SecretConnection, pubKey crypto.PubKey, signature cr // sha256 func hash32(input []byte) (res *[32]byte) { - hasher := sha256.New() - hasher.Write(input) // nolint: errcheck, gas - resSlice := hasher.Sum(nil) + hash := sha256.New + hkdf := hkdf.New(hash, input, nil, []byte("TENDERMINT_SECRET_CONNECTION_KEY_GEN")) res = new([32]byte) - copy(res[:], resSlice) - return + io.ReadFull(hkdf, res[:]) + return res } -// We only fill in the first 20 bytes with ripemd160 func hash24(input []byte) (res *[24]byte) { - hasher := ripemd160.New() - hasher.Write(input) // nolint: errcheck, gas - resSlice := hasher.Sum(nil) + hash := sha256.New + hkdf := hkdf.New(hash, input, nil, []byte("TENDERMINT_SECRET_CONNECTION_NONCE_GEN")) res = new([24]byte) - copy(res[:], resSlice) - return + io.ReadFull(hkdf, res[:]) + return res } // increment nonce big-endian by 2 with wraparound.