Experimental cipher/hmac alg change on rekey

This commit is contained in:
Russ Magee 2023-11-16 00:59:54 -08:00
parent e82d968381
commit d42756b354
5 changed files with 39 additions and 5 deletions

View File

@ -702,6 +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
copySrc []byte
copyDst string
copyQuiet bool
@ -745,8 +746,9 @@ func main() { //nolint: funlen, gocyclo
KEX_FRODOKEM_976AES
KEX_FRODOKEM_976SHAKE`)
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.BoolVar(&remodulate, "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
@ -973,6 +975,9 @@ func main() { //nolint: funlen, gocyclo
exitWithStatus(XSNetDialFailed)
}
if remodulate {
conn.SetOpts(xsnet.CORemodulateShields)
}
conn.RekeyHelper(rekeySecs)
defer conn.ShutdownRekey()

View File

@ -530,12 +530,14 @@ 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 useSystemPasswd bool
flag.BoolVar(&vopt, "v", false, "show version")
flag.UintVar(&rekeySecs, "r", 300, "rekey interval in `secs`")
flag.StringVar(&laddr, "l", ":2000", "interface[:port] to listen") //nolint:gomnd,lll
flag.BoolVar(&remodulate, "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")
flag.BoolVar(&chaffEnabled, "e", true, "enable chaff pkts")
@ -702,6 +704,9 @@ func main() { //nolint:funlen,gocyclo
} else {
log.Println("Accepted client")
if remodulate {
conn.SetOpts(xsnet.CORemodulateShields)
}
conn.RekeyHelper(rekeySecs)
// Set up chaffing to client

View File

@ -22,6 +22,7 @@ import (
"blitter.com/go/cryptmt"
"blitter.com/go/hopscotch"
"blitter.com/go/xs/logger"
"github.com/aead/chacha20/chacha"
"golang.org/x/crypto/blowfish"
"golang.org/x/crypto/twofish"
@ -57,9 +58,19 @@ func expandKeyMat(keymat []byte, blocksize int) []byte {
return keymat
}
/* (Re-)initialize the keystream and hmac state for an xsnet.Conn, returning
a cipherStream and hash
*/
// Choose a cipher and hmac alg from supported sets, given two uint8 values
func getNewStreamAlgs(cb uint8, hb uint8) (config uint32) {
// Get new cipher and hash algs (clamped to valid values) based on
// the input rekeying data
c := (cb % CAlgNoneDisallowed)
h := (hb % HmacNoneDisallowed)
config = uint32(h<<8) | uint32(c)
logger.LogDebug(fmt.Sprintf("[Chose new algs [%d:%d]", h, c))
return
}
// (Re-)initialize the keystream and hmac state for an xsnet.Conn, returning
// a cipherStream and hash
func (hc *Conn) getStream(keymat []byte) (rc cipher.Stream, mc hash.Hash, err error) {
var key []byte
var block cipher.Block

View File

@ -122,5 +122,12 @@ const (
HmacNoneDisallowed
)
// Conn opts outside of basic kex/cipher/hmac connect config
const (
CONone = iota
CORemodulateShields // if set, rekeying also reselects random cipher/hmac alg
)
type COValue uint32
// Available HMACs for hkex.Conn
type CSHmacAlg uint32

View File

@ -1351,6 +1351,9 @@ 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 {
hc.cipheropts = getNewStreamAlgs(rekeyData[0], rekeyData[1])
}
hc.r, hc.rm, err = hc.getStream(rekeyData)
case CSOTermSize:
fmt.Sscanf(string(payloadBytes), "%d %d", &hc.Rows, &hc.Cols)
@ -1615,6 +1618,9 @@ func (hc *Conn) RekeyHelper(intervalSecs uint) {
//logger.LogDebug("[+rekeyHelper]")
_, err = hc.WritePacket(rekeyData, CSORekey)
hc.Lock()
if hc.opts&CORemodulateShields != 0 {
hc.cipheropts = getNewStreamAlgs(rekeyData[0], rekeyData[1])
}
hc.w, hc.wm, err = hc.getStream(rekeyData)
//logger.LogDebug("[-rekeyHelper]")
hc.Unlock()