mirror of https://gogs.blitter.com/RLabs/xs
Some locks suggested by go race; bounds checks on chaff, rekey min secs
This commit is contained in:
parent
f30780b788
commit
397807cf9a
10
README.md
10
README.md
|
@ -63,16 +63,6 @@ In all releases prior to v0.9.3, absent a specific whitelist of algs to allow, t
|
||||||
As of release v0.9.3, the default when supplying no explicit KEX, cipher or HMAC algorithms to `xsd` results in *no* algs being accepted; so the admin must decide on a specific whitelist of algorithms.
|
As of release v0.9.3, the default when supplying no explicit KEX, cipher or HMAC algorithms to `xsd` results in *no* algs being accepted; so the admin must decide on a specific whitelist of algorithms.
|
||||||
***
|
***
|
||||||
|
|
||||||
***
|
|
||||||
**Experimental Session Crypto 'Remodulation' on Rekeying**
|
|
||||||
|
|
||||||
Support has been added for an experimental 'remodulation' of the active session cipher and hash algorithms
|
|
||||||
when a rekey is performed. This feature, only active if the `-R` option is specified by *both* server and
|
|
||||||
client, will cause the two sides to negotiate a (potentially) new cipher and hash algorithm as part of the rekeying (normal rekeying *without* 'remodulation' is on by default, with the interval optionally specified independently by client and server via the `-r` (note lowercase) option).
|
|
||||||
|
|
||||||
This experimental 'remodulation' is intended to inhibit a potential attacker's efforts to analyze session data, by reducing the usefulness of any distinguisher, presuming one exists, that may exist in one of the symmetric cipher algos used during a session. Note however, that if the initial KEM negotiation were broken and the attacker has recorded all following session traffic, they can still 'stay in sync' with the rekeys *and* algo remodulations, and be able to continue decrypting across session rekeys. (That is, this feature does not
|
|
||||||
add any security if the initial KEM exchange were broken.)
|
|
||||||
***
|
|
||||||
|
|
||||||
### Conn
|
### Conn
|
||||||
Calls to xsnet.Dial() and xsnet.Listen()/Accept() are generally the same as calls to the equivalents within the _net_ package; however upon connection a key exchange automatically occurs whereby client and server independently derive the same keying material, and all following traffic is secured by a symmetric encryption algorithm.
|
Calls to xsnet.Dial() and xsnet.Listen()/Accept() are generally the same as calls to the equivalents within the _net_ package; however upon connection a key exchange automatically occurs whereby client and server independently derive the same keying material, and all following traffic is secured by a symmetric encryption algorithm.
|
||||||
|
|
|
@ -127,7 +127,14 @@ const (
|
||||||
CONone = iota
|
CONone = iota
|
||||||
CORemodulateShields // if set, rekeying also reselects random cipher/hmac alg
|
CORemodulateShields // if set, rekeying also reselects random cipher/hmac alg
|
||||||
)
|
)
|
||||||
|
|
||||||
type COValue uint32
|
type COValue uint32
|
||||||
|
|
||||||
// Available HMACs for hkex.Conn
|
// Available HMACs for hkex.Conn
|
||||||
type CSHmacAlg uint32
|
type CSHmacAlg uint32
|
||||||
|
|
||||||
|
// Some bounds-checking consts
|
||||||
|
const (
|
||||||
|
REKEY_SECS_MIN = 1
|
||||||
|
CHAFF_FREQ_MSECS_MIN = 1
|
||||||
|
)
|
||||||
|
|
38
xsnet/net.go
38
xsnet/net.go
|
@ -1355,7 +1355,9 @@ func (hc *Conn) Read(b []byte) (n int, err error) {
|
||||||
// payloadBytes[0], payloadBytes[1], payloadBytes[2]))
|
// payloadBytes[0], payloadBytes[1], payloadBytes[2]))
|
||||||
rekeyData := payloadBytes
|
rekeyData := payloadBytes
|
||||||
if (hc.opts & CORemodulateShields) != 0 {
|
if (hc.opts & CORemodulateShields) != 0 {
|
||||||
|
hc.Lock()
|
||||||
hc.cipheropts = getNewStreamAlgs(rekeyData[0], rekeyData[1])
|
hc.cipheropts = getNewStreamAlgs(rekeyData[0], rekeyData[1])
|
||||||
|
hc.Unlock()
|
||||||
}
|
}
|
||||||
hc.r, hc.rm, err = hc.getStream(rekeyData)
|
hc.r, hc.rm, err = hc.getStream(rekeyData)
|
||||||
case CSOTermSize:
|
case CSOTermSize:
|
||||||
|
@ -1591,7 +1593,9 @@ func (hc *Conn) StartupChaff() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hc *Conn) ShutdownChaff() {
|
func (hc *Conn) ShutdownChaff() {
|
||||||
|
hc.Lock()
|
||||||
hc.chaff.shutdown = true
|
hc.chaff.shutdown = true
|
||||||
|
hc.Unlock()
|
||||||
log.Println("Chaffing SHUTDOWN")
|
log.Println("Chaffing SHUTDOWN")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1602,16 +1606,28 @@ func (hc *Conn) SetupChaff(msecsMin uint, msecsMax uint, szMax uint) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hc *Conn) ShutdownRekey() {
|
func (hc *Conn) ShutdownRekey() {
|
||||||
|
hc.Lock()
|
||||||
hc.rekey = 0
|
hc.rekey = 0
|
||||||
|
hc.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hc *Conn) RekeyHelper(intervalSecs uint) {
|
func (hc *Conn) RekeyHelper(intervalSecs uint) {
|
||||||
|
if intervalSecs < REKEY_SECS_MIN {
|
||||||
|
intervalSecs = REKEY_SECS_MIN
|
||||||
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
hc.Lock()
|
||||||
hc.rekey = intervalSecs
|
hc.rekey = intervalSecs
|
||||||
|
hc.Unlock()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if hc.rekey != 0 {
|
hc.Lock()
|
||||||
|
rekey := hc.rekey
|
||||||
|
hc.Unlock()
|
||||||
|
if rekey != 0 {
|
||||||
//logger.LogDebug(fmt.Sprintf("[rekeyHelper Loop]\n"))
|
//logger.LogDebug(fmt.Sprintf("[rekeyHelper Loop]\n"))
|
||||||
time.Sleep(time.Duration(hc.rekey) * time.Second)
|
time.Sleep(time.Duration(rekey) * time.Second)
|
||||||
|
|
||||||
// Send rekey to other end
|
// Send rekey to other end
|
||||||
rekeyData := make([]byte, 64)
|
rekeyData := make([]byte, 64)
|
||||||
|
@ -1640,11 +1656,21 @@ func (hc *Conn) RekeyHelper(intervalSecs uint) {
|
||||||
|
|
||||||
// Helper routine to spawn a chaffing goroutine for each Conn
|
// Helper routine to spawn a chaffing goroutine for each Conn
|
||||||
func (hc *Conn) chaffHelper() {
|
func (hc *Conn) chaffHelper() {
|
||||||
|
// Enforce bounds on chaff frequency and pkt size
|
||||||
|
hc.Lock()
|
||||||
|
if hc.chaff.msecsMin < CHAFF_FREQ_MSECS_MIN {
|
||||||
|
hc.chaff.msecsMin = CHAFF_FREQ_MSECS_MIN
|
||||||
|
}
|
||||||
|
hc.Unlock()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
var nextDuration int
|
var nextDuration int
|
||||||
for {
|
for {
|
||||||
//logger.LogDebug(fmt.Sprintf("[chaffHelper Loop]\n"))
|
//logger.LogDebug(fmt.Sprintf("[chaffHelper Loop]\n"))
|
||||||
if !hc.chaff.shutdown {
|
hc.Lock()
|
||||||
|
shutdown := hc.chaff.shutdown
|
||||||
|
hc.Unlock()
|
||||||
|
if !shutdown {
|
||||||
var bufTmp []byte
|
var bufTmp []byte
|
||||||
bufTmp = make([]byte, rand.Intn(int(hc.chaff.szMax)))
|
bufTmp = make([]byte, rand.Intn(int(hc.chaff.szMax)))
|
||||||
min := int(hc.chaff.msecsMin)
|
min := int(hc.chaff.msecsMin)
|
||||||
|
@ -1655,7 +1681,9 @@ func (hc *Conn) chaffHelper() {
|
||||||
//logger.LogDebug("[-chaffHelper]")
|
//logger.LogDebug("[-chaffHelper]")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("[ *** error - chaffHelper shutting down *** ]")
|
log.Println("[ *** error - chaffHelper shutting down *** ]")
|
||||||
|
hc.Lock()
|
||||||
hc.chaff.shutdown = true
|
hc.chaff.shutdown = true
|
||||||
|
hc.Unlock()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1679,7 +1707,9 @@ func (hc *Conn) ShutdownKeepAlive() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hc *Conn) ResetKeepAlive() {
|
func (hc *Conn) ResetKeepAlive() {
|
||||||
|
hc.Lock()
|
||||||
hc.keepalive = 3
|
hc.keepalive = 3
|
||||||
|
hc.Unlock()
|
||||||
log.Println("KeepAlive RESET")
|
log.Println("KeepAlive RESET")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1698,7 +1728,9 @@ func (hc *Conn) keepaliveHelper() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
time.Sleep(time.Duration(nextDuration) * time.Millisecond)
|
time.Sleep(time.Duration(nextDuration) * time.Millisecond)
|
||||||
|
hc.Lock()
|
||||||
hc.keepalive -= 1
|
hc.keepalive -= 1
|
||||||
|
hc.Unlock()
|
||||||
//logger.LogDebug(fmt.Sprintf("[keepAlive is now %d]\n", hc.keepalive))
|
//logger.LogDebug(fmt.Sprintf("[keepAlive is now %d]\n", hc.keepalive))
|
||||||
|
|
||||||
//if rand.Intn(8) == 0 {
|
//if rand.Intn(8) == 0 {
|
||||||
|
|
Loading…
Reference in New Issue