diff --git a/Makefile b/Makefile index d8de08b..7e7e3e9 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ -.PHONY: clean lib client server passwd +.PHONY: info clean lib client server passwd -SUBDIRS = hkexpasswd hkexsh hkexshd +SUBDIRS = hkexnet herradurakex hkexpasswd hkexsh hkexshd +LIBS = hkexnet herradurakex all: lib client server passwd diff --git a/herradurakex/Makefile b/herradurakex/Makefile new file mode 100644 index 0000000..e59fbc7 --- /dev/null +++ b/herradurakex/Makefile @@ -0,0 +1,17 @@ +.PHONY: info clean all lib + +all: lib + +clean: + go clean . + +lib: info + go install . + +ifneq ($(MSYSTEM),) +info: + @echo "building for Windows (MSYS)" +else +info: + @echo "building for Linux" +endif diff --git a/herradurakex.go b/herradurakex/herradurakex.go similarity index 86% rename from herradurakex.go rename to herradurakex/herradurakex.go index 9d59782..4e2c0ff 100644 --- a/herradurakex.go +++ b/herradurakex/herradurakex.go @@ -15,7 +15,7 @@ // distribution) // // golang implementation by Russ Magee (rmagee_at_gmail.com) -package hkexsh +package hkex /* Herradura - a Key exchange scheme in the style of Diffie-Hellman Key Exchange. Copyright (C) 2017 Omar Alejandro Herrera Reyna @@ -52,7 +52,7 @@ type HerraduraKEx struct { randctx *rand.Rand a *big.Int b *big.Int - d, PeerD *big.Int + d, peerD *big.Int fa *big.Int } @@ -148,22 +148,37 @@ func (h *HerraduraKEx) fscxRevolve(x, y *big.Int, passes int) (result *big.Int) // D returns the D (FSCX Revolved) value, input to generate FA // (the value for peer KEx) -func (h *HerraduraKEx) D() *big.Int { +func (h HerraduraKEx) D() *big.Int { return h.d } -// FA returns the FA value, which must be sent to peer for KEx. -func (h *HerraduraKEx) FA() { - h.fa = h.fscxRevolve(h.PeerD, h.b, h.intSz-h.pubSz) +// PeerD returns the peer D value +func (h HerraduraKEx) PeerD() *big.Int { + return h.peerD +} + +// SetPeerD stores the received peer's D value (contents, not ptr) +func (h *HerraduraKEx) SetPeerD(pd *big.Int) { + *h.peerD = *pd +} + +// ComputeFA computes the FA value, which must be sent to peer for KEx. +func (h *HerraduraKEx) ComputeFA() { + h.fa = h.fscxRevolve(h.peerD, h.b, h.intSz-h.pubSz) h.fa.Xor(h.fa, h.a) } +// FA returns the computed FA value +func (h HerraduraKEx) FA() *big.Int { + return h.fa +} + // Output HerraduraKEx type value as a string. Implements Stringer interface. func (h *HerraduraKEx) String() string { - return fmt.Sprintf("s:%d p:%d\na:%s\nb:%s\nd:->%s\n<-PeerD:%s\nfa:%s", + return fmt.Sprintf("s:%d p:%d\na:%s\nb:%s\nd:->%s\n<-peerD:%s\nfa:%s", h.intSz, h.pubSz, h.a.Text(16), h.b.Text(16), h.d.Text(16), - h.PeerD.Text(16), + h.peerD.Text(16), h.fa.Text(16)) } diff --git a/hkexnet/Makefile b/hkexnet/Makefile new file mode 100644 index 0000000..f645a41 --- /dev/null +++ b/hkexnet/Makefile @@ -0,0 +1,17 @@ +.PHONY: info clean lib + +all: lib + +clean: + go clean . + +lib: info + go install . + +ifneq ($(MSYSTEM),) +info: + @echo "Building for Windows (MSYS)" +else +info: + @echo "Building for Linux" +endif diff --git a/hkexchan.go b/hkexnet/hkexchan.go similarity index 99% rename from hkexchan.go rename to hkexnet/hkexchan.go index e2ecc76..2f75706 100644 --- a/hkexchan.go +++ b/hkexnet/hkexchan.go @@ -1,4 +1,4 @@ -package hkexsh +package hkexnet // Copyright (c) 2017-2018 Russell Magee // Licensed under the terms of the MIT license (see LICENSE.mit in this diff --git a/hkexnet.go b/hkexnet/hkexnet.go similarity index 94% rename from hkexnet.go rename to hkexnet/hkexnet.go index a0f3999..1eb0c6f 100644 --- a/hkexnet.go +++ b/hkexnet/hkexnet.go @@ -7,7 +7,7 @@ // // golang implementation by Russ Magee (rmagee_at_gmail.com) -package hkexsh +package hkexnet // Implementation of HKEx-wrapped versions of the golang standard // net package interfaces, allowing clients and servers to simply replace @@ -30,6 +30,8 @@ import ( "strings" "sync" "time" + + "blitter.com/go/hkexsh/herradurakex" ) const ( @@ -59,7 +61,7 @@ type ChaffConfig struct { type Conn struct { m *sync.Mutex c net.Conn // which also implements io.Reader, io.Writer, ... - h *HerraduraKEx + h *hkex.HerraduraKEx cipheropts uint32 // post-KEx cipher/hmac options opts uint32 // post-KEx protocol options (caller-defined) WinCh chan WinSize @@ -166,12 +168,12 @@ func Dial(protocol string, ipport string, extensions ...string) (hc *Conn, err e return nil, err } // Init hkexnet.Conn hc over net.Conn c - hc = &Conn{m: &sync.Mutex{}, c: c, closeStat: new(uint8), h: New(0, 0), dBuf: new(bytes.Buffer)} + hc = &Conn{m: &sync.Mutex{}, c: c, closeStat: new(uint8), h: hkex.New(0, 0), dBuf: new(bytes.Buffer)} hc.applyConnExtensions(extensions...) // Send hkexnet.Conn parameters to remote side // d is value for Herradura key exchange - fmt.Fprintf(c, "0x%s\n%08x:%08x\n", hc.h.d.Text(16), + fmt.Fprintf(c, "0x%s\n%08x:%08x\n", hc.h.D().Text(16), hc.cipheropts, hc.opts) d := big.NewInt(0) @@ -179,20 +181,21 @@ func Dial(protocol string, ipport string, extensions ...string) (hc *Conn, err e if err != nil { return nil, err } + // Read peer D over net.Conn (c) _, err = fmt.Fscanf(c, "%08x:%08x\n", &hc.cipheropts, &hc.opts) if err != nil { return nil, err } - hc.h.PeerD = d - log.Printf("** D:%s\n", hc.h.d.Text(16)) - log.Printf("**(c)** peerD:%s\n", hc.h.PeerD.Text(16)) - hc.h.FA() - log.Printf("**(c)** FA:%s\n", hc.h.fa) + hc.h.SetPeerD(d) + log.Printf("** local D:%s\n", hc.h.D().Text(16)) + log.Printf("**(c)** peer D:%s\n", hc.h.PeerD().Text(16)) + hc.h.ComputeFA() + log.Printf("**(c)** FA:%s\n", hc.h.FA()) - hc.r, hc.rm, err = hc.getStream(hc.h.fa) - hc.w, hc.wm, err = hc.getStream(hc.h.fa) + hc.r, hc.rm, err = hc.getStream(hc.h.FA()) + hc.w, hc.wm, err = hc.getStream(hc.h.FA()) *hc.closeStat = 99 // open or prematurely-closed status return @@ -304,7 +307,7 @@ func (hl HKExListener) Accept() (hc Conn, err error) { } log.Println("[Accepted]") - hc = Conn{m: &sync.Mutex{}, c: c, h: New(0, 0), closeStat: new(uint8), WinCh: make(chan WinSize, 1), + hc = Conn{m: &sync.Mutex{}, c: c, h: hkex.New(0, 0), closeStat: new(uint8), WinCh: make(chan WinSize, 1), dBuf: new(bytes.Buffer)} // Read in hkexnet.Conn parameters over raw Conn c @@ -321,17 +324,18 @@ func (hl HKExListener) Accept() (hc Conn, err error) { if err != nil { return hc, err } - hc.h.PeerD = d - log.Printf("** D:%s\n", hc.h.d.Text(16)) - log.Printf("**(s)** peerD:%s\n", hc.h.PeerD.Text(16)) + hc.h.SetPeerD(d) + log.Printf("** D:%s\n", hc.h.D().Text(16)) + log.Printf("**(s)** peerD:%s\n", hc.h.PeerD().Text(16)) hc.h.FA() - log.Printf("**(s)** FA:%s\n", hc.h.fa) - - fmt.Fprintf(c, "0x%s\n%08x:%08x\n", hc.h.d.Text(16), + log.Printf("**(s)** FA:%s\n", hc.h.FA()) + + // Send D and cipheropts/conn_opts to peer + fmt.Fprintf(c, "0x%s\n%08x:%08x\n", hc.h.D().Text(16), hc.cipheropts, hc.opts) - hc.r, hc.rm, err = hc.getStream(hc.h.fa) - hc.w, hc.wm, err = hc.getStream(hc.h.fa) + hc.r, hc.rm, err = hc.getStream(hc.h.FA()) + hc.w, hc.wm, err = hc.getStream(hc.h.FA()) return }