Fixes to negotiate/accept cipher remodulation

This commit is contained in:
Russ Magee 2023-11-17 13:37:11 -08:00
parent d171950f4c
commit 7efb8cc2c4
3 changed files with 35 additions and 16 deletions

View File

@ -702,7 +702,7 @@ func main() { //nolint: funlen, gocyclo
cmdStr string
tunSpecStr string // lport1:rport1[,lport2:rport2,...]
rekeySecs uint
remodulate bool // true: when rekeying, switch to random cipher/hmac alg
remodRequested bool // true: when rekeying, switch to random cipher/hmac alg
copySrc []byte
copyDst string
copyQuiet bool
@ -748,7 +748,7 @@ func main() { //nolint: funlen, gocyclo
flag.StringVar(&kcpMode, "K", "unused", "KCP `alg`, one of [KCP_NONE | KCP_AES | KCP_BLOWFISH | KCP_CAST5 | KCP_SM4 | KCP_SALSA20 | KCP_SIMPLEXOR | KCP_TEA | KCP_3DES | KCP_TWOFISH | KCP_XTEA] to use KCP (github.com/xtaci/kcp-go) reliable UDP instead of TCP") //nolint:lll
flag.UintVar(&port, "p", 2000, "``port") //nolint:gomnd,lll
flag.UintVar(&rekeySecs, "r", 300, "rekey interval in `secs`")
flag.BoolVar(&remodulate, "R", false, "Borg Countermeasures (remodulate cipher/hmac alg on each rekey)")
flag.BoolVar(&remodRequested, "R", false, "Borg Countermeasures (remodulate cipher/hmac alg on each rekey)")
//nolint:gocritic,nolintlint // flag.StringVar(&authCookie, "a", "", "auth cookie")
flag.BoolVar(&chaffEnabled, "e", true, "enable chaff pkts")
flag.UintVar(&chaffFreqMin, "f", 100, "chaff pkt freq min `msecs`") //nolint:gomnd
@ -969,15 +969,18 @@ func main() { //nolint: funlen, gocyclo
if kcpMode != "unused" {
proto = "kcp"
}
conn, err := xsnet.Dial(proto, server, cipherAlg, hmacAlg, kexAlg, kcpMode)
remodExtArg := ""
if remodRequested {
remodExtArg = "-R"
}
// Pass opt to Dial() via extensions arg
conn, err := xsnet.Dial(proto, server, cipherAlg, hmacAlg, kexAlg, kcpMode, remodExtArg)
if err != nil {
fmt.Println(err)
exitWithStatus(XSNetDialFailed)
}
if remodulate {
conn.SetOpts(xsnet.CORemodulateShields)
}
conn.RekeyHelper(rekeySecs)
defer conn.ShutdownRekey()

View File

@ -530,13 +530,13 @@ func main() { //nolint:funlen,gocyclo
var dbg bool
var laddr string
var rekeySecs uint
var remodulate bool // true: when rekeying, switch to random cipher/hmac alg
var remodSupported bool // true: when rekeying, switch to random cipher/hmac alg
var useSystemPasswd bool
flag.BoolVar(&vopt, "v", false, "show version")
flag.UintVar(&rekeySecs, "r", 300, "rekey interval in `secs`")
flag.BoolVar(&remodulate, "R", false, "Borg Countermeasures (remodulate cipher/hmac alg on each rekey)")
flag.BoolVar(&remodSupported, "R", false, "Borg Countermeasures (remodulate cipher/hmac alg on each rekey)")
flag.StringVar(&laddr, "l", ":2000", "interface[:port] to listen") //nolint:gomnd,lll
flag.StringVar(&kcpMode, "K", "unused", `set to one of ["KCP_NONE","KCP_AES", "KCP_BLOWFISH", "KCP_CAST5", "KCP_SM4", "KCP_SALSA20", "KCP_SIMPLEXOR", "KCP_TEA", "KCP_3DES", "KCP_TWOFISH", "KCP_XTEA"] to use KCP (github.com/xtaci/kcp-go) reliable UDP instead of TCP`) //nolint:lll
flag.BoolVar(&useSysLogin, "L", false, "use system login")
@ -704,8 +704,21 @@ func main() { //nolint:funlen,gocyclo
} else {
log.Println("Accepted client")
if remodulate {
conn.SetOpts(xsnet.CORemodulateShields)
// Only enable cipher alg changes on re-key if we were told
// to support it (launching xsd with -R), *and* the client
// proposes to use it.
if !remodSupported {
if (conn.Opts() & xsnet.CORemodulateShields) != 0 {
logger.LogDebug("[client proposed -R, but we don't support it.]")
conn.Close()
continue
}
} else {
if conn.Opts()&xsnet.CORemodulateShields != 0 {
logger.LogDebug("[cipher remodulation active]")
} else {
logger.LogDebug("[cipher remodulation inactive]")
}
}
conn.RekeyHelper(rekeySecs)

View File

@ -241,7 +241,7 @@ func (hc *Conn) SetConnOpts(copts uint32) {
//
// Consumers of this lib may use this for protocol-level options not part
// of the KEx or encryption info used by the connection.
func (hc Conn) Opts() uint32 {
func (hc *Conn) Opts() uint32 {
return hc.opts
}
@ -363,8 +363,11 @@ func (hc *Conn) applyConnExtensions(extensions ...string) {
log.Println("[extension arg = H_SHA512]")
hc.cipheropts &= (0xFFFF00FF)
hc.cipheropts |= (HmacSHA512 << 8)
//default:
// log.Printf("[Dial ext \"%s\" ignored]\n", s)
case "-R":
log.Println("[extension arg = -R]")
hc.opts |= CORemodulateShields
//default:
// log.Printf("[Dial ext \"%s\" ignored]\n", s)
}
}
}
@ -1351,7 +1354,7 @@ func (hc *Conn) Read(b []byte) (n int, err error) {
//logger.LogDebug(fmt.Sprintf("[Got rekey [%02x %02x %02x ...]\n",
// payloadBytes[0], payloadBytes[1], payloadBytes[2]))
rekeyData := payloadBytes
if hc.opts&CORemodulateShields != 0 {
if (hc.opts & CORemodulateShields) != 0 {
hc.cipheropts = getNewStreamAlgs(rekeyData[0], rekeyData[1])
}
hc.r, hc.rm, err = hc.getStream(rekeyData)
@ -1615,10 +1618,10 @@ func (hc *Conn) RekeyHelper(intervalSecs uint) {
_, err := crand.Read(rekeyData)
//logger.LogDebug(fmt.Sprintf("[rekey [%02x %02x %02x ...]\n",
// rekeyData[0], rekeyData[1], rekeyData[2]))
//logger.LogDebug("[+rekeyHelper]")
logger.LogDebug("[+rekeyHelper]")
_, err = hc.WritePacket(rekeyData, CSORekey)
hc.Lock()
if hc.opts&CORemodulateShields != 0 {
if (hc.opts & CORemodulateShields) != 0 {
hc.cipheropts = getNewStreamAlgs(rekeyData[0], rekeyData[1])
}
hc.w, hc.wm, err = hc.getStream(rekeyData)