mirror of https://gogs.blitter.com/RLabs/xs
Removed moving avg chaff in favour of random-padding
This commit is contained in:
parent
06ee94da03
commit
1485e8392e
|
@ -49,6 +49,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
|
const PAD_SZ = 32
|
||||||
|
|
||||||
type (
|
type (
|
||||||
WinSize struct {
|
WinSize struct {
|
||||||
|
@ -80,9 +81,7 @@ type (
|
||||||
Rows uint16
|
Rows uint16
|
||||||
Cols uint16
|
Cols uint16
|
||||||
|
|
||||||
chaff ChaffConfig
|
chaff ChaffConfig
|
||||||
totBytes *uint64 // total bytes xmitted so far
|
|
||||||
totPackets *uint64 // total packets xmitted so far
|
|
||||||
|
|
||||||
closeStat *CSOType // close status (CSOExitStatus)
|
closeStat *CSOType // close status (CSOExitStatus)
|
||||||
r cipher.Stream //read cipherStream
|
r cipher.Stream //read cipherStream
|
||||||
|
@ -266,7 +265,7 @@ func Dial(protocol string, ipport string, extensions ...string) (hc Conn, err er
|
||||||
// NOTE: kex default of KEX_HERRADURA may be overridden by
|
// NOTE: kex default of KEX_HERRADURA may be overridden by
|
||||||
// future extension args to applyConnExtensions(), which is
|
// future extension args to applyConnExtensions(), which is
|
||||||
// called prior to Dial()
|
// called prior to Dial()
|
||||||
hc = Conn{m: &sync.Mutex{}, c: c, closeStat: new(CSOType), h: hkex.New(0, 0), dBuf: new(bytes.Buffer), totBytes: new(uint64), totPackets: new(uint64)}
|
hc = Conn{m: &sync.Mutex{}, c: c, closeStat: new(CSOType), h: hkex.New(0, 0), dBuf: new(bytes.Buffer)}
|
||||||
hc.applyConnExtensions(extensions...)
|
hc.applyConnExtensions(extensions...)
|
||||||
|
|
||||||
// TODO: Factor out ALL params following this to helpers for
|
// TODO: Factor out ALL params following this to helpers for
|
||||||
|
@ -399,13 +398,13 @@ func (hl *HKExListener) Accept() (hc Conn, err error) {
|
||||||
c, err := hl.l.Accept()
|
c, err := hl.l.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hc := Conn{m: &sync.Mutex{}, c: nil, h: nil, closeStat: new(CSOType), cipheropts: 0, opts: 0,
|
hc := Conn{m: &sync.Mutex{}, c: nil, h: nil, closeStat: new(CSOType), cipheropts: 0, opts: 0,
|
||||||
r: nil, w: nil, totBytes: new(uint64), totPackets: new(uint64)}
|
r: nil, w: nil}
|
||||||
return hc, err
|
return hc, err
|
||||||
}
|
}
|
||||||
log.Println("[Accepted]")
|
log.Println("[Accepted]")
|
||||||
|
|
||||||
hc = Conn{ /*kex: from client,*/ m: &sync.Mutex{}, c: c, h: hkex.New(0, 0), closeStat: new(CSOType), WinCh: make(chan WinSize, 1),
|
hc = Conn{ /*kex: from client,*/ m: &sync.Mutex{}, c: c, h: hkex.New(0, 0), closeStat: new(CSOType), WinCh: make(chan WinSize, 1),
|
||||||
dBuf: new(bytes.Buffer), totBytes: new(uint64), totPackets: new(uint64)}
|
dBuf: new(bytes.Buffer)}
|
||||||
|
|
||||||
// TODO: Factor out ALL params following this to helpers for
|
// TODO: Factor out ALL params following this to helpers for
|
||||||
// specific KEx algs
|
// specific KEx algs
|
||||||
|
@ -503,13 +502,27 @@ func (hc Conn) Read(b []byte) (n int, err error) {
|
||||||
// to the parameter of Read() as a normal io.Reader
|
// to the parameter of Read() as a normal io.Reader
|
||||||
rs := &cipher.StreamReader{S: hc.r, R: db}
|
rs := &cipher.StreamReader{S: hc.r, R: db}
|
||||||
// The caller isn't necessarily reading the full payload so we need
|
// The caller isn't necessarily reading the full payload so we need
|
||||||
// to decrypt ot an intermediate buffer, draining it on demand of caller
|
// to decrypt to an intermediate buffer, draining it on demand of caller
|
||||||
decryptN, err := rs.Read(payloadBytes)
|
decryptN, err := rs.Read(payloadBytes)
|
||||||
log.Printf(" <-ptext:\r\n%s\r\n", hex.Dump(payloadBytes[:n]))
|
log.Printf(" <-ptext:\r\n%s\r\n", hex.Dump(payloadBytes[:n]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("hkexnet.Read():", err)
|
log.Println("hkexnet.Read():", err)
|
||||||
//panic(err)
|
//panic(err)
|
||||||
} else {
|
} else {
|
||||||
|
hc.rm.Write(payloadBytes) // Calc hmac on received data
|
||||||
|
// Padding: Read padSide, padLen, (padding | d) or (d | padding)
|
||||||
|
padSide := payloadBytes[0]
|
||||||
|
padLen := payloadBytes[1]
|
||||||
|
|
||||||
|
payloadBytes = payloadBytes[2:]
|
||||||
|
if padSide == 0 {
|
||||||
|
payloadBytes = payloadBytes[padLen:]
|
||||||
|
} else {
|
||||||
|
payloadBytes = payloadBytes[0 : len(payloadBytes)-int(padLen)]
|
||||||
|
}
|
||||||
|
|
||||||
|
//fmt.Printf("padSide:%d padLen:%d payloadBytes:%s\n",
|
||||||
|
// padSide, padLen, hex.Dump(payloadBytes))
|
||||||
|
|
||||||
// Throw away pkt if it's chaff (ie., caller to Read() won't see this data)
|
// Throw away pkt if it's chaff (ie., caller to Read() won't see this data)
|
||||||
if ctrlStatOp == CSOChaff {
|
if ctrlStatOp == CSOChaff {
|
||||||
|
@ -531,8 +544,6 @@ func (hc Conn) Read(b []byte) (n int, err error) {
|
||||||
//log.Printf("hc.dBuf: %s\n", hex.Dump(hc.dBuf.Bytes()))
|
//log.Printf("hc.dBuf: %s\n", hex.Dump(hc.dBuf.Bytes()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-calculate hmac, compare with received value
|
|
||||||
hc.rm.Write(payloadBytes)
|
|
||||||
hTmp := hc.rm.Sum(nil)[0:4]
|
hTmp := hc.rm.Sum(nil)[0:4]
|
||||||
log.Printf("<%04x) HMAC:(i)%s (c)%02x\r\n", decryptN, hex.EncodeToString([]byte(hmacIn[0:])), hTmp)
|
log.Printf("<%04x) HMAC:(i)%s (c)%02x\r\n", decryptN, hex.EncodeToString([]byte(hmacIn[0:])), hTmp)
|
||||||
|
|
||||||
|
@ -562,7 +573,9 @@ func (hc Conn) Read(b []byte) (n int, err error) {
|
||||||
//
|
//
|
||||||
// See go doc io.Writer
|
// See go doc io.Writer
|
||||||
func (hc Conn) Write(b []byte) (n int, err error) {
|
func (hc Conn) Write(b []byte) (n int, err error) {
|
||||||
|
//fmt.Printf("WRITE(%d)\n", len(b))
|
||||||
n, err = hc.WritePacket(b, CSONone)
|
n, err = hc.WritePacket(b, CSONone)
|
||||||
|
//fmt.Printf("WROTE(%d)\n", n)
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,6 +589,28 @@ func (hc *Conn) WritePacket(b []byte, op byte) (n int, err error) {
|
||||||
return 0, errors.New("Secure chan not ready for writing")
|
return 0, errors.New("Secure chan not ready for writing")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Padding
|
||||||
|
padLen := PAD_SZ - ((uint32(len(b)) + PAD_SZ) % PAD_SZ)
|
||||||
|
if padLen == PAD_SZ {
|
||||||
|
// No padding required
|
||||||
|
padLen = 0
|
||||||
|
}
|
||||||
|
padBytes := make([]byte, padLen)
|
||||||
|
rand.Read(padBytes)
|
||||||
|
// For a little more confusion let's support padding either before
|
||||||
|
// or after the payload.
|
||||||
|
padSide := rand.Intn(2)
|
||||||
|
//fmt.Printf("--\n")
|
||||||
|
//fmt.Printf("PRE_PADDING:%s\r\n", hex.Dump(b))
|
||||||
|
//fmt.Printf("padSide:%d padLen:%d\r\n", padSide, padLen)
|
||||||
|
if padSide == 0 {
|
||||||
|
b = append([]byte{byte(padSide)}, append([]byte{byte(padLen)}, append(padBytes, b...)...)...)
|
||||||
|
} else {
|
||||||
|
b = append([]byte{byte(padSide)}, append([]byte{byte(padLen)}, append(b, padBytes...)...)...)
|
||||||
|
}
|
||||||
|
//fmt.Printf("POST_PADDING:%s\r\n", hex.Dump(b))
|
||||||
|
//fmt.Printf("--\r\n")
|
||||||
|
|
||||||
// N.B. Originally this Lock() surrounded only the
|
// N.B. Originally this Lock() surrounded only the
|
||||||
// calls to binary.Write(hc.c ..) however there appears
|
// calls to binary.Write(hc.c ..) however there appears
|
||||||
// to be some other unshareable state in the Conn
|
// to be some other unshareable state in the Conn
|
||||||
|
@ -614,18 +649,6 @@ func (hc *Conn) WritePacket(b []byte, op byte) (n int, err error) {
|
||||||
err = binary.Write(hc.c, binary.BigEndian, payloadLen)
|
err = binary.Write(hc.c, binary.BigEndian, payloadLen)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
n, err = hc.c.Write(wb.Bytes())
|
n, err = hc.c.Write(wb.Bytes())
|
||||||
|
|
||||||
// If regular traffic, update running avg stats
|
|
||||||
if op != CSOChaff {
|
|
||||||
if *hc.totBytes+uint64(n) > *hc.totBytes {
|
|
||||||
*hc.totBytes = *hc.totBytes + uint64(n)
|
|
||||||
*hc.totPackets = *hc.totPackets + 1
|
|
||||||
log.Printf("totPackets:%d totBytes:%d\n",
|
|
||||||
*hc.totPackets, *hc.totBytes)
|
|
||||||
} else {
|
|
||||||
//overflow, don't add to totBytes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
//fmt.Println("[c]WriteError!")
|
//fmt.Println("[c]WriteError!")
|
||||||
}
|
}
|
||||||
|
@ -640,7 +663,10 @@ func (hc *Conn) WritePacket(b []byte, op byte) (n int, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
return
|
|
||||||
|
// We must 'lie' to caller indicating the length of THEIR
|
||||||
|
// data written (ie., not including the padding and padding headers)
|
||||||
|
return n - 2 - int(padLen), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hc *Conn) EnableChaff() {
|
func (hc *Conn) EnableChaff() {
|
||||||
|
@ -673,20 +699,7 @@ func (hc *Conn) chaffHelper() {
|
||||||
var nextDuration int
|
var nextDuration int
|
||||||
if hc.chaff.enabled {
|
if hc.chaff.enabled {
|
||||||
var bufTmp []byte
|
var bufTmp []byte
|
||||||
if false {
|
bufTmp = make([]byte, rand.Intn(int(hc.chaff.szMax)))
|
||||||
bufTmp = make([]byte, rand.Intn(int(hc.chaff.szMax)))
|
|
||||||
} else {
|
|
||||||
// size chaff with running avg of actual traffic
|
|
||||||
denom := *hc.totPackets
|
|
||||||
numer := *hc.totBytes
|
|
||||||
if numer == 0 {
|
|
||||||
numer = uint64(rand.Intn(63) + 1)
|
|
||||||
}
|
|
||||||
if denom == 0 {
|
|
||||||
denom = 1
|
|
||||||
}
|
|
||||||
bufTmp = make([]byte, (numer / denom))
|
|
||||||
}
|
|
||||||
min := int(hc.chaff.msecsMin)
|
min := int(hc.chaff.msecsMin)
|
||||||
nextDuration = rand.Intn(int(hc.chaff.msecsMax)-min) + min
|
nextDuration = rand.Intn(int(hc.chaff.msecsMax)-min) + min
|
||||||
_, _ = rand.Read(bufTmp)
|
_, _ = rand.Read(bufTmp)
|
||||||
|
|
Loading…
Reference in New Issue