mirror of
https://github.com/tim-beatham/smegmesh.git
synced 2024-12-12 17:41:08 +01:00
02dfd73e08
- Separated synchronisation calls into independent processes - Commented code for submission
109 lines
2.3 KiB
Go
109 lines
2.3 KiB
Go
package ip
|
|
|
|
// Generates a CGA see RFC 3972
|
|
// https://datatracker.ietf.org/doc/html/rfc3972
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/sha1"
|
|
"net"
|
|
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
)
|
|
|
|
const (
|
|
ModifierLength = 16
|
|
ZeroLength = 9
|
|
hash2Length = 57
|
|
hash1Length = 58
|
|
Hash2Prefix = 14
|
|
Hash1Prefix = 8
|
|
InterfaceIdLen = 8
|
|
)
|
|
|
|
// CGAParameters: parameters used to create a new cryotpgraphically generated
|
|
// address
|
|
type CgaParameters struct {
|
|
Modifier [ModifierLength]byte
|
|
// SubnetPrefix: prefix of the subnetwork
|
|
SubnetPrefix [2 * InterfaceIdLen]byte
|
|
// CollisionCount: total number of times we have atempted to generate a porefix
|
|
CollisionCount uint8
|
|
// PublicKey: WireGuard public key of our interface
|
|
PublicKey wgtypes.Key
|
|
// interfaceId: the generated interfaceId
|
|
interfaceId [2 * InterfaceIdLen]byte
|
|
// flag: represents whether or not an IP address has been generated
|
|
flag byte
|
|
}
|
|
|
|
func NewCga(key wgtypes.Key, collisionCount uint8, subnetPrefix [2 * InterfaceIdLen]byte) (*CgaParameters, error) {
|
|
var params CgaParameters
|
|
|
|
_, err := rand.Read(params.Modifier[:])
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
params.PublicKey = key
|
|
params.SubnetPrefix = subnetPrefix
|
|
params.CollisionCount = collisionCount
|
|
return ¶ms, nil
|
|
}
|
|
|
|
func (c *CgaParameters) generateHash1() []byte {
|
|
var byteVal [hash1Length]byte
|
|
|
|
for i := 0; i < ModifierLength; i++ {
|
|
byteVal[i] = c.Modifier[i]
|
|
}
|
|
|
|
for i := 0; i < wgtypes.KeyLen; i++ {
|
|
byteVal[ModifierLength+ZeroLength+i] = c.PublicKey[i]
|
|
}
|
|
|
|
byteVal[hash1Length-1] = c.CollisionCount
|
|
|
|
hash := sha1.Sum(byteVal[:])
|
|
return hash[:Hash1Prefix]
|
|
}
|
|
|
|
func clearBit(num, pos int) byte {
|
|
mask := ^(1 << pos)
|
|
result := num & mask
|
|
|
|
return byte(result)
|
|
}
|
|
|
|
func (c *CgaParameters) generateInterface() []byte {
|
|
hash1 := c.generateHash1()
|
|
|
|
var interfaceId []byte = make([]byte, InterfaceIdLen)
|
|
|
|
copy(interfaceId[:], hash1)
|
|
|
|
interfaceId[0] = clearBit(int(interfaceId[0]), 6)
|
|
interfaceId[0] = clearBit(int(interfaceId[1]), 7)
|
|
return interfaceId
|
|
}
|
|
|
|
func (c *CgaParameters) GetIP() net.IP {
|
|
if c.flag == 1 {
|
|
return c.interfaceId[:]
|
|
}
|
|
|
|
bytes := c.generateInterface()
|
|
|
|
for i := 0; i < InterfaceIdLen; i++ {
|
|
c.interfaceId[i] = c.SubnetPrefix[i]
|
|
}
|
|
|
|
for i := InterfaceIdLen; i < 2*InterfaceIdLen; i++ {
|
|
c.interfaceId[i] = bytes[i-8]
|
|
}
|
|
|
|
c.flag = 1
|
|
return c.interfaceId[:]
|
|
}
|