udp: Rotate connection ID generation IVs every hour

This commit is contained in:
Justin Li
2015-02-20 15:38:27 -05:00
parent afb22c3df6
commit 4c3cd6cc0a
4 changed files with 102 additions and 33 deletions

View File

@@ -5,31 +5,37 @@
package udp
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
)
var connectionKey, connectionIV []byte
type ConnectionIDGenerator struct {
iv, iv2 []byte
block cipher.Block
}
func InitConnectionIDEncryption() error {
connectionKey = make([]byte, 16)
_, err := rand.Read(connectionKey)
func (g *ConnectionIDGenerator) Init() error {
key := make([]byte, 16)
_, err := rand.Read(key)
if err != nil {
return err
}
connectionIV = make([]byte, 16)
_, err = rand.Read(connectionIV)
return err
}
func GenerateConnectionID(ip []byte) []byte {
block, err := aes.NewCipher(connectionKey)
g.block, err = aes.NewCipher(key)
if err != nil {
panic(err)
return err
}
return g.NewIV()
}
func (g *ConnectionIDGenerator) Generate(ip []byte) []byte {
return g.generate(ip, g.iv)
}
func (g *ConnectionIDGenerator) generate(ip []byte, iv []byte) []byte {
if len(ip) > 16 {
panic("IP larger than 16 bytes")
}
@@ -39,7 +45,7 @@ func GenerateConnectionID(ip []byte) []byte {
}
ct := make([]byte, 16)
stream := cipher.NewCFBDecrypter(block, connectionIV)
stream := cipher.NewCFBDecrypter(g.block, iv)
stream.XORKeyStream(ct, ip)
for i := len(ip) - 1; i >= 8; i-- {
@@ -49,6 +55,28 @@ func GenerateConnectionID(ip []byte) []byte {
return ct[:8]
}
func init() {
InitConnectionIDEncryption()
func (g *ConnectionIDGenerator) Matches(id []byte, ip []byte) bool {
if expected := g.generate(ip, g.iv); bytes.Equal(id, expected) {
return true
}
if iv2 := g.iv2; iv2 != nil {
if expected := g.generate(ip, iv2); bytes.Equal(id, expected) {
return true
}
}
return false
}
func (g *ConnectionIDGenerator) NewIV() error {
newiv := make([]byte, 16)
if _, err := rand.Read(newiv); err != nil {
return err
}
g.iv2 = g.iv
g.iv = newiv
return nil
}