KYBER768 KEM works. :O

This commit is contained in:
Russ Magee 2018-10-10 21:12:38 -07:00
parent 4c286ae6c1
commit 231ede1734
3 changed files with 105 additions and 22 deletions

View file

@ -19,7 +19,6 @@ import (
"fmt" "fmt"
"hash" "hash"
"log" "log"
"math/big"
"golang.org/x/crypto/blowfish" "golang.org/x/crypto/blowfish"
"golang.org/x/crypto/twofish" "golang.org/x/crypto/twofish"
@ -33,7 +32,7 @@ import (
/* 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) getStream(keymat *big.Int) (rc cipher.Stream, mc hash.Hash, err error) { func (hc Conn) getStream(keymat []byte) (rc cipher.Stream, mc hash.Hash, err error) {
var key []byte var key []byte
var block cipher.Block var block cipher.Block
var iv []byte var iv []byte
@ -44,23 +43,23 @@ func (hc Conn) getStream(keymat *big.Int) (rc cipher.Stream, mc hash.Hash, err e
// is >= 2*cipher.BlockSize (enough for both key and iv) // is >= 2*cipher.BlockSize (enough for both key and iv)
switch copts { switch copts {
case CAlgAES256: case CAlgAES256:
key = keymat.Bytes()[0:aes.BlockSize] key = keymat[0:aes.BlockSize]
block, err = aes.NewCipher(key) block, err = aes.NewCipher(key)
ivlen = aes.BlockSize ivlen = aes.BlockSize
iv = keymat.Bytes()[aes.BlockSize : aes.BlockSize+ivlen] iv = keymat[aes.BlockSize : aes.BlockSize+ivlen]
rc = cipher.NewOFB(block, iv) rc = cipher.NewOFB(block, iv)
log.Printf("[cipher AES_256 (%d)]\n", copts) log.Printf("[cipher AES_256 (%d)]\n", copts)
break break
case CAlgTwofish128: case CAlgTwofish128:
key = keymat.Bytes()[0:twofish.BlockSize] key = keymat[0:twofish.BlockSize]
block, err = twofish.NewCipher(key) block, err = twofish.NewCipher(key)
ivlen = twofish.BlockSize ivlen = twofish.BlockSize
iv = keymat.Bytes()[twofish.BlockSize : twofish.BlockSize+ivlen] iv = keymat[twofish.BlockSize : twofish.BlockSize+ivlen]
rc = cipher.NewOFB(block, iv) rc = cipher.NewOFB(block, iv)
log.Printf("[cipher TWOFISH_128 (%d)]\n", copts) log.Printf("[cipher TWOFISH_128 (%d)]\n", copts)
break break
case CAlgBlowfish64: case CAlgBlowfish64:
key = keymat.Bytes()[0:blowfish.BlockSize] key = keymat[0:blowfish.BlockSize]
block, err = blowfish.NewCipher(key) block, err = blowfish.NewCipher(key)
ivlen = blowfish.BlockSize ivlen = blowfish.BlockSize
// N.b. Bounds enforcement of differing cipher algorithms // N.b. Bounds enforcement of differing cipher algorithms
@ -72,7 +71,7 @@ func (hc Conn) getStream(keymat *big.Int) (rc cipher.Stream, mc hash.Hash, err e
// //
// I assume the other two check bounds and only // I assume the other two check bounds and only
// copy what's needed whereas blowfish does no such check. // copy what's needed whereas blowfish does no such check.
iv = keymat.Bytes()[blowfish.BlockSize : blowfish.BlockSize+ivlen] iv = keymat[blowfish.BlockSize : blowfish.BlockSize+ivlen]
rc = cipher.NewOFB(block, iv) rc = cipher.NewOFB(block, iv)
log.Printf("[cipher BLOWFISH_64 (%d)]\n", copts) log.Printf("[cipher BLOWFISH_64 (%d)]\n", copts)
break break

View file

@ -46,6 +46,7 @@ import (
"time" "time"
"blitter.com/go/hkexsh/herradurakex" "blitter.com/go/hkexsh/herradurakex"
kyber "git.schwanenlied.me/yawning/kyber.git"
) )
/*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/
@ -171,12 +172,14 @@ func _new(kexAlg KEXAlg, conn *net.Conn) (hc *Conn, e error) {
// Set up KEx/KEM-specifics // Set up KEx/KEM-specifics
switch hc.kex { switch hc.kex {
case KEX_HERRADURA: case KEX_HERRADURA:
default: return hc, nil //HKExAcceptSetup(hc.c, hc)
return hc, HKExAcceptSetup(hc.c, hc)
log.Printf("[KEx alg %d accepted]\n", kexAlg) log.Printf("[KEx alg %d accepted]\n", kexAlg)
case KEX_KYBER768: case KEX_KYBER768:
fmt.Println("KYBER768: TODO") return hc, nil //Kyber768AcceptSetup(hc.c, hc)
return nil, errors.New("KEx Setup failed") log.Printf("[KEx alg %d accepted]\n", kexAlg)
default:
return hc, nil //HKExAcceptSetup(hc.c, hc)
log.Printf("[KEx alg %d accepted]\n", kexAlg)
} }
return return
} }
@ -222,8 +225,53 @@ func (hc *Conn) applyConnExtensions(extensions ...string) {
} }
} }
// randReader wraps rand.Read() in a struct that implements io.Reader
// for use by the Kyber KEM methods.
type randReader struct {
}
func (r randReader) Read(b []byte) (n int, e error) {
n, e = rand.Read(b)
return
}
func Kyber768DialSetup(c net.Conn, hc *Conn) (err error) { func Kyber768DialSetup(c net.Conn, hc *Conn) (err error) {
return errors.New("NOT IMPLEMENTED") //h := hkex.New(0, 0)
// Send hkexnet.Conn parameters to remote side
// Alice, step 1: Generate a key pair.
r := new(randReader)
alicePublicKey, alicePrivateKey, err := kyber.Kyber768.GenerateKeyPair(r)
if err != nil {
panic(err)
}
// Alice, step 2: Send the public key to Bob
fmt.Fprintf(c, "0x%x\n%08x:%08x\n", alicePublicKey.Bytes(),
hc.cipheropts, hc.opts)
// [Bob, step 1-3], from which we read cipher text
b := big.NewInt(0)
_, err = fmt.Fscanln(c, b)
if err != nil {
return err
}
log.Printf("[Got server ciphertext:0x%x]\n", b.Bytes())
// Read cipheropts, session opts
_, err = fmt.Fscanf(c, "%08x:%08x\n",
&hc.cipheropts, &hc.opts)
if err != nil {
return err
}
// Alice, step 3: Decrypt the KEM cipher text.
aliceSharedSecret := alicePrivateKey.KEMDecrypt(b.Bytes())
log.Printf("[Derived sharedSecret:0x%x]\n", aliceSharedSecret)
hc.r, hc.rm, err = hc.getStream(aliceSharedSecret)
hc.w, hc.wm, err = hc.getStream(aliceSharedSecret)
return
} }
func HKExDialSetup(c net.Conn, hc *Conn) (err error) { func HKExDialSetup(c net.Conn, hc *Conn) (err error) {
@ -251,13 +299,47 @@ func HKExDialSetup(c net.Conn, hc *Conn) (err error) {
h.ComputeFA() h.ComputeFA()
log.Printf("**(c)** FA:%s\n", h.FA()) log.Printf("**(c)** FA:%s\n", h.FA())
hc.r, hc.rm, err = hc.getStream(h.FA()) hc.r, hc.rm, err = hc.getStream(h.FA().Bytes())
hc.w, hc.wm, err = hc.getStream(h.FA()) hc.w, hc.wm, err = hc.getStream(h.FA().Bytes())
return return
} }
func Kyber768AcceptSetup(c *net.Conn, hc *Conn) (err error) { func Kyber768AcceptSetup(c *net.Conn, hc *Conn) (err error) {
return errors.New("NOT IMPLEMENTED") //h := hkex.New(0, 0)
// Bob, step 1: Deserialize Alice's public key from the binary encoding.
alicePublicKey := big.NewInt(0)
_, err = fmt.Fscanln(*c, alicePublicKey)
log.Printf("[Got client pubKey:0x%x\n]", alicePublicKey)
if err != nil {
return err
}
_, err = fmt.Fscanf(*c, "%08x:%08x\n",
&hc.cipheropts, &hc.opts)
log.Printf("[Got cipheropts, opts:%v, %v]", hc.cipheropts, hc.opts)
if err != nil {
return err
}
peerPublicKey, err := kyber.Kyber768.PublicKeyFromBytes(alicePublicKey.Bytes())
if err != nil {
panic(err)
}
// Bob, step 2: Generate the KEM cipher text and shared secret.
r := new(randReader)
cipherText, bobSharedSecret, err := peerPublicKey.KEMEncrypt(r)
if err != nil {
panic(err)
}
// Bob, step 3: Send the cipher text to Alice (Not shown).
fmt.Fprintf(*c, "0x%x\n%08x:%08x\n", cipherText,
hc.cipheropts, hc.opts)
log.Printf("[Derived sharedSecret:0x%x]\n", bobSharedSecret)
hc.r, hc.rm, err = hc.getStream(bobSharedSecret)
hc.w, hc.wm, err = hc.getStream(bobSharedSecret)
return
} }
func HKExAcceptSetup(c *net.Conn, hc *Conn) (err error) { func HKExAcceptSetup(c *net.Conn, hc *Conn) (err error) {
@ -286,8 +368,8 @@ func HKExAcceptSetup(c *net.Conn, hc *Conn) (err error) {
fmt.Fprintf(*c, "0x%s\n%08x:%08x\n", h.D().Text(16), fmt.Fprintf(*c, "0x%s\n%08x:%08x\n", h.D().Text(16),
hc.cipheropts, hc.opts) hc.cipheropts, hc.opts)
hc.r, hc.rm, err = hc.getStream(h.FA()) hc.r, hc.rm, err = hc.getStream(h.FA().Bytes())
hc.w, hc.wm, err = hc.getStream(h.FA()) hc.w, hc.wm, err = hc.getStream(h.FA().Bytes())
return return
} }

View file

@ -351,8 +351,9 @@ func main() {
var gopt bool //login via password, asking server to generate authToken var gopt bool //login via password, asking server to generate authToken
var dbg bool var dbg bool
var shellMode bool // if true act as shell, else file copier var shellMode bool // if true act as shell, else file copier
var cAlg string var cAlg string //cipher alg
var hAlg string var hAlg string //hmac alg
var kAlg string //KEX/KEM alg
var server string var server string
var port uint var port uint
var cmdStr string var cmdStr string
@ -373,6 +374,7 @@ func main() {
flag.BoolVar(&dbg, "d", false, "debug logging") flag.BoolVar(&dbg, "d", false, "debug logging")
flag.StringVar(&cAlg, "c", "C_AES_256", "`cipher` [\"C_AES_256\" | \"C_TWOFISH_128\" | \"C_BLOWFISH_64\"]") flag.StringVar(&cAlg, "c", "C_AES_256", "`cipher` [\"C_AES_256\" | \"C_TWOFISH_128\" | \"C_BLOWFISH_64\"]")
flag.StringVar(&hAlg, "m", "H_SHA256", "`hmac` [\"H_SHA256\"]") flag.StringVar(&hAlg, "m", "H_SHA256", "`hmac` [\"H_SHA256\"]")
flag.StringVar(&kAlg, "k", "KEX_HERRADURA", "`kex` [\"KEX_HERRADURA\" | \"KEX_KYBER768\"]")
flag.UintVar(&port, "p", 2000, "`port`") flag.UintVar(&port, "p", 2000, "`port`")
//flag.StringVar(&authCookie, "a", "", "auth cookie") //flag.StringVar(&authCookie, "a", "", "auth cookie")
flag.BoolVar(&chaffEnabled, "e", true, "enabled chaff pkts (default true)") flag.BoolVar(&chaffEnabled, "e", true, "enabled chaff pkts (default true)")
@ -543,7 +545,7 @@ func main() {
} }
} }
conn, err := hkexnet.Dial("tcp", server, "KEX_HERRADURA", cAlg, hAlg) conn, err := hkexnet.Dial("tcp", server, cAlg, hAlg, kAlg)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
panic(err) panic(err)