diff --git a/demo/server.go b/demo/server.go index cf14828..b4a03f3 100644 --- a/demo/server.go +++ b/demo/server.go @@ -44,7 +44,7 @@ func main() { go func(ch chan []byte, eCh chan error) { for { // try to read the data - data := make([]byte, 64) + data := make([]byte, 8) chN, err = c.Read(data) if err != nil { // send an error if it's encountered diff --git a/hkexchan.go b/hkexchan.go index 4ea537d..884e45c 100644 --- a/hkexchan.go +++ b/hkexchan.go @@ -18,13 +18,12 @@ package herradurakex /* Support functions to set up encryption once an HKEx Conn has been - established with FA exchange */ +established with FA exchange */ import ( "crypto/aes" "crypto/cipher" "fmt" - "io" "math/big" "os" ) @@ -41,7 +40,7 @@ const ( /* Support functionality to set up encryption after a channel has been negotiated via hkexnet.go */ -func (hc Conn) getStreamReader(keymat *big.Int, flags uint32, r io.Reader) (ret *cipher.StreamReader) { +func (hc Conn) getStream(keymat *big.Int, flags uint32) (ret cipher.Stream) { var key []byte var block cipher.Block var err error @@ -53,10 +52,16 @@ func (hc Conn) getStreamReader(keymat *big.Int, flags uint32, r io.Reader) (ret case C_AES_256: key = keymat.Bytes()[0:aes.BlockSize] block, err = aes.NewCipher(key) + iv := make([]byte, aes.BlockSize) + //if _, err = io.ReadFull(crand.Reader, iv); err != nil { + // panic(err) + //} + iv = keymat.Bytes()[aes.BlockSize:] + ret = cipher.NewOFB(block, iv) break default: fmt.Println("DOOFUS SET A VALID CIPHER ALG") - block, err = aes.NewCipher(key) + block, err = nil, nil os.Exit(1) } @@ -64,53 +69,5 @@ func (hc Conn) getStreamReader(keymat *big.Int, flags uint32, r io.Reader) (ret panic(err) } - // If the key is unique for each ciphertext, then it's ok to use a zero - // IV. - var iv [aes.BlockSize]byte - stream := cipher.NewOFB(block, iv[:]) - - ret = &cipher.StreamReader{S: stream, R: r} - - // Note that this example is simplistic in that it omits any - // authentication of the encrypted data. If you were actually to use - // StreamReader in this manner, an attacker could flip arbitrary bits in - // the output. - return -} - -func (hc Conn) getStreamWriter(keymat *big.Int, flags uint32, w io.Writer) (ret *cipher.StreamWriter) { - var key []byte - var block cipher.Block - var err error - - // 256 algs should be enough for everybody.(tm) - cipherAlg := (flags & 8) - //TODO: flags for HMAC from keymat - switch cipherAlg { - case C_AES_256: - key = keymat.Bytes()[0:aes.BlockSize] - block, err = aes.NewCipher(key) - break - default: - fmt.Println("DOOFUS SET A VALID CIPHER ALG") - block, err = aes.NewCipher(key) - os.Exit(1) - } - - if err != nil { - panic(err) - } - - // If the key is unique for each ciphertext, then it's ok to use a zero - // IV. - var iv [aes.BlockSize]byte - stream := cipher.NewOFB(block, iv[:]) - - ret = &cipher.StreamWriter{S: stream, W: w} - - // Note that this example is simplistic in that it omits any - // authentication of the encrypted data. If you were actually to use - // StreamReader in this manner, an attacker could flip arbitrary bits in - // the output. return } diff --git a/hkexnet.go b/hkexnet.go index 8de7bda..29658be 100644 --- a/hkexnet.go +++ b/hkexnet.go @@ -22,6 +22,7 @@ package herradurakex // 'net.Dial', 'net.Listen' etc. with 'hkex.Dial', 'hkex.Listen' and so // forth. import ( + "bytes" "crypto/cipher" "fmt" "math/big" @@ -33,8 +34,8 @@ import ( type Conn struct { c net.Conn // which also implements io.Reader, io.Writer, ... h *HerraduraKEx - r *cipher.StreamReader - w *cipher.StreamWriter + r cipher.Stream + w cipher.Stream } // Dial as net.Dial(), but with implicit HKEx PeerD read on connect @@ -58,8 +59,8 @@ func Dial(protocol string, ipport string) (hc *Conn, err error) { hc.h.FA() fmt.Printf("**(c)** FA:%s\n", hc.h.fa) - hc.r = hc.getStreamReader(hc.h.fa, 0x0, hc.c) - hc.w = hc.getStreamWriter(hc.h.fa, 0x0, hc.c) + hc.r = hc.getStream(hc.h.fa, 0x0) + hc.w = hc.getStream(hc.h.fa, 0x0) return } @@ -97,7 +98,7 @@ func (hl *HKExListener) Accept() (hc Conn, err error) { if err != nil { return Conn{nil, nil, nil, nil}, err } - hc = Conn{c, New(0, 0), nil, nil} + hc = Conn{c: c, h: New(0, 0), r: nil, w: nil} d := big.NewInt(0) _, err = fmt.Fscanln(c, d) @@ -113,35 +114,36 @@ func (hl *HKExListener) Accept() (hc Conn, err error) { fmt.Fprintf(c, "0x%s\n", hc.h.d.Text(16)) - hc.r = hc.getStreamReader(hc.h.fa, 0x0, hc.c) - hc.w = hc.getStreamWriter(hc.h.fa, 0x0, hc.c) + hc.r = hc.getStream(hc.h.fa, 0x0) + hc.w = hc.getStream(hc.h.fa, 0x0) return } /*---------------------------------------------------------------------*/ func (hc Conn) Read(b []byte) (n int, err error) { - n, err = hc.c.Read(b) fmt.Printf("[Decrypting...]\n") - fmt.Printf("[ciphertext:%+v]\n", b[0:n]) - for i := 0; i < n; i++ { - //for i, _ := range b { - // FOR TESTING ONLY!! USE REAL CRYPTO HERE - //b[i] ^= byte( hc.h.d.Mod(hc.h.d, big.NewInt(int64(c))).Int64() ) - b[i] ^= hc.h.fa.Bytes()[0] + n, err = hc.c.Read(b) + if err != nil && err.Error() != "EOF" { + panic(err) + } + if n > 0 { + fmt.Printf(" ctext:%+v\n", b[:n]) + db := bytes.NewBuffer(b[:n]) + rs := &cipher.StreamReader{S: hc.r, R: db} + n, err = rs.Read(b) + fmt.Printf(" ptext:%+v\n", b[:n]) } - fmt.Printf("[plaintext:%+v]\n", b[0:n]) return } func (hc Conn) Write(b []byte) (n int, err error) { fmt.Printf("[Encrypting...]\n") - for i, _ := range b { - // FOR TESTING ONLY!! USE REAL CRYPTO HERE - //b[i] ^= byte( hc.h.d.Mod(hc.h.d, big.NewInt(int64(c))).Int64() ) - b[i] ^= hc.h.fa.Bytes()[0] - } - fmt.Printf("[ciphertext:%+v]\n", b) - n, err = hc.c.Write(b) + fmt.Printf(" ptext:%+v\n", b) + var wb bytes.Buffer + ws := &cipher.StreamWriter{S: hc.w, W: &wb} + n, err = ws.Write(b) + fmt.Printf(" ctext:%+v\n", wb.Bytes()) + n, err = hc.c.Write(wb.Bytes()) return }