mirror of https://gogs.blitter.com/RLabs/xs
				
				
				
			KYBER768 KEM works. :O
This commit is contained in:
		
							parent
							
								
									4c286ae6c1
								
							
						
					
					
						commit
						231ede1734
					
				| 
						 | 
				
			
			@ -19,7 +19,6 @@ import (
 | 
			
		|||
	"fmt"
 | 
			
		||||
	"hash"
 | 
			
		||||
	"log"
 | 
			
		||||
	"math/big"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/crypto/blowfish"
 | 
			
		||||
	"golang.org/x/crypto/twofish"
 | 
			
		||||
| 
						 | 
				
			
			@ -33,7 +32,7 @@ import (
 | 
			
		|||
/* Support functionality to set up encryption after a channel has
 | 
			
		||||
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 block cipher.Block
 | 
			
		||||
	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)
 | 
			
		||||
	switch copts {
 | 
			
		||||
	case CAlgAES256:
 | 
			
		||||
		key = keymat.Bytes()[0:aes.BlockSize]
 | 
			
		||||
		key = keymat[0:aes.BlockSize]
 | 
			
		||||
		block, err = aes.NewCipher(key)
 | 
			
		||||
		ivlen = aes.BlockSize
 | 
			
		||||
		iv = keymat.Bytes()[aes.BlockSize : aes.BlockSize+ivlen]
 | 
			
		||||
		iv = keymat[aes.BlockSize : aes.BlockSize+ivlen]
 | 
			
		||||
		rc = cipher.NewOFB(block, iv)
 | 
			
		||||
		log.Printf("[cipher AES_256 (%d)]\n", copts)
 | 
			
		||||
		break
 | 
			
		||||
	case CAlgTwofish128:
 | 
			
		||||
		key = keymat.Bytes()[0:twofish.BlockSize]
 | 
			
		||||
		key = keymat[0:twofish.BlockSize]
 | 
			
		||||
		block, err = twofish.NewCipher(key)
 | 
			
		||||
		ivlen = twofish.BlockSize
 | 
			
		||||
		iv = keymat.Bytes()[twofish.BlockSize : twofish.BlockSize+ivlen]
 | 
			
		||||
		iv = keymat[twofish.BlockSize : twofish.BlockSize+ivlen]
 | 
			
		||||
		rc = cipher.NewOFB(block, iv)
 | 
			
		||||
		log.Printf("[cipher TWOFISH_128 (%d)]\n", copts)
 | 
			
		||||
		break
 | 
			
		||||
	case CAlgBlowfish64:
 | 
			
		||||
		key = keymat.Bytes()[0:blowfish.BlockSize]
 | 
			
		||||
		key = keymat[0:blowfish.BlockSize]
 | 
			
		||||
		block, err = blowfish.NewCipher(key)
 | 
			
		||||
		ivlen = blowfish.BlockSize
 | 
			
		||||
		// 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
 | 
			
		||||
		// 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)
 | 
			
		||||
		log.Printf("[cipher BLOWFISH_64 (%d)]\n", copts)
 | 
			
		||||
		break
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,6 +46,7 @@ import (
 | 
			
		|||
	"time"
 | 
			
		||||
 | 
			
		||||
	"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
 | 
			
		||||
	switch hc.kex {
 | 
			
		||||
	case KEX_HERRADURA:
 | 
			
		||||
	default:
 | 
			
		||||
		return hc, HKExAcceptSetup(hc.c, hc)
 | 
			
		||||
		return hc, nil //HKExAcceptSetup(hc.c, hc)
 | 
			
		||||
		log.Printf("[KEx alg %d accepted]\n", kexAlg)
 | 
			
		||||
	case KEX_KYBER768:
 | 
			
		||||
		fmt.Println("KYBER768: TODO")
 | 
			
		||||
		return nil, errors.New("KEx Setup failed")
 | 
			
		||||
		return hc, nil //Kyber768AcceptSetup(hc.c, hc)
 | 
			
		||||
		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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
	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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -251,13 +299,47 @@ func HKExDialSetup(c net.Conn, hc *Conn) (err error) {
 | 
			
		|||
	h.ComputeFA()
 | 
			
		||||
	log.Printf("**(c)** FA:%s\n", h.FA())
 | 
			
		||||
 | 
			
		||||
	hc.r, hc.rm, err = hc.getStream(h.FA())
 | 
			
		||||
	hc.w, hc.wm, err = hc.getStream(h.FA())
 | 
			
		||||
	hc.r, hc.rm, err = hc.getStream(h.FA().Bytes())
 | 
			
		||||
	hc.w, hc.wm, err = hc.getStream(h.FA().Bytes())
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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) {
 | 
			
		||||
| 
						 | 
				
			
			@ -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),
 | 
			
		||||
		hc.cipheropts, hc.opts)
 | 
			
		||||
 | 
			
		||||
	hc.r, hc.rm, err = hc.getStream(h.FA())
 | 
			
		||||
	hc.w, hc.wm, err = hc.getStream(h.FA())
 | 
			
		||||
	hc.r, hc.rm, err = hc.getStream(h.FA().Bytes())
 | 
			
		||||
	hc.w, hc.wm, err = hc.getStream(h.FA().Bytes())
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -351,8 +351,9 @@ func main() {
 | 
			
		|||
	var gopt bool //login via password, asking server to generate authToken
 | 
			
		||||
	var dbg bool
 | 
			
		||||
	var shellMode bool // if true act as shell, else file copier
 | 
			
		||||
	var cAlg string
 | 
			
		||||
	var hAlg string
 | 
			
		||||
	var cAlg string    //cipher alg
 | 
			
		||||
	var hAlg string    //hmac alg
 | 
			
		||||
	var kAlg string    //KEX/KEM alg
 | 
			
		||||
	var server string
 | 
			
		||||
	var port uint
 | 
			
		||||
	var cmdStr string
 | 
			
		||||
| 
						 | 
				
			
			@ -373,6 +374,7 @@ func main() {
 | 
			
		|||
	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(&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.StringVar(&authCookie, "a", "", "auth cookie")
 | 
			
		||||
	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 {
 | 
			
		||||
		fmt.Println(err)
 | 
			
		||||
		panic(err)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue