p2p: Remove RipeMd160.

Generate keys with HKDF instead of hash functions, which provides better security properties.

Add xchacha20poly1305 to secret connection. (Due to rebasing, this code has been removed)
This commit is contained in:
Zaki Manian
2018-05-13 18:42:29 -04:00
committed by Alexander Simmerl
parent 66fe5b7bae
commit 1b04e4e5f1
3 changed files with 34 additions and 37 deletions

View File

@@ -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:

20
Gopkg.lock generated
View File

@@ -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",

View File

@@ -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.