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 cmdStr string
tunSpecStr string // lport1:rport1[,lport2:rport2,...] tunSpecStr string // lport1:rport1[,lport2:rport2,...]
rekeySecs uint 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 copySrc []byte
copyDst string copyDst string
copyQuiet bool 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.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(&port, "p", 2000, "``port") //nolint:gomnd,lll
flag.UintVar(&rekeySecs, "r", 300, "rekey interval in `secs`") 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") //nolint:gocritic,nolintlint // flag.StringVar(&authCookie, "a", "", "auth cookie")
flag.BoolVar(&chaffEnabled, "e", true, "enable chaff pkts") flag.BoolVar(&chaffEnabled, "e", true, "enable chaff pkts")
flag.UintVar(&chaffFreqMin, "f", 100, "chaff pkt freq min `msecs`") //nolint:gomnd flag.UintVar(&chaffFreqMin, "f", 100, "chaff pkt freq min `msecs`") //nolint:gomnd
@ -969,15 +969,18 @@ func main() { //nolint: funlen, gocyclo
if kcpMode != "unused" { if kcpMode != "unused" {
proto = "kcp" 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 { if err != nil {
fmt.Println(err) fmt.Println(err)
exitWithStatus(XSNetDialFailed) exitWithStatus(XSNetDialFailed)
} }
if remodulate {
conn.SetOpts(xsnet.CORemodulateShields)
}
conn.RekeyHelper(rekeySecs) conn.RekeyHelper(rekeySecs)
defer conn.ShutdownRekey() defer conn.ShutdownRekey()

View File

@ -530,13 +530,13 @@ func main() { //nolint:funlen,gocyclo
var dbg bool var dbg bool
var laddr string var laddr string
var rekeySecs uint 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 var useSystemPasswd bool
flag.BoolVar(&vopt, "v", false, "show version") flag.BoolVar(&vopt, "v", false, "show version")
flag.UintVar(&rekeySecs, "r", 300, "rekey interval in `secs`") 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(&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.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") flag.BoolVar(&useSysLogin, "L", false, "use system login")
@ -704,8 +704,21 @@ func main() { //nolint:funlen,gocyclo
} else { } else {
log.Println("Accepted client") log.Println("Accepted client")
if remodulate { // Only enable cipher alg changes on re-key if we were told
conn.SetOpts(xsnet.CORemodulateShields) // 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) 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 // Consumers of this lib may use this for protocol-level options not part
// of the KEx or encryption info used by the connection. // of the KEx or encryption info used by the connection.
func (hc Conn) Opts() uint32 { func (hc *Conn) Opts() uint32 {
return hc.opts return hc.opts
} }
@ -363,8 +363,11 @@ func (hc *Conn) applyConnExtensions(extensions ...string) {
log.Println("[extension arg = H_SHA512]") log.Println("[extension arg = H_SHA512]")
hc.cipheropts &= (0xFFFF00FF) hc.cipheropts &= (0xFFFF00FF)
hc.cipheropts |= (HmacSHA512 << 8) hc.cipheropts |= (HmacSHA512 << 8)
//default: case "-R":
// log.Printf("[Dial ext \"%s\" ignored]\n", s) 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", //logger.LogDebug(fmt.Sprintf("[Got rekey [%02x %02x %02x ...]\n",
// 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.cipheropts = getNewStreamAlgs(rekeyData[0], rekeyData[1]) hc.cipheropts = getNewStreamAlgs(rekeyData[0], rekeyData[1])
} }
hc.r, hc.rm, err = hc.getStream(rekeyData) hc.r, hc.rm, err = hc.getStream(rekeyData)
@ -1615,10 +1618,10 @@ func (hc *Conn) RekeyHelper(intervalSecs uint) {
_, err := crand.Read(rekeyData) _, err := crand.Read(rekeyData)
//logger.LogDebug(fmt.Sprintf("[rekey [%02x %02x %02x ...]\n", //logger.LogDebug(fmt.Sprintf("[rekey [%02x %02x %02x ...]\n",
// rekeyData[0], rekeyData[1], rekeyData[2])) // rekeyData[0], rekeyData[1], rekeyData[2]))
//logger.LogDebug("[+rekeyHelper]") logger.LogDebug("[+rekeyHelper]")
_, err = hc.WritePacket(rekeyData, CSORekey) _, err = hc.WritePacket(rekeyData, CSORekey)
hc.Lock() hc.Lock()
if hc.opts&CORemodulateShields != 0 { if (hc.opts & CORemodulateShields) != 0 {
hc.cipheropts = getNewStreamAlgs(rekeyData[0], rekeyData[1]) hc.cipheropts = getNewStreamAlgs(rekeyData[0], rekeyData[1])
} }
hc.w, hc.wm, err = hc.getStream(rekeyData) hc.w, hc.wm, err = hc.getStream(rekeyData)