/*
GoVPN -- simple secure free software virtual private network daemon
-Copyright (C) 2014-2016 Sergey Matveev <stargrave@stargrave.org>
+Copyright (C) 2014-2017 Sergey Matveev <stargrave@stargrave.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
"sync/atomic"
"time"
- "github.com/dchest/blake2b"
+ "chacha20"
+ "golang.org/x/crypto/blake2b"
"golang.org/x/crypto/poly1305"
- "golang.org/x/crypto/salsa20"
)
const (
NonceSize = 8
NonceBucketSize = 256
TagSize = poly1305.TagSize
- // S20BS is Salsa20's internal blocksize in bytes
+ // S20BS is ChaCha20's internal blocksize in bytes
S20BS = 64
// Maximal amount of bytes transfered with single key (4 GiB)
MaxBytesPerKey uint64 = 1 << 32
func newNonces(key *[32]byte, i uint64) chan *[NonceSize]byte {
macKey := make([]byte, 32)
- salsa20.XORKeyStream(macKey, make([]byte, 32), make([]byte, 8), key)
- mac := blake2b.NewMAC(NonceSize, macKey)
+ chacha20.XORKeyStream(macKey, make([]byte, 32), new([16]byte), key)
+ mac, err := blake2b.New256(macKey)
+ if err != nil {
+ panic(err)
+ }
+ sum := make([]byte, mac.Size())
nonces := make(chan *[NonceSize]byte, NonceBucketSize*3)
go func() {
for {
buf := new([NonceSize]byte)
binary.BigEndian.PutUint64(buf[:], i)
mac.Write(buf[:])
- mac.Sum(buf[:0])
+ mac.Sum(sum[0:])
+ copy(buf[:], sum)
nonces <- buf
mac.Reset()
i += 2
bufR []byte
tagR *[TagSize]byte
keyAuthR *[SSize]byte
+ nonceR *[16]byte
pktSizeR int
// UDP-related
bufT []byte
tagT *[TagSize]byte
keyAuthT *[SSize]byte
+ nonceT *[16]byte
frameT []byte
noncesT chan *[NonceSize]byte
}
tagR: new([TagSize]byte),
tagT: new([TagSize]byte),
keyAuthR: new([SSize]byte),
+ nonceR: new([16]byte),
keyAuthT: new([SSize]byte),
+ nonceT: new([16]byte),
}
if isClient {
}
copy(p.frameT[len(p.frameT)-NonceSize:], (<-p.noncesT)[:])
var out []byte
+ copy(p.nonceT[8:], p.frameT[len(p.frameT)-NonceSize:])
if p.Encless {
var err error
- out, err = EnclessEncode(
- p.key,
- p.frameT[len(p.frameT)-NonceSize:],
- p.frameT[:len(p.frameT)-NonceSize],
- )
+ out, err = EnclessEncode(p.key, p.nonceT, p.frameT[:len(p.frameT)-NonceSize])
if err != nil {
panic(err)
}
out = append(out, p.frameT[len(p.frameT)-NonceSize:]...)
} else {
- salsa20.XORKeyStream(
+ chacha20.XORKeyStream(
p.bufT[:S20BS+len(p.frameT)-NonceSize],
p.bufT[:S20BS+len(p.frameT)-NonceSize],
- p.frameT[len(p.frameT)-NonceSize:],
+ p.nonceT,
p.key,
)
copy(p.keyAuthT[:], p.bufT[:SSize])
}
var out []byte
p.BusyR.Lock()
+ copy(p.nonceR[8:], data[len(data)-NonceSize:])
if p.Encless {
var err error
- out, err = EnclessDecode(
- p.key,
- data[len(data)-NonceSize:],
- data[:len(data)-NonceSize],
- )
+ out, err = EnclessDecode(p.key, p.nonceR, data[:len(data)-NonceSize])
if err != nil {
p.FramesUnauth++
p.BusyR.Unlock()
p.bufR[i] = 0
}
copy(p.bufR[S20BS:], data[TagSize:])
- salsa20.XORKeyStream(
+ chacha20.XORKeyStream(
p.bufR[:S20BS+len(data)-TagSize-NonceSize],
p.bufR[:S20BS+len(data)-TagSize-NonceSize],
- data[len(data)-NonceSize:],
+ p.nonceR,
p.key,
)
copy(p.keyAuthR[:], p.bufR[:SSize])