Compare commits
6 Commits
0.0.202001
...
0.0.202003
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae88e2a2cd | ||
|
|
4739708ca4 | ||
|
|
b33219c2cf | ||
|
|
9cbcff10dd | ||
|
|
6ed56ff2df | ||
|
|
cb4bb63030 |
@@ -118,7 +118,7 @@ func createNetlinkRouteSocket() (int, error) {
|
||||
}
|
||||
saddr := &unix.SockaddrNetlink{
|
||||
Family: unix.AF_NETLINK,
|
||||
Groups: uint32(1 << (unix.RTNLGRP_IPV4_ROUTE - 1)),
|
||||
Groups: unix.RTMGRP_IPV4_ROUTE,
|
||||
}
|
||||
err = unix.Bind(sock, saddr)
|
||||
if err != nil {
|
||||
|
||||
@@ -236,24 +236,12 @@ func (device *Device) SetPrivateKey(sk NoisePrivateKey) error {
|
||||
|
||||
// do static-static DH pre-computations
|
||||
|
||||
rmKey := device.staticIdentity.privateKey.IsZero()
|
||||
|
||||
expiredPeers := make([]*Peer, 0, len(device.peers.keyMap))
|
||||
for key, peer := range device.peers.keyMap {
|
||||
for _, peer := range device.peers.keyMap {
|
||||
handshake := &peer.handshake
|
||||
|
||||
if rmKey {
|
||||
handshake.precomputedStaticStatic = [NoisePublicKeySize]byte{}
|
||||
} else {
|
||||
handshake.precomputedStaticStatic = device.staticIdentity.privateKey.sharedSecret(handshake.remoteStatic)
|
||||
}
|
||||
|
||||
if isZero(handshake.precomputedStaticStatic[:]) {
|
||||
unsafeRemovePeer(device, peer, key)
|
||||
} else {
|
||||
expiredPeers = append(expiredPeers, peer)
|
||||
}
|
||||
}
|
||||
|
||||
for _, peer := range lockedPeers {
|
||||
peer.handshake.mutex.RUnlock()
|
||||
|
||||
@@ -154,6 +154,7 @@ func init() {
|
||||
}
|
||||
|
||||
func (device *Device) CreateMessageInitiation(peer *Peer) (*MessageInitiation, error) {
|
||||
var errZeroECDHResult = errors.New("ECDH returned all zeros")
|
||||
|
||||
device.staticIdentity.RLock()
|
||||
defer device.staticIdentity.RUnlock()
|
||||
@@ -162,12 +163,7 @@ func (device *Device) CreateMessageInitiation(peer *Peer) (*MessageInitiation, e
|
||||
handshake.mutex.Lock()
|
||||
defer handshake.mutex.Unlock()
|
||||
|
||||
if isZero(handshake.precomputedStaticStatic[:]) {
|
||||
return nil, errors.New("static shared secret is zero")
|
||||
}
|
||||
|
||||
// create ephemeral key
|
||||
|
||||
var err error
|
||||
handshake.hash = InitialHash
|
||||
handshake.chainKey = InitialChainKey
|
||||
@@ -176,31 +172,22 @@ func (device *Device) CreateMessageInitiation(peer *Peer) (*MessageInitiation, e
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// assign index
|
||||
|
||||
device.indexTable.Delete(handshake.localIndex)
|
||||
handshake.localIndex, err = device.indexTable.NewIndexForHandshake(peer, handshake)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
handshake.mixHash(handshake.remoteStatic[:])
|
||||
|
||||
msg := MessageInitiation{
|
||||
Type: MessageInitiationType,
|
||||
Ephemeral: handshake.localEphemeral.publicKey(),
|
||||
Sender: handshake.localIndex,
|
||||
}
|
||||
|
||||
handshake.mixKey(msg.Ephemeral[:])
|
||||
handshake.mixHash(msg.Ephemeral[:])
|
||||
|
||||
// encrypt static key
|
||||
|
||||
func() {
|
||||
var key [chacha20poly1305.KeySize]byte
|
||||
ss := handshake.localEphemeral.sharedSecret(handshake.remoteStatic)
|
||||
if isZero(ss[:]) {
|
||||
return nil, errZeroECDHResult
|
||||
}
|
||||
var key [chacha20poly1305.KeySize]byte
|
||||
KDF2(
|
||||
&handshake.chainKey,
|
||||
&key,
|
||||
@@ -209,23 +196,29 @@ func (device *Device) CreateMessageInitiation(peer *Peer) (*MessageInitiation, e
|
||||
)
|
||||
aead, _ := chacha20poly1305.New(key[:])
|
||||
aead.Seal(msg.Static[:0], ZeroNonce[:], device.staticIdentity.publicKey[:], handshake.hash[:])
|
||||
}()
|
||||
handshake.mixHash(msg.Static[:])
|
||||
|
||||
// encrypt timestamp
|
||||
|
||||
timestamp := tai64n.Now()
|
||||
func() {
|
||||
var key [chacha20poly1305.KeySize]byte
|
||||
if isZero(handshake.precomputedStaticStatic[:]) {
|
||||
return nil, errZeroECDHResult
|
||||
}
|
||||
KDF2(
|
||||
&handshake.chainKey,
|
||||
&key,
|
||||
handshake.chainKey[:],
|
||||
handshake.precomputedStaticStatic[:],
|
||||
)
|
||||
aead, _ := chacha20poly1305.New(key[:])
|
||||
timestamp := tai64n.Now()
|
||||
aead, _ = chacha20poly1305.New(key[:])
|
||||
aead.Seal(msg.Timestamp[:0], ZeroNonce[:], timestamp[:], handshake.hash[:])
|
||||
}()
|
||||
|
||||
// assign index
|
||||
device.indexTable.Delete(handshake.localIndex)
|
||||
msg.Sender, err = device.indexTable.NewIndexForHandshake(peer, handshake)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
handshake.localIndex = msg.Sender
|
||||
|
||||
handshake.mixHash(msg.Timestamp[:])
|
||||
handshake.state = HandshakeInitiationCreated
|
||||
@@ -250,16 +243,16 @@ func (device *Device) ConsumeMessageInitiation(msg *MessageInitiation) *Peer {
|
||||
mixKey(&chainKey, &InitialChainKey, msg.Ephemeral[:])
|
||||
|
||||
// decrypt static key
|
||||
|
||||
var err error
|
||||
var peerPK NoisePublicKey
|
||||
func() {
|
||||
var key [chacha20poly1305.KeySize]byte
|
||||
ss := device.staticIdentity.privateKey.sharedSecret(msg.Ephemeral)
|
||||
if isZero(ss[:]) {
|
||||
return nil
|
||||
}
|
||||
KDF2(&chainKey, &key, chainKey[:], ss[:])
|
||||
aead, _ := chacha20poly1305.New(key[:])
|
||||
_, err = aead.Open(peerPK[:0], ZeroNonce[:], msg.Static[:], hash[:])
|
||||
}()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@@ -273,23 +266,24 @@ func (device *Device) ConsumeMessageInitiation(msg *MessageInitiation) *Peer {
|
||||
}
|
||||
|
||||
handshake := &peer.handshake
|
||||
if isZero(handshake.precomputedStaticStatic[:]) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// verify identity
|
||||
|
||||
var timestamp tai64n.Timestamp
|
||||
var key [chacha20poly1305.KeySize]byte
|
||||
|
||||
handshake.mutex.RLock()
|
||||
|
||||
if isZero(handshake.precomputedStaticStatic[:]) {
|
||||
handshake.mutex.RUnlock()
|
||||
return nil
|
||||
}
|
||||
KDF2(
|
||||
&chainKey,
|
||||
&key,
|
||||
chainKey[:],
|
||||
handshake.precomputedStaticStatic[:],
|
||||
)
|
||||
aead, _ := chacha20poly1305.New(key[:])
|
||||
aead, _ = chacha20poly1305.New(key[:])
|
||||
_, err = aead.Open(timestamp[:0], ZeroNonce[:], msg.Timestamp[:], hash[:])
|
||||
if err != nil {
|
||||
handshake.mutex.RUnlock()
|
||||
|
||||
@@ -52,6 +52,15 @@ func (key *NoisePrivateKey) FromHex(src string) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (key *NoisePrivateKey) FromMaybeZeroHex(src string) (err error) {
|
||||
err = loadExactHex(key[:], src)
|
||||
if key.IsZero() {
|
||||
return
|
||||
}
|
||||
key.clamp()
|
||||
return
|
||||
}
|
||||
|
||||
func (key NoisePrivateKey) ToHex() string {
|
||||
return hex.EncodeToString(key[:])
|
||||
}
|
||||
|
||||
@@ -108,7 +108,6 @@ func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error) {
|
||||
handshake := &peer.handshake
|
||||
handshake.mutex.Lock()
|
||||
handshake.precomputedStaticStatic = device.staticIdentity.privateKey.sharedSecret(pk)
|
||||
ssIsZero := isZero(handshake.precomputedStaticStatic[:])
|
||||
handshake.remoteStatic = pk
|
||||
handshake.mutex.Unlock()
|
||||
|
||||
@@ -116,13 +115,9 @@ func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error) {
|
||||
|
||||
peer.endpoint = nil
|
||||
|
||||
// conditionally add
|
||||
// add
|
||||
|
||||
if !ssIsZero {
|
||||
device.peers.keyMap[pk] = peer
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// start peer
|
||||
|
||||
|
||||
@@ -515,11 +515,19 @@ func (device *Device) RoutineEncryption() {
|
||||
// pad content to multiple of 16
|
||||
|
||||
mtu := int(atomic.LoadInt32(&device.tun.mtu))
|
||||
lastUnit := len(elem.packet) % mtu
|
||||
var paddedSize int
|
||||
if mtu == 0 {
|
||||
paddedSize = (len(elem.packet) + PaddingMultiple - 1) & ^(PaddingMultiple - 1)
|
||||
} else {
|
||||
lastUnit := len(elem.packet)
|
||||
if lastUnit > mtu {
|
||||
lastUnit %= mtu
|
||||
}
|
||||
paddedSize := (lastUnit + PaddingMultiple - 1) & ^(PaddingMultiple - 1)
|
||||
if paddedSize > mtu {
|
||||
paddedSize = mtu
|
||||
}
|
||||
}
|
||||
for i := len(elem.packet); i < paddedSize; i++ {
|
||||
elem.packet = append(elem.packet, 0)
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ func (device *Device) IpcSetOperation(socket *bufio.Reader) *IPCError {
|
||||
switch key {
|
||||
case "private_key":
|
||||
var sk NoisePrivateKey
|
||||
err := sk.FromHex(value)
|
||||
err := sk.FromMaybeZeroHex(value)
|
||||
if err != nil {
|
||||
logError.Println("Failed to set private_key:", err)
|
||||
return &IPCError{ipc.IpcErrorInvalid}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
package device
|
||||
|
||||
const WireGuardGoVersion = "0.0.20200121"
|
||||
const WireGuardGoVersion = "0.0.20200320"
|
||||
|
||||
2
go.mod
2
go.mod
@@ -5,6 +5,6 @@ go 1.12
|
||||
require (
|
||||
golang.org/x/crypto v0.0.0-20191002192127-34f69633bfdc
|
||||
golang.org/x/net v0.0.0-20191003171128-d98b1b443823
|
||||
golang.org/x/sys v0.0.0-20191003212358-c178f38b412c
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527
|
||||
golang.org/x/text v0.3.2
|
||||
)
|
||||
|
||||
4
go.sum
4
go.sum
@@ -6,8 +6,8 @@ golang.org/x/net v0.0.0-20191003171128-d98b1b443823 h1:Ypyv6BNJh07T1pUSrehkLemqP
|
||||
golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191003212358-c178f38b412c h1:6Zx7DRlKXf79yfxuQ/7GqV3w2y7aDsk6bGg0MzF5RVU=
|
||||
golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
|
||||
@@ -85,7 +85,7 @@ func createNetlinkSocket() (int, error) {
|
||||
}
|
||||
saddr := &unix.SockaddrNetlink{
|
||||
Family: unix.AF_NETLINK,
|
||||
Groups: uint32((1 << (unix.RTNLGRP_LINK - 1)) | (1 << (unix.RTNLGRP_IPV4_IFADDR - 1)) | (1 << (unix.RTNLGRP_IPV6_IFADDR - 1))),
|
||||
Groups: unix.RTMGRP_LINK | unix.RTMGRP_IPV4_IFADDR | unix.RTMGRP_IPV6_IFADDR,
|
||||
}
|
||||
err = unix.Bind(sock, saddr)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user