aboutsummaryrefslogtreecommitdiffstats
path: root/src/macs.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/macs.go')
-rw-r--r--src/macs.go270
1 files changed, 0 insertions, 270 deletions
diff --git a/src/macs.go b/src/macs.go
deleted file mode 100644
index d55e18f..0000000
--- a/src/macs.go
+++ /dev/null
@@ -1,270 +0,0 @@
-package main
-
-import (
- "crypto/hmac"
- "crypto/rand"
- "golang.org/x/crypto/blake2s"
- "net"
- "sync"
- "time"
-)
-
-type MACStateDevice struct {
- mutex sync.RWMutex
- refreshed time.Time
- secret [blake2s.Size]byte
- keyMAC1 [blake2s.Size]byte
- keyMAC2 [blake2s.Size]byte // TODO: Change to more descriptive size constant, rename to something.
-}
-
-type MACStatePeer struct {
- mutex sync.RWMutex
- cookieSet time.Time
- cookie [blake2s.Size128]byte
- lastMAC1Set bool
- lastMAC1 [blake2s.Size128]byte
- keyMAC1 [blake2s.Size]byte
- keyMAC2 [blake2s.Size]byte
-}
-
-/* Methods for verifing MAC fields
- * and creating/consuming cookies replies
- * (per device)
- */
-
-func (state *MACStateDevice) Init(pk NoisePublicKey) {
- state.mutex.Lock()
- defer state.mutex.Unlock()
-
- func() {
- hsh, _ := blake2s.New256(nil)
- hsh.Write([]byte(WGLabelMAC1))
- hsh.Write(pk[:])
- hsh.Sum(state.keyMAC1[:0])
- }()
-
- func() {
- hsh, _ := blake2s.New256(nil)
- hsh.Write([]byte(WGLabelCookie))
- hsh.Write(pk[:])
- hsh.Sum(state.keyMAC2[:0])
- }()
-
- state.refreshed = time.Time{}
-}
-
-func (state *MACStateDevice) CheckMAC1(msg []byte) bool {
- size := len(msg)
- startMac1 := size - (blake2s.Size128 * 2)
- startMac2 := size - blake2s.Size128
-
- var mac1 [blake2s.Size128]byte
- func() {
- mac, _ := blake2s.New128(state.keyMAC1[:])
- mac.Write(msg[:startMac1])
- mac.Sum(mac1[:0])
- }()
-
- return hmac.Equal(mac1[:], msg[startMac1:startMac2])
-}
-
-func (state *MACStateDevice) CheckMAC2(msg []byte, addr *net.UDPAddr) bool {
- state.mutex.RLock()
- defer state.mutex.RUnlock()
-
- if time.Now().Sub(state.refreshed) > CookieRefreshTime {
- return false
- }
-
- // derive cookie key
-
- var cookie [blake2s.Size128]byte
- func() {
- port := [2]byte{byte(addr.Port >> 8), byte(addr.Port)}
- mac, _ := blake2s.New128(state.secret[:])
- mac.Write(addr.IP)
- mac.Write(port[:]) // TODO: Be faster and more platform dependent?
- mac.Sum(cookie[:0])
- }()
-
- // calculate mac of packet
-
- start := len(msg) - blake2s.Size128
-
- var mac2 [blake2s.Size128]byte
- func() {
- mac, _ := blake2s.New128(cookie[:])
- mac.Write(msg[:start])
- mac.Sum(mac2[:0])
- }()
-
- return hmac.Equal(mac2[:], msg[start:])
-}
-
-func (device *Device) CreateMessageCookieReply(
- msg []byte, receiver uint32, addr *net.UDPAddr,
-) (*MessageCookieReply, error) {
-
- state := &device.mac
- state.mutex.RLock()
-
- // refresh cookie secret
-
- if time.Now().Sub(state.refreshed) > CookieRefreshTime {
- state.mutex.RUnlock()
- state.mutex.Lock()
- _, err := rand.Read(state.secret[:])
- if err != nil {
- state.mutex.Unlock()
- return nil, err
- }
- state.refreshed = time.Now()
- state.mutex.Unlock()
- state.mutex.RLock()
- }
-
- // derive cookie key
-
- var cookie [blake2s.Size128]byte
- func() {
- port := [2]byte{byte(addr.Port >> 8), byte(addr.Port)}
- mac, _ := blake2s.New128(state.secret[:])
- mac.Write(addr.IP)
- mac.Write(port[:]) // TODO: Do whatever we did above
- mac.Sum(cookie[:0])
- }()
-
- // encrypt cookie
-
- size := len(msg)
-
- startMac1 := size - (blake2s.Size128 * 2)
- startMac2 := size - blake2s.Size128
-
- mac1 := msg[startMac1:startMac2]
-
- reply := new(MessageCookieReply)
- reply.Type = MessageCookieReplyType
- reply.Receiver = receiver
- _, err := rand.Read(reply.Nonce[:])
- if err != nil {
- state.mutex.RUnlock()
- return nil, err
- }
-
- XChaCha20Poly1305Encrypt(
- reply.Cookie[:0],
- &reply.Nonce,
- cookie[:],
- mac1,
- &state.keyMAC2,
- )
-
- state.mutex.RUnlock()
- return reply, nil
-}
-
-func (device *Device) ConsumeMessageCookieReply(msg *MessageCookieReply) bool {
-
- if msg.Type != MessageCookieReplyType {
- return false
- }
-
- // lookup peer
-
- lookup := device.indices.Lookup(msg.Receiver)
- if lookup.handshake == nil {
- return false
- }
-
- // decrypt and store cookie
-
- var cookie [blake2s.Size128]byte
- state := &lookup.peer.mac
-
- state.mutex.Lock()
- defer state.mutex.Unlock()
-
- if !state.lastMAC1Set {
- return false
- }
-
- _, err := XChaCha20Poly1305Decrypt(
- cookie[:0],
- &msg.Nonce,
- msg.Cookie[:],
- state.lastMAC1[:],
- &state.keyMAC2,
- )
-
- if err != nil {
- return false
- }
-
- state.cookieSet = time.Now()
- state.cookie = cookie
- return true
-}
-
-/* Methods for generating the MAC fields
- * (per peer)
- */
-
-func (state *MACStatePeer) Init(pk NoisePublicKey) {
- state.mutex.Lock()
- defer state.mutex.Unlock()
-
- func() {
- hsh, _ := blake2s.New256(nil)
- hsh.Write([]byte(WGLabelMAC1))
- hsh.Write(pk[:])
- hsh.Sum(state.keyMAC1[:0])
- }()
-
- func() {
- hsh, _ := blake2s.New256(nil)
- hsh.Write([]byte(WGLabelCookie))
- hsh.Write(pk[:])
- hsh.Sum(state.keyMAC2[:0])
- }()
-
- state.cookieSet = time.Time{} // never
-}
-
-func (state *MACStatePeer) AddMacs(msg []byte) {
- size := len(msg)
-
- startMac1 := size - (blake2s.Size128 * 2)
- startMac2 := size - blake2s.Size128
-
- mac1 := msg[startMac1 : startMac1+blake2s.Size128]
- mac2 := msg[startMac2 : startMac2+blake2s.Size128]
-
- state.mutex.Lock()
- defer state.mutex.Unlock()
-
- // set mac1
-
- func() {
- mac, _ := blake2s.New128(state.keyMAC1[:])
- mac.Write(msg[:startMac1])
- mac.Sum(mac1[:0])
- }()
- copy(state.lastMAC1[:], mac1)
- state.lastMAC1Set = true
-
- // set mac2
-
- if state.cookieSet.IsZero() {
- return
- }
- if time.Now().Sub(state.cookieSet) > CookieRefreshTime {
- state.cookieSet = time.Time{}
- return
- }
- func() {
- mac, _ := blake2s.New128(state.cookie[:])
- mac.Write(msg[:startMac2])
- mac.Sum(mac2[:0])
- }()
-}