Skip to content

Instantly share code, notes, and snippets.

@clouetb
Created April 7, 2018 17:14
Show Gist options
  • Save clouetb/072786143f89d7ebd0174f51d396f82b to your computer and use it in GitHub Desktop.
Save clouetb/072786143f89d7ebd0174f51d396f82b to your computer and use it in GitHub Desktop.
--- go-ethereum-1.7.2/p2p/rlpx.go 2017-10-14 14:58:53.000000000 +0200
+++ rlpx.go 2018-04-07 19:07:05.000000000 +0200
@@ -173,17 +173,20 @@
var (
sec secrets
err error
+ initiator bool // A flag tracking if node is initiator of the handshakes
)
if dial == nil {
sec, err = receiverEncHandshake(t.fd, prv, nil)
+ initiator = false
} else {
sec, err = initiatorEncHandshake(t.fd, prv, dial.ID, nil)
+ initiator = true
}
if err != nil {
return discover.NodeID{}, err
}
t.wmu.Lock()
- t.rw = newRLPXFrameRW(t.fd, sec)
+ t.rw = newRLPXFrameRW(t.fd, sec, initiator)
t.wmu.Unlock()
return sec.RemoteID, nil
}
@@ -203,7 +206,7 @@
// which are negotiated during the encryption handshake.
type secrets struct {
RemoteID discover.NodeID
- AES, MAC []byte
+ AES, AES2, MAC []byte
EgressMAC, IngressMAC hash.Hash
Token []byte
}
@@ -242,10 +245,12 @@
// derive base secrets from ephemeral key agreement
sharedSecret := crypto.Keccak256(ecdheSecret, crypto.Keccak256(h.respNonce, h.initNonce))
aesSecret := crypto.Keccak256(ecdheSecret, sharedSecret)
+ aesSecret2 := crypto.Keccak256(ecdheSecret, aesSecret) // derive a second secret for aes
s := secrets{
RemoteID: h.remoteID,
AES: aesSecret,
- MAC: crypto.Keccak256(ecdheSecret, aesSecret),
+ AES2: aesSecret2,
+ MAC: crypto.Keccak256(ecdheSecret, aesSecret2), // derive mac secret from second aes secret
}
// setup sha3 instances for the MACs
@@ -569,22 +574,38 @@
snappy bool
}
-func newRLPXFrameRW(conn io.ReadWriter, s secrets) *rlpxFrameRW {
+func newRLPXFrameRW(conn io.ReadWriter, s secrets, initiator bool) *rlpxFrameRW {
macc, err := aes.NewCipher(s.MAC)
if err != nil {
panic("invalid MAC secret: " + err.Error())
}
- encc, err := aes.NewCipher(s.AES)
+ // initializes aes keys according to role played by node during the handshake
+ var enccKey, deccKey []byte
+ if initiator {
+ enccKey = s.AES
+ deccKey = s.AES2
+ } else {
+ enccKey = s.AES2
+ deccKey = s.AES
+ }
+ // create 2 cyphers
+ encc, err := aes.NewCipher(enccKey)
+ if err != nil {
+ panic("invalid AES secret: " + err.Error())
+ }
+ decc, err := aes.NewCipher(deccKey)
if err != nil {
panic("invalid AES secret: " + err.Error())
}
// we use an all-zeroes IV for AES because the key used
// for encryption is ephemeral.
- iv := make([]byte, encc.BlockSize())
+ enccIv := make([]byte, encc.BlockSize())
+ deccIv := make([]byte, decc.BlockSize())
+
return &rlpxFrameRW{
conn: conn,
- enc: cipher.NewCTR(encc, iv),
- dec: cipher.NewCTR(encc, iv),
+ enc: cipher.NewCTR(encc, enccIv),
+ dec: cipher.NewCTR(decc, deccIv),
macCipher: macc,
egressMAC: s.EgressMAC,
ingressMAC: s.IngressMAC,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment