Hoorah, got basic crypto working over hkex Conn

This commit is contained in:
Russ Magee 2018-01-10 22:50:13 -08:00
parent b28ca552bd
commit c43b13989b
3 changed files with 34 additions and 75 deletions

View File

@ -44,7 +44,7 @@ func main() {
go func(ch chan []byte, eCh chan error) { go func(ch chan []byte, eCh chan error) {
for { for {
// try to read the data // try to read the data
data := make([]byte, 64) data := make([]byte, 8)
chN, err = c.Read(data) chN, err = c.Read(data)
if err != nil { if err != nil {
// send an error if it's encountered // send an error if it's encountered

View File

@ -24,7 +24,6 @@ import (
"crypto/aes" "crypto/aes"
"crypto/cipher" "crypto/cipher"
"fmt" "fmt"
"io"
"math/big" "math/big"
"os" "os"
) )
@ -41,7 +40,7 @@ const (
/* Support functionality to set up encryption after a channel has /* Support functionality to set up encryption after a channel has
been negotiated via hkexnet.go 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 key []byte
var block cipher.Block var block cipher.Block
var err error var err error
@ -53,10 +52,16 @@ func (hc Conn) getStreamReader(keymat *big.Int, flags uint32, r io.Reader) (ret
case C_AES_256: case C_AES_256:
key = keymat.Bytes()[0:aes.BlockSize] key = keymat.Bytes()[0:aes.BlockSize]
block, err = aes.NewCipher(key) 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 break
default: default:
fmt.Println("DOOFUS SET A VALID CIPHER ALG") fmt.Println("DOOFUS SET A VALID CIPHER ALG")
block, err = aes.NewCipher(key) block, err = nil, nil
os.Exit(1) os.Exit(1)
} }
@ -64,53 +69,5 @@ func (hc Conn) getStreamReader(keymat *big.Int, flags uint32, r io.Reader) (ret
panic(err) 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 return
} }

View File

@ -22,6 +22,7 @@ package herradurakex
// 'net.Dial', 'net.Listen' etc. with 'hkex.Dial', 'hkex.Listen' and so // 'net.Dial', 'net.Listen' etc. with 'hkex.Dial', 'hkex.Listen' and so
// forth. // forth.
import ( import (
"bytes"
"crypto/cipher" "crypto/cipher"
"fmt" "fmt"
"math/big" "math/big"
@ -33,8 +34,8 @@ import (
type Conn struct { type Conn struct {
c net.Conn // which also implements io.Reader, io.Writer, ... c net.Conn // which also implements io.Reader, io.Writer, ...
h *HerraduraKEx h *HerraduraKEx
r *cipher.StreamReader r cipher.Stream
w *cipher.StreamWriter w cipher.Stream
} }
// Dial as net.Dial(), but with implicit HKEx PeerD read on connect // 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() hc.h.FA()
fmt.Printf("**(c)** FA:%s\n", hc.h.fa) fmt.Printf("**(c)** FA:%s\n", hc.h.fa)
hc.r = hc.getStreamReader(hc.h.fa, 0x0, hc.c) hc.r = hc.getStream(hc.h.fa, 0x0)
hc.w = hc.getStreamWriter(hc.h.fa, 0x0, hc.c) hc.w = hc.getStream(hc.h.fa, 0x0)
return return
} }
@ -97,7 +98,7 @@ func (hl *HKExListener) Accept() (hc Conn, err error) {
if err != nil { if err != nil {
return Conn{nil, nil, nil, nil}, err 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) d := big.NewInt(0)
_, err = fmt.Fscanln(c, d) _, 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)) fmt.Fprintf(c, "0x%s\n", hc.h.d.Text(16))
hc.r = hc.getStreamReader(hc.h.fa, 0x0, hc.c) hc.r = hc.getStream(hc.h.fa, 0x0)
hc.w = hc.getStreamWriter(hc.h.fa, 0x0, hc.c) hc.w = hc.getStream(hc.h.fa, 0x0)
return return
} }
/*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/
func (hc Conn) Read(b []byte) (n int, err error) { func (hc Conn) Read(b []byte) (n int, err error) {
n, err = hc.c.Read(b)
fmt.Printf("[Decrypting...]\n") fmt.Printf("[Decrypting...]\n")
fmt.Printf("[ciphertext:%+v]\n", b[0:n]) n, err = hc.c.Read(b)
for i := 0; i < n; i++ { if err != nil && err.Error() != "EOF" {
//for i, _ := range b { panic(err)
// FOR TESTING ONLY!! USE REAL CRYPTO HERE }
//b[i] ^= byte( hc.h.d.Mod(hc.h.d, big.NewInt(int64(c))).Int64() ) if n > 0 {
b[i] ^= hc.h.fa.Bytes()[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 return
} }
func (hc Conn) Write(b []byte) (n int, err error) { func (hc Conn) Write(b []byte) (n int, err error) {
fmt.Printf("[Encrypting...]\n") fmt.Printf("[Encrypting...]\n")
for i, _ := range b { fmt.Printf(" ptext:%+v\n", b)
// FOR TESTING ONLY!! USE REAL CRYPTO HERE var wb bytes.Buffer
//b[i] ^= byte( hc.h.d.Mod(hc.h.d, big.NewInt(int64(c))).Int64() ) ws := &cipher.StreamWriter{S: hc.w, W: &wb}
b[i] ^= hc.h.fa.Bytes()[0] n, err = ws.Write(b)
} fmt.Printf(" ctext:%+v\n", wb.Bytes())
fmt.Printf("[ciphertext:%+v]\n", b) n, err = hc.c.Write(wb.Bytes())
n, err = hc.c.Write(b)
return return
} }