71 lines
2.8 KiB
Go
71 lines
2.8 KiB
Go
package shared
|
||
|
||
import "encoding/binary"
|
||
|
||
const PROTO_VERSION uint16 = 1
|
||
|
||
// pubKey - public key generated by the client
|
||
// privKey - private key generated by the client
|
||
// serverPubKey - pre-shared public key used for authenticating the server
|
||
// serverPrivKey - long-term private key used for authenticating the server
|
||
// sessionKey - per-peer symmetrical key derived via HPKE for encrypting unicast packets
|
||
// multicastKey - key shared between everyone for encrypting multicast packets
|
||
// authSecret - secret assigned to a client for authenticating subsequent requests
|
||
|
||
// SYM = XChaCha20‑Poly1305 with nonce prepended
|
||
// HMAC = HMAC-SHA-256
|
||
// hpke = HPKE(MLKEM768X25519, ChaCha20Poly1305, HKDF-SHA-256)
|
||
// ds = ML-DSA
|
||
|
||
// packet format
|
||
// [ version - 2 bytes ] [ type - 2 bytes ] [ payload - see below ]
|
||
const (
|
||
_ uint16 = iota
|
||
// (client -> server) requests a challenge to prove the ownership of the privKey
|
||
// [ pubKey - 1216 bytes ]
|
||
REQ_GET_CHALLENGE
|
||
// (server -> client) provides an encrypted authSecret
|
||
// [ ds.Sign(serverPrivKey, rest) - 2420 bytes ] [ HPKE(pubKey, authSecret) - 1168 bytes ]
|
||
RESP_GET_CHALLENGE
|
||
// (client -> server) requests an IP
|
||
// [ HMAC(authSecret, pubKey) - 32 bytes ] [ pubKey - 1216 bytes ]
|
||
REQ_REGISTER
|
||
// (server -> client) returns the assigned IP and encrypted multicastKey
|
||
// [ ds.Sign(serverPrivKey, rest) - 2420 bytes ] [ ip - 16 bytes ] [ hpke.Seal(pubKey, multicastKey) - 1168 bytes ]
|
||
RESP_REGISTER
|
||
// (client -> server) requests peer's pubKey from the server for encapsulation
|
||
// [ ip - 16 bytes ]
|
||
REQ_GET_PUBKEY
|
||
// (server -> client) provides requested pubKey
|
||
// [ ds.Sign(serverPrivKey, rest) - 2420 bytes ] [ ip - 16 bytes ] [ pubKey - 1216 bytes ]
|
||
RESP_GET_PUBKEY
|
||
// (client -> server -> client2) establishes a sessionKey with another peer
|
||
// [ HMAC(authSecret, rest) - 32 bytes ] [ destIP - 16 bytes ] [ srcIP - 16 bytes ] [ hpke.Encap(pubKey) - 1120 bytes ]
|
||
REQ_ESTABLISH
|
||
// (client2 -> server -> client) acknowledges the sessionKey was established
|
||
// [ HMAC(authSecret, rest) - 32 bytes ] [ destIP - 16 bytes ] [ srcIP - 16 bytes ]
|
||
RESP_ESTABLISH
|
||
// (client -> server -> client2) relays an encrypted packet to a specified peer
|
||
// [ HMAC(authSecret, rest) - 32 bytes ] [ destIP - 16 bytes ] [ srcIP - 16 bytes ] [ SYM(sessionKey, pkt) ]
|
||
UNICAST_PKT
|
||
// (client -> server -> *) broadcasts an encrypted packet
|
||
// [ HMAC(authSecret, rest) - 32 bytes ] [ SYM(multicastKey, pkt) ]
|
||
BROADCAST_PKT
|
||
)
|
||
|
||
func BuildPkt(pktType uint16, parts ...[]byte) []byte {
|
||
var total int
|
||
for _, p := range parts {
|
||
total += len(p)
|
||
}
|
||
|
||
out := make([]byte, 4, 4+total)
|
||
binary.LittleEndian.PutUint16(out[0:], PROTO_VERSION)
|
||
binary.LittleEndian.PutUint16(out[2:], pktType)
|
||
|
||
for _, p := range parts {
|
||
out = append(out, p...)
|
||
}
|
||
return out
|
||
}
|