diff --git a/device/noise-protocol.go b/device/noise-protocol.go index 5cf1702..54da936 100644 --- a/device/noise-protocol.go +++ b/device/noise-protocol.go @@ -14,7 +14,6 @@ import ( "golang.org/x/crypto/blake2s" "golang.org/x/crypto/chacha20poly1305" - "golang.org/x/crypto/poly1305" "golang.zx2c4.com/wireguard/tai64n" ) @@ -65,7 +64,7 @@ const ( MessageResponseSize = 92 // size of response message MessageCookieReplySize = 64 // size of cookie reply message MessageTransportHeaderSize = 16 // size of data preceding content in transport message - MessageTransportSize = MessageTransportHeaderSize + poly1305.TagSize // size of empty transport + MessageTransportSize = MessageTransportHeaderSize // size of empty transport (no encryption tag) MessageKeepaliveSize = MessageTransportSize // size of keepalive MessageHandshakeSize = MessageInitiationSize // size of largest handshake related message ) @@ -86,8 +85,8 @@ type MessageInitiation struct { Type uint32 Sender uint32 Ephemeral NoisePublicKey - Static [NoisePublicKeySize + poly1305.TagSize]byte - Timestamp [tai64n.TimestampSize + poly1305.TagSize]byte + Static [NoisePublicKeySize + Poly1305TagSize]byte + Timestamp [tai64n.TimestampSize + Poly1305TagSize]byte MAC1 [blake2s.Size128]byte MAC2 [blake2s.Size128]byte } @@ -97,7 +96,7 @@ type MessageResponse struct { Sender uint32 Receiver uint32 Ephemeral NoisePublicKey - Empty [poly1305.TagSize]byte + Empty [Poly1305TagSize]byte MAC1 [blake2s.Size128]byte MAC2 [blake2s.Size128]byte } @@ -113,7 +112,7 @@ type MessageCookieReply struct { Type uint32 Receiver uint32 Nonce [chacha20poly1305.NonceSizeX]byte - Cookie [blake2s.Size128 + poly1305.TagSize]byte + Cookie [blake2s.Size128 + Poly1305TagSize]byte } var errMessageLengthMismatch = errors.New("message length mismatch") @@ -615,27 +614,13 @@ func (peer *Peer) BeginSymmetricSession() error { handshake.mutex.Lock() defer handshake.mutex.Unlock() - // derive keys + // determine initiator role var isInitiator bool - var sendKey [chacha20poly1305.KeySize]byte - var recvKey [chacha20poly1305.KeySize]byte if handshake.state == handshakeResponseConsumed { - KDF2( - &sendKey, - &recvKey, - handshake.chainKey[:], - nil, - ) isInitiator = true } else if handshake.state == handshakeResponseCreated { - KDF2( - &recvKey, - &sendKey, - handshake.chainKey[:], - nil, - ) isInitiator = false } else { return fmt.Errorf("invalid state for keypair derivation: %v", handshake.state) @@ -644,18 +629,15 @@ func (peer *Peer) BeginSymmetricSession() error { // zero handshake setZero(handshake.chainKey[:]) - setZero(handshake.hash[:]) // Doesn't necessarily need to be zeroed. Could be used for something interesting down the line. + setZero(handshake.hash[:]) setZero(handshake.localEphemeral[:]) peer.handshake.state = handshakeZeroed - // create AEAD instances + // create keypair without encryption keypair := new(Keypair) - keypair.send, _ = chacha20poly1305.New(sendKey[:]) - keypair.receive, _ = chacha20poly1305.New(recvKey[:]) - - setZero(sendKey[:]) - setZero(recvKey[:]) + keypair.send = nil // no encryption + keypair.receive = nil // no decryption keypair.created = time.Now() keypair.replayFilter.Reset() diff --git a/device/noise-types.go b/device/noise-types.go index 41c944e..da6e411 100644 --- a/device/noise-types.go +++ b/device/noise-types.go @@ -15,6 +15,7 @@ const ( NoisePublicKeySize = 32 NoisePrivateKeySize = 32 NoisePresharedKeySize = 32 + Poly1305TagSize = 16 // Size of Poly1305 authentication tag ) type ( diff --git a/device/receive.go b/device/receive.go index 1392957..4fdcbb5 100644 --- a/device/receive.go +++ b/device/receive.go @@ -12,7 +12,6 @@ import ( "sync" "time" - "golang.org/x/crypto/chacha20poly1305" "golang.org/x/net/ipv4" "golang.org/x/net/ipv6" "golang.zx2c4.com/wireguard/conn" @@ -236,8 +235,6 @@ func (device *Device) RoutineReceiveIncoming(maxBatchSize int, recv conn.Receive } func (device *Device) RoutineDecryption(id int) { - var nonce [chacha20poly1305.NonceSize]byte - defer device.log.Verbosef("Routine: decryption worker %d - stopped", id) device.log.Verbosef("Routine: decryption worker %d - started", id) @@ -247,20 +244,9 @@ func (device *Device) RoutineDecryption(id int) { counter := elem.packet[MessageTransportOffsetCounter:MessageTransportOffsetContent] content := elem.packet[MessageTransportOffsetContent:] - // decrypt and release to consumer - var err error + // pass through content without decryption elem.counter = binary.LittleEndian.Uint64(counter) - // copy counter to nonce - binary.LittleEndian.PutUint64(nonce[0x4:0xc], elem.counter) - elem.packet, err = elem.keypair.receive.Open( - content[:0], - nonce[:], - content, - nil, - ) - if err != nil { - elem.packet = nil - } + elem.packet = content } elemsContainer.Unlock() } diff --git a/device/send.go b/device/send.go index ff8f7da..12189e9 100644 --- a/device/send.go +++ b/device/send.go @@ -13,7 +13,6 @@ import ( "sync" "time" - "golang.org/x/crypto/chacha20poly1305" "golang.org/x/net/ipv4" "golang.org/x/net/ipv6" "golang.zx2c4.com/wireguard/conn" @@ -431,15 +430,12 @@ func calculatePaddingSize(packetSize, mtu int) int { return paddedSize - lastUnit } -/* Encrypts the elements in the queue +/* Processes the elements in the queue without encryption * and marks them for sequential consumption (by releasing the mutex) * * Obs. One instance per core */ func (device *Device) RoutineEncryption(id int) { - var paddingZeros [PaddingMultiple]byte - var nonce [chacha20poly1305.NonceSize]byte - defer device.log.Verbosef("Routine: encryption worker %d - stopped", id) device.log.Verbosef("Routine: encryption worker %d - started", id) @@ -456,19 +452,9 @@ func (device *Device) RoutineEncryption(id int) { binary.LittleEndian.PutUint32(fieldReceiver, elem.keypair.remoteIndex) binary.LittleEndian.PutUint64(fieldNonce, elem.nonce) - // pad content to multiple of 16 - paddingSize := calculatePaddingSize(len(elem.packet), int(device.tun.mtu.Load())) - elem.packet = append(elem.packet, paddingZeros[:paddingSize]...) - - // encrypt content and release to consumer - - binary.LittleEndian.PutUint64(nonce[4:], elem.nonce) - elem.packet = elem.keypair.send.Seal( - header, - nonce[:], - elem.packet, - nil, - ) + // append content directly to header without encryption + copy(elem.buffer[MessageTransportHeaderSize:], elem.packet) + elem.packet = elem.buffer[:MessageTransportHeaderSize+len(elem.packet)] } elemsContainer.Unlock() }