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.
 | 
			
		||||
***
 | 
			
		||||
 | 
			
		||||
***
 | 
			
		||||
**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
 | 
			
		||||
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
 | 
			
		||||
	CORemodulateShields // if set, rekeying also reselects random cipher/hmac alg
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type COValue uint32
 | 
			
		||||
 | 
			
		||||
// Available HMACs for hkex.Conn
 | 
			
		||||
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]))
 | 
			
		||||
				rekeyData := payloadBytes
 | 
			
		||||
				if (hc.opts & CORemodulateShields) != 0 {
 | 
			
		||||
					hc.Lock()
 | 
			
		||||
					hc.cipheropts = getNewStreamAlgs(rekeyData[0], rekeyData[1])
 | 
			
		||||
					hc.Unlock()
 | 
			
		||||
				}
 | 
			
		||||
				hc.r, hc.rm, err = hc.getStream(rekeyData)
 | 
			
		||||
			case CSOTermSize:
 | 
			
		||||
| 
						 | 
				
			
			@ -1591,7 +1593,9 @@ func (hc *Conn) StartupChaff() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (hc *Conn) ShutdownChaff() {
 | 
			
		||||
	hc.Lock()
 | 
			
		||||
	hc.chaff.shutdown = true
 | 
			
		||||
	hc.Unlock()
 | 
			
		||||
	log.Println("Chaffing SHUTDOWN")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1602,16 +1606,28 @@ func (hc *Conn) SetupChaff(msecsMin uint, msecsMax uint, szMax uint) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (hc *Conn) ShutdownRekey() {
 | 
			
		||||
	hc.Lock()
 | 
			
		||||
	hc.rekey = 0
 | 
			
		||||
	hc.Unlock()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (hc *Conn) RekeyHelper(intervalSecs uint) {
 | 
			
		||||
	if intervalSecs < REKEY_SECS_MIN {
 | 
			
		||||
		intervalSecs = REKEY_SECS_MIN
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	go func() {
 | 
			
		||||
		hc.Lock()
 | 
			
		||||
		hc.rekey = intervalSecs
 | 
			
		||||
		hc.Unlock()
 | 
			
		||||
 | 
			
		||||
		for {
 | 
			
		||||
			if hc.rekey != 0 {
 | 
			
		||||
			hc.Lock()
 | 
			
		||||
			rekey := hc.rekey
 | 
			
		||||
			hc.Unlock()
 | 
			
		||||
			if rekey != 0 {
 | 
			
		||||
				//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
 | 
			
		||||
				rekeyData := make([]byte, 64)
 | 
			
		||||
| 
						 | 
				
			
			@ -1640,11 +1656,21 @@ func (hc *Conn) RekeyHelper(intervalSecs uint) {
 | 
			
		|||
 | 
			
		||||
// Helper routine to spawn a chaffing goroutine for each Conn
 | 
			
		||||
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() {
 | 
			
		||||
		var nextDuration int
 | 
			
		||||
		for {
 | 
			
		||||
			//logger.LogDebug(fmt.Sprintf("[chaffHelper Loop]\n"))
 | 
			
		||||
			if !hc.chaff.shutdown {
 | 
			
		||||
			hc.Lock()
 | 
			
		||||
			shutdown := hc.chaff.shutdown
 | 
			
		||||
			hc.Unlock()
 | 
			
		||||
			if !shutdown {
 | 
			
		||||
				var bufTmp []byte
 | 
			
		||||
				bufTmp = make([]byte, rand.Intn(int(hc.chaff.szMax)))
 | 
			
		||||
				min := int(hc.chaff.msecsMin)
 | 
			
		||||
| 
						 | 
				
			
			@ -1655,7 +1681,9 @@ func (hc *Conn) chaffHelper() {
 | 
			
		|||
				//logger.LogDebug("[-chaffHelper]")
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					log.Println("[ *** error - chaffHelper shutting down *** ]")
 | 
			
		||||
					hc.Lock()
 | 
			
		||||
					hc.chaff.shutdown = true
 | 
			
		||||
					hc.Unlock()
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -1679,7 +1707,9 @@ func (hc *Conn) ShutdownKeepAlive() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (hc *Conn) ResetKeepAlive() {
 | 
			
		||||
	hc.Lock()
 | 
			
		||||
	hc.keepalive = 3
 | 
			
		||||
	hc.Unlock()
 | 
			
		||||
	log.Println("KeepAlive RESET")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1698,7 +1728,9 @@ func (hc *Conn) keepaliveHelper() {
 | 
			
		|||
				break
 | 
			
		||||
			}
 | 
			
		||||
			time.Sleep(time.Duration(nextDuration) * time.Millisecond)
 | 
			
		||||
			hc.Lock()
 | 
			
		||||
			hc.keepalive -= 1
 | 
			
		||||
			hc.Unlock()
 | 
			
		||||
			//logger.LogDebug(fmt.Sprintf("[keepAlive is now %d]\n", hc.keepalive))
 | 
			
		||||
 | 
			
		||||
			//if rand.Intn(8) == 0 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue