wip: use atomic add for counters, added crypto

This commit is contained in:
jdl 2024-12-17 08:07:53 +01:00
parent a561dd3cce
commit bb379ec350
4 changed files with 158 additions and 9 deletions

View File

@ -4,9 +4,16 @@ import (
"log"
"net"
"net/netip"
"sync/atomic"
"vppn/fasttime"
)
// TODO:
type connRouter interface {
Lookup(byte) *peer
Mediator() *peer
}
type connWriter struct {
*net.UDPConn
localIP byte
@ -37,10 +44,8 @@ func (w *connWriter) WriteTo(remoteIP, packetType byte, data []byte) error {
return nil
}
w.counters[remoteIP]++
h := header{
Counter: w.counters[remoteIP],
Counter: atomic.AddUint64(&w.counters[remoteIP], 1),
SourceIP: w.localIP,
ViaIP: 0,
DestIP: remoteIP,

26
node/crypto.go Normal file
View File

@ -0,0 +1,26 @@
package node
import "golang.org/x/crypto/nacl/box"
// Encrypting the packet will also set the header's DataSize field.
func encryptPacket(h *header, sharedKey, data, out []byte) []byte {
h.DataSize = uint16(len(data) + box.Overhead)
out = out[:h.DataSize+headerSize]
h.Marshal(out)
box.SealAfterPrecomputation(out[headerSize:headerSize], data, (*[24]byte)(out[:headerSize]), (*[32]byte)(sharedKey))
return out
}
func decryptPacket(sharedKey, packetAndHeader, out []byte) (decrypted []byte, ok bool) {
return box.OpenAfterPrecomputation(
out[:0],
packetAndHeader[headerSize:],
(*[24]byte)(packetAndHeader[:headerSize]),
(*[32]byte)(sharedKey))
}
func computeSharedKey(peerPubKey, privKey []byte) []byte {
shared := [32]byte{}
box.Precompute(&shared, (*[32]byte)(peerPubKey), (*[32]byte)(privKey))
return shared[:]
}

121
node/crypto_test.go Normal file
View File

@ -0,0 +1,121 @@
package node
import (
"bytes"
"crypto/rand"
"reflect"
"testing"
"golang.org/x/crypto/nacl/box"
)
func TestEncryptDecryptPacket(t *testing.T) {
pubKey1, privKey1, err := box.GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
pubKey2, privKey2, err := box.GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
sharedEncKey := [32]byte{}
box.Precompute(&sharedEncKey, pubKey2, privKey1)
sharedDecKey := [32]byte{}
box.Precompute(&sharedDecKey, pubKey1, privKey2)
original := make([]byte, if_mtu-64)
rand.Read(original)
h := header{
Counter: 2893749238,
SourceIP: 5,
ViaIP: 8,
DestIP: 12,
PacketType: 32,
}
encrypted := make([]byte, bufferSize)
encrypted = encryptPacket(&h, sharedEncKey[:], original, encrypted)
decrypted := make([]byte, bufferSize)
var ok bool
decrypted, ok = decryptPacket(sharedDecKey[:], encrypted, decrypted)
if !ok {
t.Fatal(ok)
}
var h2 header
h2.Parse(encrypted)
if !reflect.DeepEqual(h, h2) {
t.Fatal(h, h2)
}
if !bytes.Equal(original, decrypted) {
t.Fatal("mismatch")
}
}
/*
func BenchmarkEncryptPacket(b *testing.B) {
_, privKey1, err := box.GenerateKey(rand.Reader)
if err != nil {
b.Fatal(err)
}
pubKey2, _, err := box.GenerateKey(rand.Reader)
if err != nil {
b.Fatal(err)
}
sharedEncKey := [32]byte{}
box.Precompute(&sharedEncKey, pubKey2, privKey1)
original := make([]byte, MTU)
rand.Read(original)
nonce := make([]byte, NONCE_SIZE)
rand.Read(nonce)
encrypted := make([]byte, BUFFER_SIZE)
for i := 0; i < b.N; i++ {
encrypted = encryptPacket(sharedEncKey[:], nonce, original, encrypted)
}
}
func BenchmarkDecryptPacket(b *testing.B) {
pubKey1, privKey1, err := box.GenerateKey(rand.Reader)
if err != nil {
b.Fatal(err)
}
pubKey2, privKey2, err := box.GenerateKey(rand.Reader)
if err != nil {
b.Fatal(err)
}
sharedEncKey := [32]byte{}
box.Precompute(&sharedEncKey, pubKey2, privKey1)
sharedDecKey := [32]byte{}
box.Precompute(&sharedDecKey, pubKey1, privKey2)
original := make([]byte, MTU)
rand.Read(original)
nonce := make([]byte, NONCE_SIZE)
rand.Read(nonce)
encrypted := make([]byte, BUFFER_SIZE)
encrypted = encryptPacket(sharedEncKey[:], nonce, original, encrypted)
decrypted := make([]byte, MTU)
for i := 0; i < b.N; i++ {
decrypted, _ = decryptPacket(sharedDecKey[:], encrypted, decrypted)
}
}
*/

View File

@ -6,12 +6,9 @@ import (
)
type peer struct {
IP byte
// TODO: Version
Addr *netip.AddrPort
// TODO: ViaIP
// TODO: EncPubKey
// TODO: SignPrivKey
IP byte
Addr *netip.AddrPort // If we have direct connection, otherwise use mediator.
// TODO: SharedKey []byte
}
type peerRepo [256]*atomic.Pointer[peer]