mirror of https://gogs.blitter.com/RLabs/xs
-Added client -c option to pass cipher alg
-Note about blowfish iv len (lack of) bounds check in .NewOFB(); -TODO added to enforce keymat from HKex >= 2*chosen cipher blocksize (assuming keylen == blocksize -- might not be true for all future algs)
This commit is contained in:
parent
aaa99360be
commit
5493921e9f
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
hkex "blitter.com/herradurakex"
|
hkex "blitter.com/herradurakex"
|
||||||
|
@ -13,7 +14,12 @@ import (
|
||||||
// encrypt/decrypt is done within the type.
|
// encrypt/decrypt is done within the type.
|
||||||
// Compare to 'clientp.go' in this directory to see the equivalence.
|
// Compare to 'clientp.go' in this directory to see the equivalence.
|
||||||
func main() {
|
func main() {
|
||||||
conn, err := hkex.Dial("tcp", "localhost:2000", "C_TWOFISH_128")
|
var cAlg string
|
||||||
|
|
||||||
|
flag.StringVar(&cAlg, "c", "C_AES_256", "cipher [\"C_AES_256\" | \"C_TWOFISH_128\" | \"C_BLOWFISH_64\"]")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
conn, err := hkex.Dial("tcp", "localhost:2000", cAlg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// handle error
|
// handle error
|
||||||
fmt.Println("Err!")
|
fmt.Println("Err!")
|
||||||
|
|
37
hkexchan.go
37
hkexchan.go
|
@ -28,6 +28,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/blowfish"
|
||||||
"golang.org/x/crypto/twofish"
|
"golang.org/x/crypto/twofish"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@ import (
|
||||||
const (
|
const (
|
||||||
C_AES_256 = iota
|
C_AES_256 = iota
|
||||||
C_TWOFISH_128 // golang.org/x/crypto/twofish
|
C_TWOFISH_128 // golang.org/x/crypto/twofish
|
||||||
|
C_BLOWFISH_64 // golang.org/x/crypto/blowfish
|
||||||
C_NONE_DISALLOWED
|
C_NONE_DISALLOWED
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -52,31 +54,48 @@ been negotiated via hkexnet.go
|
||||||
func (hc Conn) getStream(keymat *big.Int) (ret cipher.Stream) {
|
func (hc Conn) getStream(keymat *big.Int) (ret cipher.Stream) {
|
||||||
var key []byte
|
var key []byte
|
||||||
var block cipher.Block
|
var block cipher.Block
|
||||||
|
var ivlen int
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
copts := hc.cipheropts & 0xFF
|
copts := hc.cipheropts & 0xFF
|
||||||
|
// TODO: each cipher alg case should ensure len(keymat.Bytes())
|
||||||
|
// is >= 2*cipher.BlockSize (enough for both key and iv)
|
||||||
switch copts {
|
switch copts {
|
||||||
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)
|
||||||
|
ivlen = aes.BlockSize
|
||||||
iv := make([]byte, aes.BlockSize)
|
iv := make([]byte, aes.BlockSize)
|
||||||
//if _, err = io.ReadFull(crand.Reader, iv); err != nil {
|
iv = keymat.Bytes()[aes.BlockSize : aes.BlockSize+ivlen]
|
||||||
// panic(err)
|
|
||||||
//}
|
|
||||||
iv = keymat.Bytes()[aes.BlockSize:]
|
|
||||||
ret = cipher.NewOFB(block, iv)
|
ret = cipher.NewOFB(block, iv)
|
||||||
fmt.Printf("[cipher AES_256 (%d)]\n", copts)
|
fmt.Printf("[cipher AES_256 (%d)]\n", copts)
|
||||||
break
|
break
|
||||||
case C_TWOFISH_128:
|
case C_TWOFISH_128:
|
||||||
key = keymat.Bytes()[0:twofish.BlockSize]
|
key = keymat.Bytes()[0:twofish.BlockSize]
|
||||||
block, err = twofish.NewCipher(key)
|
block, err = twofish.NewCipher(key)
|
||||||
|
ivlen = twofish.BlockSize
|
||||||
iv := make([]byte, twofish.BlockSize)
|
iv := make([]byte, twofish.BlockSize)
|
||||||
//if _, err = io.ReadFull(crand.Reader, iv); err != nil {
|
iv = keymat.Bytes()[twofish.BlockSize : twofish.BlockSize+ivlen]
|
||||||
// panic(err)
|
|
||||||
//}
|
|
||||||
iv = keymat.Bytes()[twofish.BlockSize:]
|
|
||||||
ret = cipher.NewOFB(block, iv)
|
ret = cipher.NewOFB(block, iv)
|
||||||
fmt.Printf("[cipher TWOFISH_256 (%d)]\n", copts)
|
fmt.Printf("[cipher TWOFISH_128 (%d)]\n", copts)
|
||||||
|
break
|
||||||
|
case C_BLOWFISH_64:
|
||||||
|
key = keymat.Bytes()[0:blowfish.BlockSize]
|
||||||
|
block, err = blowfish.NewCipher(key)
|
||||||
|
ivlen = blowfish.BlockSize
|
||||||
|
iv := make([]byte, blowfish.BlockSize)
|
||||||
|
// N.b. Bounds enforcement of differing cipher algorithms
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// cipher/aes and x/cipher/twofish appear to allow one to
|
||||||
|
// pass an iv larger than the blockSize harmlessly to
|
||||||
|
// cipher.NewOFB(); x/cipher/blowfish implementation will
|
||||||
|
// segfault here if len(iv) is not exactly blowfish.BlockSize.
|
||||||
|
//
|
||||||
|
// 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]
|
||||||
|
ret = cipher.NewOFB(block, iv)
|
||||||
|
fmt.Printf("[cipher BLOWFISH_64 (%d)]\n", copts)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
fmt.Printf("DOOFUS SET A VALID CIPHER ALG (%d)\n", copts)
|
fmt.Printf("DOOFUS SET A VALID CIPHER ALG (%d)\n", copts)
|
||||||
|
|
|
@ -89,6 +89,11 @@ func (hc *Conn) applyConnExtensions(extensions ...string) {
|
||||||
hc.cipheropts &= (0xFFFFFF00)
|
hc.cipheropts &= (0xFFFFFF00)
|
||||||
hc.cipheropts |= C_TWOFISH_128
|
hc.cipheropts |= C_TWOFISH_128
|
||||||
break
|
break
|
||||||
|
case "C_BLOWFISH_64":
|
||||||
|
fmt.Println("[extension arg = C_BLOWFISH_64]")
|
||||||
|
hc.cipheropts &= (0xFFFFFF00)
|
||||||
|
hc.cipheropts |= C_BLOWFISH_64
|
||||||
|
break
|
||||||
case "H_SHA256":
|
case "H_SHA256":
|
||||||
hc.cipheropts &= (0xFFFF00FF)
|
hc.cipheropts &= (0xFFFF00FF)
|
||||||
hc.cipheropts |= (H_SHA256 << 8)
|
hc.cipheropts |= (H_SHA256 << 8)
|
||||||
|
|
Loading…
Reference in New Issue