noise: unify zero checking of ecdh
This commit is contained in:
parent
b33219c2cf
commit
4739708ca4
|
@ -240,9 +240,6 @@ func (device *Device) SetPrivateKey(sk NoisePrivateKey) error {
|
||||||
for _, peer := range device.peers.keyMap {
|
for _, peer := range device.peers.keyMap {
|
||||||
handshake := &peer.handshake
|
handshake := &peer.handshake
|
||||||
handshake.precomputedStaticStatic = device.staticIdentity.privateKey.sharedSecret(handshake.remoteStatic)
|
handshake.precomputedStaticStatic = device.staticIdentity.privateKey.sharedSecret(handshake.remoteStatic)
|
||||||
if isZero(handshake.precomputedStaticStatic[:]) {
|
|
||||||
panic("an invalid peer public key made it into the configuration")
|
|
||||||
}
|
|
||||||
expiredPeers = append(expiredPeers, peer)
|
expiredPeers = append(expiredPeers, peer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (device *Device) CreateMessageInitiation(peer *Peer) (*MessageInitiation, error) {
|
func (device *Device) CreateMessageInitiation(peer *Peer) (*MessageInitiation, error) {
|
||||||
|
var errZeroECDHResult = errors.New("ECDH returned all zeros")
|
||||||
|
|
||||||
device.staticIdentity.RLock()
|
device.staticIdentity.RLock()
|
||||||
defer device.staticIdentity.RUnlock()
|
defer device.staticIdentity.RUnlock()
|
||||||
|
@ -162,12 +163,7 @@ func (device *Device) CreateMessageInitiation(peer *Peer) (*MessageInitiation, e
|
||||||
handshake.mutex.Lock()
|
handshake.mutex.Lock()
|
||||||
defer handshake.mutex.Unlock()
|
defer handshake.mutex.Unlock()
|
||||||
|
|
||||||
if isZero(handshake.precomputedStaticStatic[:]) {
|
|
||||||
return nil, errors.New("static shared secret is zero")
|
|
||||||
}
|
|
||||||
|
|
||||||
// create ephemeral key
|
// create ephemeral key
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
handshake.hash = InitialHash
|
handshake.hash = InitialHash
|
||||||
handshake.chainKey = InitialChainKey
|
handshake.chainKey = InitialChainKey
|
||||||
|
@ -176,56 +172,53 @@ func (device *Device) CreateMessageInitiation(peer *Peer) (*MessageInitiation, e
|
||||||
return nil, err
|
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[:])
|
handshake.mixHash(handshake.remoteStatic[:])
|
||||||
|
|
||||||
msg := MessageInitiation{
|
msg := MessageInitiation{
|
||||||
Type: MessageInitiationType,
|
Type: MessageInitiationType,
|
||||||
Ephemeral: handshake.localEphemeral.publicKey(),
|
Ephemeral: handshake.localEphemeral.publicKey(),
|
||||||
Sender: handshake.localIndex,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handshake.mixKey(msg.Ephemeral[:])
|
handshake.mixKey(msg.Ephemeral[:])
|
||||||
handshake.mixHash(msg.Ephemeral[:])
|
handshake.mixHash(msg.Ephemeral[:])
|
||||||
|
|
||||||
// encrypt static key
|
// encrypt static key
|
||||||
|
ss := handshake.localEphemeral.sharedSecret(handshake.remoteStatic)
|
||||||
func() {
|
if isZero(ss[:]) {
|
||||||
var key [chacha20poly1305.KeySize]byte
|
return nil, errZeroECDHResult
|
||||||
ss := handshake.localEphemeral.sharedSecret(handshake.remoteStatic)
|
}
|
||||||
KDF2(
|
var key [chacha20poly1305.KeySize]byte
|
||||||
&handshake.chainKey,
|
KDF2(
|
||||||
&key,
|
&handshake.chainKey,
|
||||||
handshake.chainKey[:],
|
&key,
|
||||||
ss[:],
|
handshake.chainKey[:],
|
||||||
)
|
ss[:],
|
||||||
aead, _ := chacha20poly1305.New(key[:])
|
)
|
||||||
aead.Seal(msg.Static[:0], ZeroNonce[:], device.staticIdentity.publicKey[:], handshake.hash[:])
|
aead, _ := chacha20poly1305.New(key[:])
|
||||||
}()
|
aead.Seal(msg.Static[:0], ZeroNonce[:], device.staticIdentity.publicKey[:], handshake.hash[:])
|
||||||
handshake.mixHash(msg.Static[:])
|
handshake.mixHash(msg.Static[:])
|
||||||
|
|
||||||
// encrypt timestamp
|
// encrypt timestamp
|
||||||
|
if isZero(handshake.precomputedStaticStatic[:]) {
|
||||||
|
return nil, errZeroECDHResult
|
||||||
|
}
|
||||||
|
KDF2(
|
||||||
|
&handshake.chainKey,
|
||||||
|
&key,
|
||||||
|
handshake.chainKey[:],
|
||||||
|
handshake.precomputedStaticStatic[:],
|
||||||
|
)
|
||||||
timestamp := tai64n.Now()
|
timestamp := tai64n.Now()
|
||||||
func() {
|
aead, _ = chacha20poly1305.New(key[:])
|
||||||
var key [chacha20poly1305.KeySize]byte
|
aead.Seal(msg.Timestamp[:0], ZeroNonce[:], timestamp[:], handshake.hash[:])
|
||||||
KDF2(
|
|
||||||
&handshake.chainKey,
|
// assign index
|
||||||
&key,
|
device.indexTable.Delete(handshake.localIndex)
|
||||||
handshake.chainKey[:],
|
msg.Sender, err = device.indexTable.NewIndexForHandshake(peer, handshake)
|
||||||
handshake.precomputedStaticStatic[:],
|
if err != nil {
|
||||||
)
|
return nil, err
|
||||||
aead, _ := chacha20poly1305.New(key[:])
|
}
|
||||||
aead.Seal(msg.Timestamp[:0], ZeroNonce[:], timestamp[:], handshake.hash[:])
|
handshake.localIndex = msg.Sender
|
||||||
}()
|
|
||||||
|
|
||||||
handshake.mixHash(msg.Timestamp[:])
|
handshake.mixHash(msg.Timestamp[:])
|
||||||
handshake.state = HandshakeInitiationCreated
|
handshake.state = HandshakeInitiationCreated
|
||||||
|
@ -250,16 +243,16 @@ func (device *Device) ConsumeMessageInitiation(msg *MessageInitiation) *Peer {
|
||||||
mixKey(&chainKey, &InitialChainKey, msg.Ephemeral[:])
|
mixKey(&chainKey, &InitialChainKey, msg.Ephemeral[:])
|
||||||
|
|
||||||
// decrypt static key
|
// decrypt static key
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var peerPK NoisePublicKey
|
var peerPK NoisePublicKey
|
||||||
func() {
|
var key [chacha20poly1305.KeySize]byte
|
||||||
var key [chacha20poly1305.KeySize]byte
|
ss := device.staticIdentity.privateKey.sharedSecret(msg.Ephemeral)
|
||||||
ss := device.staticIdentity.privateKey.sharedSecret(msg.Ephemeral)
|
if isZero(ss[:]) {
|
||||||
KDF2(&chainKey, &key, chainKey[:], ss[:])
|
return nil
|
||||||
aead, _ := chacha20poly1305.New(key[:])
|
}
|
||||||
_, err = aead.Open(peerPK[:0], ZeroNonce[:], msg.Static[:], hash[:])
|
KDF2(&chainKey, &key, chainKey[:], ss[:])
|
||||||
}()
|
aead, _ := chacha20poly1305.New(key[:])
|
||||||
|
_, err = aead.Open(peerPK[:0], ZeroNonce[:], msg.Static[:], hash[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -273,23 +266,24 @@ func (device *Device) ConsumeMessageInitiation(msg *MessageInitiation) *Peer {
|
||||||
}
|
}
|
||||||
|
|
||||||
handshake := &peer.handshake
|
handshake := &peer.handshake
|
||||||
if isZero(handshake.precomputedStaticStatic[:]) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify identity
|
// verify identity
|
||||||
|
|
||||||
var timestamp tai64n.Timestamp
|
var timestamp tai64n.Timestamp
|
||||||
var key [chacha20poly1305.KeySize]byte
|
|
||||||
|
|
||||||
handshake.mutex.RLock()
|
handshake.mutex.RLock()
|
||||||
|
|
||||||
|
if isZero(handshake.precomputedStaticStatic[:]) {
|
||||||
|
handshake.mutex.RUnlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
KDF2(
|
KDF2(
|
||||||
&chainKey,
|
&chainKey,
|
||||||
&key,
|
&key,
|
||||||
chainKey[:],
|
chainKey[:],
|
||||||
handshake.precomputedStaticStatic[:],
|
handshake.precomputedStaticStatic[:],
|
||||||
)
|
)
|
||||||
aead, _ := chacha20poly1305.New(key[:])
|
aead, _ = chacha20poly1305.New(key[:])
|
||||||
_, err = aead.Open(timestamp[:0], ZeroNonce[:], msg.Timestamp[:], hash[:])
|
_, err = aead.Open(timestamp[:0], ZeroNonce[:], msg.Timestamp[:], hash[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handshake.mutex.RUnlock()
|
handshake.mutex.RUnlock()
|
||||||
|
|
|
@ -108,7 +108,6 @@ func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error) {
|
||||||
handshake := &peer.handshake
|
handshake := &peer.handshake
|
||||||
handshake.mutex.Lock()
|
handshake.mutex.Lock()
|
||||||
handshake.precomputedStaticStatic = device.staticIdentity.privateKey.sharedSecret(pk)
|
handshake.precomputedStaticStatic = device.staticIdentity.privateKey.sharedSecret(pk)
|
||||||
ssIsZero := isZero(handshake.precomputedStaticStatic[:])
|
|
||||||
handshake.remoteStatic = pk
|
handshake.remoteStatic = pk
|
||||||
handshake.mutex.Unlock()
|
handshake.mutex.Unlock()
|
||||||
|
|
||||||
|
@ -116,13 +115,9 @@ func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error) {
|
||||||
|
|
||||||
peer.endpoint = nil
|
peer.endpoint = nil
|
||||||
|
|
||||||
// conditionally add
|
// add
|
||||||
|
|
||||||
if !ssIsZero {
|
device.peers.keyMap[pk] = peer
|
||||||
device.peers.keyMap[pk] = peer
|
|
||||||
} else {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// start peer
|
// start peer
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue