net.go 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610
  1. // xsnet.go - net.Conn compatible channel setup with encrypted/HMAC
  2. // negotiation
  3. // Copyright (c) 2017-2020 Russell Magee
  4. // Licensed under the terms of the MIT license (see LICENSE.mit in this
  5. // distribution)
  6. //
  7. // golang implementation by Russ Magee (rmagee_at_gmail.com)
  8. package xsnet
  9. // Implementation of HKEx-wrapped versions of the golang standard
  10. // net package interfaces, allowing clients and servers to simply replace
  11. // 'net.Dial' and 'net.Listen' with 'hkex.Dial' and 'hkex.Listen'
  12. // (though some extra methods are implemented and must be used
  13. // for things outside of the scope of plain sockets).
  14. // DESIGN PRINCIPLE: There shall be no protocol features which enable
  15. // downgrade attacks. The server shall have final authority to accept or
  16. // reject any and all proposed KEx and connection parameters proposed by
  17. // clients at setup. Action on denial shall be a simple server disconnect
  18. // with possibly a status code sent so client can determine why connection
  19. // was denied (compare to how failed auth is communicated to client).
  20. import (
  21. "bytes"
  22. "crypto/cipher"
  23. "encoding/binary"
  24. "encoding/hex"
  25. "errors"
  26. "fmt"
  27. "hash"
  28. "io"
  29. "io/ioutil"
  30. "log"
  31. "math/big"
  32. "math/rand"
  33. "net"
  34. "strings"
  35. "sync"
  36. "time"
  37. hkex "blitter.com/go/herradurakex"
  38. "blitter.com/go/kyber"
  39. "blitter.com/go/newhope"
  40. "blitter.com/go/xs/logger"
  41. frodo "github.com/kuking/go-frodokem"
  42. )
  43. /*---------------------------------------------------------------------*/
  44. const PAD_SZ = 32 // max size of padding applied to each packet
  45. const HMAC_CHK_SZ = 8 // leading bytes of HMAC to xmit for verification
  46. type (
  47. WinSize struct {
  48. Rows uint16
  49. Cols uint16
  50. }
  51. // chaffconfig captures attributes used to send chaff packets betwixt
  52. // client and server connections, to obscure true traffic timing and
  53. // patterns
  54. // see: https://en.wikipedia.org/wiki/chaff_(countermeasure)
  55. ChaffConfig struct {
  56. shutdown bool //set to inform chaffHelper to shut down
  57. enabled bool
  58. msecsMin uint //msecs min interval
  59. msecsMax uint //msecs max interval
  60. szMax uint // max size in bytes
  61. }
  62. // Conn is a connection wrapping net.Conn with KEX & session state
  63. Conn struct {
  64. kex KEXAlg // KEX/KEM proposal (client -> server)
  65. m *sync.Mutex // (internal)
  66. c *net.Conn // which also implements io.Reader, io.Writer, ...
  67. logCipherText bool // somewhat expensive, for debugging
  68. logPlainText bool // INSECURE and somewhat expensive, for debugging
  69. logTunActivity bool
  70. cipheropts uint32 // post-KEx cipher/hmac options
  71. opts uint32 // post-KEx protocol options (caller-defined)
  72. WinCh chan WinSize
  73. Rows uint16
  74. Cols uint16
  75. chaff ChaffConfig
  76. tuns *map[uint16](*TunEndpoint)
  77. closeStat *CSOType // close status (CSOExitStatus)
  78. r cipher.Stream //read cipherStream
  79. rm hash.Hash
  80. w cipher.Stream //write cipherStream
  81. wm hash.Hash
  82. dBuf *bytes.Buffer //decrypt buffer for Read()
  83. }
  84. )
  85. var (
  86. Log *logger.Writer // reg. syslog output (no -d)
  87. )
  88. // Return string (suitable as map key) for a tunnel endpoint
  89. func (t *TunEndpoint) String() string {
  90. return fmt.Sprintf("[%d:%s:%d]", t.Lport, t.Peer, t.Rport)
  91. }
  92. func (k *KEXAlg) String() string {
  93. switch *k {
  94. case KEX_HERRADURA256:
  95. return "KEX_HERRADURA256"
  96. case KEX_HERRADURA512:
  97. return "KEX_HERRADURA512"
  98. case KEX_HERRADURA1024:
  99. return "KEX_HERRADURA1024"
  100. case KEX_HERRADURA2048:
  101. return "KEX_HERRADURA2048"
  102. case KEX_KYBER512:
  103. return "KEX_KYBER512"
  104. case KEX_KYBER768:
  105. return "KEX_KYBER768"
  106. case KEX_KYBER1024:
  107. return "KEX_KYBER1024"
  108. case KEX_NEWHOPE:
  109. return "KEX_NEWHOPE"
  110. case KEX_NEWHOPE_SIMPLE:
  111. return "KEX_NEWHOPE_SIMPLE"
  112. case KEX_FRODOKEM_1344AES:
  113. return "KEX_FRODOKEM_1344AES"
  114. case KEX_FRODOKEM_1344SHAKE:
  115. return "KEX_FRODOKEM_1344SHAKE"
  116. case KEX_FRODOKEM_976AES:
  117. return "KEX_FRODOKEM_976AES"
  118. case KEX_FRODOKEM_976SHAKE:
  119. return "KEX_FRODOKEM_976SHAKE"
  120. default:
  121. return "KEX_ERR_UNK"
  122. }
  123. }
  124. func (hc *Conn) CAlg() CSCipherAlg {
  125. return CSCipherAlg(hc.cipheropts & 0x0FF)
  126. }
  127. func (c *CSCipherAlg) String() string {
  128. switch *c & 0x0FF {
  129. case CAlgAES256:
  130. return "C_AES_256"
  131. case CAlgTwofish128:
  132. return "C_TWOFISH_128"
  133. case CAlgBlowfish64:
  134. return "C_BLOWFISH_64"
  135. case CAlgCryptMT1:
  136. return "C_CRYPTMT1"
  137. case CAlgChaCha20_12:
  138. return "C_CHACHA20_12"
  139. default:
  140. return "C_ERR_UNK"
  141. }
  142. }
  143. func (hc *Conn) HAlg() CSHmacAlg {
  144. return CSHmacAlg((hc.cipheropts >> 8) & 0x0FF)
  145. }
  146. func (h *CSHmacAlg) String() string {
  147. switch (*h >> 8) & 0x0FF {
  148. case HmacSHA256:
  149. return "H_SHA256"
  150. case HmacSHA512:
  151. return "C_SHA512"
  152. default:
  153. return "H_ERR_UNK"
  154. }
  155. }
  156. func _initLogging(d bool, c string, f logger.Priority) {
  157. if Log == nil {
  158. Log, _ = logger.New(f, fmt.Sprintf("%s:xsnet", c))
  159. }
  160. if d {
  161. log.SetFlags(0) // syslog will have date,time
  162. log.SetOutput(Log)
  163. } else {
  164. log.SetOutput(ioutil.Discard)
  165. }
  166. }
  167. func Init(d bool, c string, f logger.Priority) {
  168. _initLogging(d, c, f)
  169. }
  170. func (hc *Conn) Lock() {
  171. hc.m.Lock()
  172. }
  173. func (hc *Conn) Unlock() {
  174. hc.m.Unlock()
  175. }
  176. func (hc *Conn) KEX() KEXAlg {
  177. return hc.kex
  178. }
  179. func (hc *Conn) GetStatus() CSOType {
  180. return *hc.closeStat
  181. }
  182. func (hc *Conn) SetStatus(stat CSOType) {
  183. *hc.closeStat = stat
  184. log.Println("closeStat:", *hc.closeStat)
  185. }
  186. // ConnOpts returns the cipher/hmac options value, which is sent to the
  187. // peer but is not itself part of the KEx.
  188. //
  189. // (Used for protocol-level negotiations after KEx such as
  190. // cipher/HMAC algorithm options etc.)
  191. func (hc *Conn) ConnOpts() uint32 {
  192. return hc.cipheropts
  193. }
  194. // SetConnOpts sets the cipher/hmac options value, which is sent to the
  195. // peer as part of KEx but not part of the KEx itself.
  196. //
  197. // opts - bitfields for cipher and hmac alg. to use after KEx
  198. func (hc *Conn) SetConnOpts(copts uint32) {
  199. hc.cipheropts = copts
  200. }
  201. // Opts returns the protocol options value, which is sent to the peer
  202. // but is not itself part of the KEx or connection (cipher/hmac) setup.
  203. //
  204. // Consumers of this lib may use this for protocol-level options not part
  205. // of the KEx or encryption info used by the connection.
  206. func (hc Conn) Opts() uint32 {
  207. return hc.opts
  208. }
  209. // SetOpts sets the protocol options value, which is sent to the peer
  210. // but is not itself part of the KEx or connection (cipher/hmac) setup.
  211. //
  212. // Consumers of this lib may use this for protocol-level options not part
  213. // of the KEx of encryption info used by the connection.
  214. //
  215. // opts - a uint32, caller-defined
  216. func (hc *Conn) SetOpts(opts uint32) {
  217. hc.opts = opts
  218. }
  219. // Return a new xsnet.Conn
  220. //
  221. // Note this is internal: use Dial() or Accept()
  222. func _new(kexAlg KEXAlg, conn *net.Conn) (hc *Conn, e error) {
  223. // Set up stuff common to all KEx/KEM types
  224. hc = &Conn{kex: kexAlg,
  225. m: &sync.Mutex{},
  226. c: conn,
  227. closeStat: new(CSOType),
  228. WinCh: make(chan WinSize, 1),
  229. dBuf: new(bytes.Buffer)}
  230. tempMap := make(map[uint16]*TunEndpoint)
  231. hc.tuns = &tempMap
  232. *hc.closeStat = CSEStillOpen // open or prematurely-closed status
  233. // Set up KEx/KEM-specifics
  234. switch kexAlg {
  235. case KEX_HERRADURA256:
  236. fallthrough
  237. case KEX_HERRADURA512:
  238. fallthrough
  239. case KEX_HERRADURA1024:
  240. fallthrough
  241. case KEX_HERRADURA2048:
  242. fallthrough
  243. case KEX_KYBER512:
  244. fallthrough
  245. case KEX_KYBER768:
  246. fallthrough
  247. case KEX_KYBER1024:
  248. fallthrough
  249. case KEX_NEWHOPE:
  250. fallthrough
  251. case KEX_NEWHOPE_SIMPLE:
  252. fallthrough
  253. case KEX_FRODOKEM_1344AES:
  254. fallthrough
  255. case KEX_FRODOKEM_1344SHAKE:
  256. fallthrough
  257. case KEX_FRODOKEM_976AES:
  258. fallthrough
  259. case KEX_FRODOKEM_976SHAKE:
  260. log.Printf("[KEx alg %d accepted]\n", kexAlg)
  261. default:
  262. // UNREACHABLE: _getkexalgnum() guarantees a valid KEX value
  263. hc.kex = KEX_HERRADURA512
  264. log.Printf("[KEx alg %d ?? defaults to %d]\n", kexAlg, hc.kex)
  265. }
  266. //hc.logCipherText = true // !!! DEBUGGING ONLY !!! NEVER DEPLOY this uncommented !!!
  267. return
  268. }
  269. // applyConnExtensions processes optional Dial() negotiation
  270. // parameters. See also getkexalgnum().
  271. //
  272. // Currently defined extension values
  273. //
  274. // KEx algs
  275. //
  276. // KEX_HERRADURA256 KEX_HERRADURA512 KEX_HERRADURA1024 KEX_HERRADURA2048
  277. //
  278. // KEX_KYBER512 KEX_KYBER768 KEX_KYBER1024
  279. //
  280. // KEX_NEWHOPE KEX_NEWHOPE_SIMPLE
  281. //
  282. // Session (symmetric) crypto
  283. //
  284. // C_AES_256 C_TWOFISH_128 C_BLOWFISH_128 C_CRYPTMT1 C_CHACHA20_12
  285. //
  286. // Session HMACs
  287. //
  288. // H_SHA256 H_SHA512
  289. func (hc *Conn) applyConnExtensions(extensions ...string) {
  290. for _, s := range extensions {
  291. switch s {
  292. case "C_AES_256":
  293. log.Println("[extension arg = C_AES_256]")
  294. hc.cipheropts &= (0xFFFFFF00)
  295. hc.cipheropts |= CAlgAES256
  296. case "C_TWOFISH_128":
  297. log.Println("[extension arg = C_TWOFISH_128]")
  298. hc.cipheropts &= (0xFFFFFF00)
  299. hc.cipheropts |= CAlgTwofish128
  300. case "C_BLOWFISH_64":
  301. log.Println("[extension arg = C_BLOWFISH_64]")
  302. hc.cipheropts &= (0xFFFFFF00)
  303. hc.cipheropts |= CAlgBlowfish64
  304. case "C_CRYPTMT1":
  305. log.Println("[extension arg = C_CRYPTMT1]")
  306. hc.cipheropts &= (0xFFFFFF00)
  307. hc.cipheropts |= CAlgCryptMT1
  308. case "C_CHACHA20_12":
  309. log.Println("[extension arg = C_CHACHA20_12]")
  310. hc.cipheropts &= (0xFFFFFF00)
  311. hc.cipheropts |= CAlgChaCha20_12
  312. case "H_SHA256":
  313. log.Println("[extension arg = H_SHA256]")
  314. hc.cipheropts &= (0xFFFF00FF)
  315. hc.cipheropts |= (HmacSHA256 << 8)
  316. case "H_SHA512":
  317. log.Println("[extension arg = H_SHA512]")
  318. hc.cipheropts &= (0xFFFF00FF)
  319. hc.cipheropts |= (HmacSHA512 << 8)
  320. //default:
  321. // log.Printf("[Dial ext \"%s\" ignored]\n", s)
  322. }
  323. }
  324. }
  325. func getkexalgnum(extensions ...string) (k KEXAlg) {
  326. k = KEX_HERRADURA512 // default
  327. for _, s := range extensions {
  328. switch s {
  329. case "KEX_HERRADURA256":
  330. k = KEX_HERRADURA256
  331. break //out of for
  332. case "KEX_HERRADURA512":
  333. k = KEX_HERRADURA512
  334. break //out of for
  335. case "KEX_HERRADURA1024":
  336. k = KEX_HERRADURA1024
  337. break //out of for
  338. case "KEX_HERRADURA2048":
  339. k = KEX_HERRADURA2048
  340. break //out of for
  341. case "KEX_KYBER512":
  342. k = KEX_KYBER512
  343. break //out of for
  344. case "KEX_KYBER768":
  345. k = KEX_KYBER768
  346. break //out of for
  347. case "KEX_KYBER1024":
  348. k = KEX_KYBER1024
  349. break //out of for
  350. case "KEX_NEWHOPE":
  351. k = KEX_NEWHOPE
  352. break //out of for
  353. case "KEX_NEWHOPE_SIMPLE":
  354. k = KEX_NEWHOPE_SIMPLE
  355. break //out of for
  356. case "KEX_FRODOKEM_1344AES":
  357. k = KEX_FRODOKEM_1344AES
  358. break //out of for
  359. case "KEX_FRODOKEM_1344SHAKE":
  360. k = KEX_FRODOKEM_1344SHAKE
  361. break //out of for
  362. case "KEX_FRODOKEM_976AES":
  363. k = KEX_FRODOKEM_976AES
  364. break //out of for
  365. case "KEX_FRODOKEM_976SHAKE":
  366. k = KEX_FRODOKEM_976SHAKE
  367. break //out of for
  368. }
  369. }
  370. return
  371. }
  372. func FrodoKEMDialSetup(c io.ReadWriter, hc *Conn) (err error) {
  373. // Send xsnet.Conn parameters to remote side
  374. // Alice, step 1: Generate a key pair.
  375. var kem frodo.FrodoKEM
  376. switch hc.kex {
  377. case KEX_FRODOKEM_1344AES:
  378. kem = frodo.Frodo1344AES()
  379. case KEX_FRODOKEM_1344SHAKE:
  380. kem = frodo.Frodo1344SHAKE()
  381. case KEX_FRODOKEM_976AES:
  382. kem = frodo.Frodo976AES()
  383. default:
  384. kem = frodo.Frodo976SHAKE()
  385. }
  386. pubA, secA := kem.Keygen() // pA
  387. // Alice, step 2: Send the public key (na,ea) to Bob
  388. n, err := fmt.Fprintf(c, "0x%x\n", pubA)
  389. if err != nil {
  390. panic(err)
  391. }
  392. if n < len(pubA) {
  393. panic(errors.New("incomplete Fprintf() of pubA"))
  394. }
  395. // (... and send cipher, connection opts)
  396. fmt.Fprintf(c, "0x%x:0x%x\n", hc.cipheropts, hc.opts)
  397. // [Bob does the same and sends use a public key (nb, eb)
  398. pubB_bigint := big.NewInt(0)
  399. _, err = fmt.Fscanf(c, "0x%x\n", pubB_bigint)
  400. pubB := pubB_bigint.Bytes()
  401. // (... and sends us cipher, connection opts)
  402. _, err = fmt.Fscanf(c, "0x%x:0x%x\n",
  403. &hc.cipheropts, &hc.opts)
  404. if err != nil {
  405. return err
  406. }
  407. // Alice, step 3: Create ctAtoB, shareA
  408. ctAtoB, shareA, err := kem.Encapsulate(pubB)
  409. if err != nil {
  410. return err
  411. }
  412. // Alice, step 4: Send ctAtoB to Bob
  413. fmt.Fprintf(c, "0x%x\n", ctAtoB)
  414. // Alice, step 5: Receive ctBtoA from Bob
  415. ctBtoA_bigint := big.NewInt(0)
  416. _, err = fmt.Fscanf(c, "0x%x\n", ctBtoA_bigint)
  417. ctBtoA := ctBtoA_bigint.Bytes()
  418. // Alice, step 6: compute Bob's share
  419. shareB, err := kem.Dencapsulate(secA, ctBtoA)
  420. sessionKey := append(shareA, shareB...)
  421. hc.r, hc.rm, err = hc.getStream(sessionKey)
  422. hc.w, hc.wm, err = hc.getStream(sessionKey)
  423. return
  424. }
  425. // randReader wraps rand.Read() in a struct that implements io.Reader
  426. // for use by the Kyber and NEWHOPE/NEWHOPE_SIMPLE KEM methods.
  427. type randReader struct {
  428. }
  429. func (r randReader) Read(b []byte) (n int, e error) {
  430. n, e = rand.Read(b)
  431. return
  432. }
  433. func NewHopeDialSetup(c io.ReadWriter, hc *Conn) (err error) {
  434. // Send xsnet.Conn parameters to remote side
  435. // Alice, step 1: Generate a key pair.
  436. r := new(randReader)
  437. rand.Seed(time.Now().UnixNano())
  438. privKeyAlice, pubKeyAlice, err := newhope.GenerateKeyPairAlice(r)
  439. if err != nil {
  440. panic(err)
  441. }
  442. // Alice, step 2: Send the public key to Bob
  443. fmt.Fprintf(c, "0x%x\n0x%x:0x%x\n", pubKeyAlice.Send,
  444. hc.cipheropts, hc.opts)
  445. // [Bob does step 1-3], from which we read Bob's pubkey
  446. publicKeyBob := big.NewInt(0)
  447. fmt.Fscanf(c, "0x%x\n", publicKeyBob)
  448. var pubKeyBob newhope.PublicKeyBob
  449. for i := range pubKeyBob.Send {
  450. pubKeyBob.Send[i] = publicKeyBob.Bytes()[i]
  451. }
  452. //log.Printf("[Got server pubKey[]:%v]\n", pubKeyBob)
  453. // Read cipheropts, session opts
  454. _, err = fmt.Fscanf(c, "0x%x:0x%x\n",
  455. &hc.cipheropts, &hc.opts)
  456. if err != nil {
  457. return err
  458. }
  459. // Alice, step 3: Derive shared secret
  460. // (NOTE: actual over-wire exchange was already done above. This is
  461. // the math voodoo 'exchange' done after receiving data from Bob.)
  462. aliceSharedSecret, err := newhope.KeyExchangeAlice(&pubKeyBob, privKeyAlice)
  463. if err != nil {
  464. panic(err)
  465. }
  466. hc.r, hc.rm, err = hc.getStream(aliceSharedSecret)
  467. hc.w, hc.wm, err = hc.getStream(aliceSharedSecret)
  468. return
  469. }
  470. func NewHopeSimpleDialSetup(c io.ReadWriter, hc *Conn) (err error) {
  471. // Send xsnet.Conn parameters to remote side
  472. // Alice, step 1: Generate a key pair.
  473. r := new(randReader)
  474. rand.Seed(time.Now().UnixNano())
  475. privKeyAlice, pubKeyAlice, err := newhope.GenerateKeyPairSimpleAlice(r)
  476. if err != nil {
  477. panic(err)
  478. }
  479. // Alice, step 2: Send the public key to Bob
  480. fmt.Fprintf(c, "0x%x\n0x%x:0x%x\n", pubKeyAlice.Send,
  481. hc.cipheropts, hc.opts)
  482. // [Bob does step 1-3], from which we read Bob's pubkey
  483. publicKeyBob := big.NewInt(0)
  484. fmt.Fscanf(c, "0x%x\n", publicKeyBob)
  485. var pubKeyBob newhope.PublicKeySimpleBob
  486. for i := range pubKeyBob.Send {
  487. pubKeyBob.Send[i] = publicKeyBob.Bytes()[i]
  488. }
  489. //log.Printf("[Got server pubKey[]:%v]\n", pubKeyBob)
  490. // Read cipheropts, session opts
  491. _, err = fmt.Fscanf(c, "0x%x:0x%x\n",
  492. &hc.cipheropts, &hc.opts)
  493. if err != nil {
  494. return err
  495. }
  496. // Alice, step 3: Derive shared secret
  497. // (NOTE: actual over-wire exchange was already done above. This is
  498. // the math voodoo 'exchange' done after receiving data from Bob.)
  499. aliceSharedSecret, err := newhope.KeyExchangeSimpleAlice(&pubKeyBob, privKeyAlice)
  500. if err != nil {
  501. panic(err)
  502. }
  503. hc.r, hc.rm, err = hc.getStream(aliceSharedSecret)
  504. hc.w, hc.wm, err = hc.getStream(aliceSharedSecret)
  505. return
  506. }
  507. func KyberDialSetup(c io.ReadWriter /*net.Conn*/, hc *Conn) (err error) {
  508. // Send xsnet.Conn parameters to remote side
  509. // Alice, step 1: Generate a key pair.
  510. r := new(randReader)
  511. rand.Seed(time.Now().UnixNano())
  512. var alicePublicKey *kyber.PublicKey
  513. var alicePrivateKey *kyber.PrivateKey
  514. switch hc.kex {
  515. case KEX_KYBER512:
  516. alicePublicKey, alicePrivateKey, err = kyber.Kyber512.GenerateKeyPair(r)
  517. case KEX_KYBER768:
  518. alicePublicKey, alicePrivateKey, err = kyber.Kyber768.GenerateKeyPair(r)
  519. case KEX_KYBER1024:
  520. alicePublicKey, alicePrivateKey, err = kyber.Kyber1024.GenerateKeyPair(r)
  521. default:
  522. alicePublicKey, alicePrivateKey, err = kyber.Kyber768.GenerateKeyPair(r)
  523. }
  524. if err != nil {
  525. panic(err)
  526. }
  527. // Alice, step 2: Send the public key to Bob
  528. fmt.Fprintf(c, "0x%x\n0x%x:0x%x\n", alicePublicKey.Bytes(),
  529. hc.cipheropts, hc.opts)
  530. // [Bob, step 1-3], from which we read cipher text
  531. pubKeyB := make([]byte, 4096)
  532. fmt.Fscanf(c, "0x%x\n", &pubKeyB)
  533. //if err != nil {
  534. // return err
  535. //}
  536. //log.Printf("[Got server pubKeyB[]:%v]\n", pubKeyB)
  537. // Read cipheropts, session opts
  538. _, err = fmt.Fscanf(c, "0x%x:0x%x\n",
  539. &hc.cipheropts, &hc.opts)
  540. if err != nil {
  541. return err
  542. }
  543. // Alice, step 3: Decrypt the KEM cipher text.
  544. aliceSharedSecret := alicePrivateKey.KEMDecrypt(pubKeyB)
  545. hc.r, hc.rm, err = hc.getStream(aliceSharedSecret)
  546. hc.w, hc.wm, err = hc.getStream(aliceSharedSecret)
  547. return
  548. }
  549. func HKExDialSetup(c io.ReadWriter /*net.Conn*/, hc *Conn) (err error) {
  550. var h *hkex.HerraduraKEx
  551. switch hc.kex {
  552. case KEX_HERRADURA256:
  553. h = hkex.New(256, 64)
  554. case KEX_HERRADURA512:
  555. h = hkex.New(512, 128)
  556. case KEX_HERRADURA1024:
  557. h = hkex.New(1024, 256)
  558. case KEX_HERRADURA2048:
  559. h = hkex.New(2048, 512)
  560. default:
  561. h = hkex.New(256, 64)
  562. }
  563. // Send xsnet.Conn parameters to remote side
  564. // d is value for Herradura key exchange
  565. fmt.Fprintf(c, "0x%s\n0x%x:0x%x\n", h.D().Text(16),
  566. hc.cipheropts, hc.opts)
  567. // Read peer D over net.Conn (c)
  568. d := big.NewInt(0)
  569. _, err = fmt.Fscanln(c, d)
  570. if err != nil {
  571. return err
  572. }
  573. _, err = fmt.Fscanf(c, "0x%x:0x%x\n",
  574. &hc.cipheropts, &hc.opts)
  575. if err != nil {
  576. return err
  577. }
  578. h.SetPeerD(d)
  579. log.Printf("** local D:%s\n", h.D().Text(16))
  580. log.Printf("**(c)** peer D:%s\n", h.PeerD().Text(16))
  581. h.ComputeFA()
  582. log.Printf("**(c)** FA:%s\n", h.FA())
  583. hc.r, hc.rm, err = hc.getStream(h.FA().Bytes())
  584. hc.w, hc.wm, err = hc.getStream(h.FA().Bytes())
  585. return
  586. }
  587. func FrodoKEMAcceptSetup(c *net.Conn, hc *Conn) (err error) {
  588. // Bob, step 1: Generate a key pair.
  589. var kem frodo.FrodoKEM
  590. switch hc.kex {
  591. case KEX_FRODOKEM_1344AES:
  592. kem = frodo.Frodo1344AES()
  593. case KEX_FRODOKEM_1344SHAKE:
  594. kem = frodo.Frodo1344SHAKE()
  595. case KEX_FRODOKEM_976AES:
  596. kem = frodo.Frodo976AES()
  597. default:
  598. kem = frodo.Frodo976SHAKE()
  599. }
  600. pubB, secB := kem.Keygen()
  601. // [Alice sends use a public key (na, ea)
  602. pubA_bigint := big.NewInt(0)
  603. _, err = fmt.Fscanf(*c, "0x%x\n", pubA_bigint)
  604. pubA := pubA_bigint.Bytes()
  605. // (... and sends us cipher, connection opts)
  606. _, err = fmt.Fscanf(*c, "0x%x:0x%x\n",
  607. &hc.cipheropts, &hc.opts)
  608. if err != nil {
  609. return err
  610. }
  611. // Bob, step 2: Send the public key (nb,eb) to Alice
  612. n, err := fmt.Fprintf(*c, "0x%x\n", pubB)
  613. if err != nil {
  614. panic(err)
  615. }
  616. if n < len(pubB) {
  617. panic(errors.New("incomplete Fprintf() of pubB"))
  618. }
  619. // (... and send cipher, connection opts)
  620. fmt.Fprintf(*c, "0x%x:0x%x\n", hc.cipheropts, hc.opts)
  621. // Bob, step 3: Create ctBtoA, shareB
  622. ctBtoA, shareB, err := kem.Encapsulate(pubA)
  623. if err != nil {
  624. return err
  625. }
  626. // Bob, step 4: Send ctBtoA to Alice
  627. fmt.Fprintf(*c, "0x%x\n", ctBtoA)
  628. // Bob, step 5: Receive ctAtoB from Alice
  629. ctAtoB_bigint := big.NewInt(0)
  630. _, err = fmt.Fscanf(*c, "0x%x\n", ctAtoB_bigint)
  631. ctAtoB := ctAtoB_bigint.Bytes()
  632. // Alice, step 6: compute Bob's share
  633. shareA, err := kem.Dencapsulate(secB, ctAtoB)
  634. sessionKey := append(shareA, shareB...)
  635. hc.r, hc.rm, err = hc.getStream(sessionKey)
  636. hc.w, hc.wm, err = hc.getStream(sessionKey)
  637. return
  638. }
  639. func NewHopeAcceptSetup(c *net.Conn, hc *Conn) (err error) {
  640. r := new(randReader)
  641. rand.Seed(time.Now().UnixNano())
  642. // Bob, step 1: Deserialize Alice's public key from the binary encoding.
  643. alicePublicKey := big.NewInt(0)
  644. _, err = fmt.Fscanln(*c, alicePublicKey)
  645. //log.Printf("[Got client pubKey:0x%x\n]", alicePublicKey)
  646. if err != nil {
  647. return err
  648. }
  649. var pubKeyAlice newhope.PublicKeyAlice
  650. for i := range pubKeyAlice.Send {
  651. pubKeyAlice.Send[i] = alicePublicKey.Bytes()[i]
  652. }
  653. _, err = fmt.Fscanf(*c, "0x%x:0x%x\n",
  654. &hc.cipheropts, &hc.opts)
  655. log.Printf("[Got cipheropts, opts:%v, %v]", hc.cipheropts, hc.opts)
  656. if err != nil {
  657. return err
  658. }
  659. // Bob, step 2: Generate the KEM cipher text and shared secret.
  660. pubKeyBob, bobSharedSecret, err := newhope.KeyExchangeBob(r, &pubKeyAlice)
  661. if err != nil {
  662. panic(err)
  663. }
  664. // Bob, step 3: Send the cipher text to Alice.
  665. fmt.Fprintf(*c, "0x%x\n0x%x:0x%x\n", pubKeyBob.Send,
  666. hc.cipheropts, hc.opts)
  667. hc.r, hc.rm, err = hc.getStream(bobSharedSecret)
  668. hc.w, hc.wm, err = hc.getStream(bobSharedSecret)
  669. return
  670. }
  671. func NewHopeSimpleAcceptSetup(c *net.Conn, hc *Conn) (err error) {
  672. r := new(randReader)
  673. rand.Seed(time.Now().UnixNano())
  674. // Bob, step 1: Deserialize Alice's public key from the binary encoding.
  675. alicePublicKey := big.NewInt(0)
  676. _, err = fmt.Fscanln(*c, alicePublicKey)
  677. //log.Printf("[Got client pubKey:0x%x\n]", alicePublicKey)
  678. if err != nil {
  679. return err
  680. }
  681. var pubKeyAlice newhope.PublicKeySimpleAlice
  682. for i := range pubKeyAlice.Send {
  683. pubKeyAlice.Send[i] = alicePublicKey.Bytes()[i]
  684. }
  685. _, err = fmt.Fscanf(*c, "0x%x:0x%x\n",
  686. &hc.cipheropts, &hc.opts)
  687. log.Printf("[Got cipheropts, opts:%v, %v]", hc.cipheropts, hc.opts)
  688. if err != nil {
  689. return err
  690. }
  691. // Bob, step 2: Generate the KEM cipher text and shared secret.
  692. pubKeyBob, bobSharedSecret, err := newhope.KeyExchangeSimpleBob(r, &pubKeyAlice)
  693. if err != nil {
  694. panic(err)
  695. }
  696. // Bob, step 3: Send the cipher text to Alice.
  697. fmt.Fprintf(*c, "0x%x\n0x%x:0x%x\n", pubKeyBob.Send,
  698. hc.cipheropts, hc.opts)
  699. hc.r, hc.rm, err = hc.getStream(bobSharedSecret)
  700. hc.w, hc.wm, err = hc.getStream(bobSharedSecret)
  701. return
  702. }
  703. func KyberAcceptSetup(c *net.Conn, hc *Conn) (err error) {
  704. // Bob, step 1: Deserialize Alice's public key from the binary encoding.
  705. alicePublicKey := big.NewInt(0)
  706. _, err = fmt.Fscanln(*c, alicePublicKey)
  707. //log.Printf("[Got client pubKey:0x%x\n]", alicePublicKey)
  708. if err != nil {
  709. return err
  710. }
  711. _, err = fmt.Fscanf(*c, "0x%x:0x%x\n",
  712. &hc.cipheropts, &hc.opts)
  713. log.Printf("[Got cipheropts, opts:%v, %v]", hc.cipheropts, hc.opts)
  714. if err != nil {
  715. return err
  716. }
  717. var peerPublicKey *kyber.PublicKey
  718. switch hc.kex {
  719. case KEX_KYBER512:
  720. peerPublicKey, err = kyber.Kyber512.PublicKeyFromBytes(alicePublicKey.Bytes())
  721. case KEX_KYBER768:
  722. peerPublicKey, err = kyber.Kyber768.PublicKeyFromBytes(alicePublicKey.Bytes())
  723. case KEX_KYBER1024:
  724. peerPublicKey, err = kyber.Kyber1024.PublicKeyFromBytes(alicePublicKey.Bytes())
  725. default:
  726. peerPublicKey, err = kyber.Kyber768.PublicKeyFromBytes(alicePublicKey.Bytes())
  727. }
  728. if err != nil {
  729. panic(err)
  730. }
  731. // Bob, step 2: Generate the KEM cipher text and shared secret.
  732. r := new(randReader)
  733. rand.Seed(time.Now().UnixNano())
  734. cipherText, bobSharedSecret, err := peerPublicKey.KEMEncrypt(r)
  735. if err != nil {
  736. panic(err)
  737. }
  738. // Bob, step 3: Send the cipher text to Alice.
  739. fmt.Fprintf(*c, "0x%x\n0x%x:0x%x\n", cipherText,
  740. hc.cipheropts, hc.opts)
  741. hc.r, hc.rm, err = hc.getStream(bobSharedSecret)
  742. hc.w, hc.wm, err = hc.getStream(bobSharedSecret)
  743. return
  744. }
  745. func HKExAcceptSetup(c *net.Conn, hc *Conn) (err error) {
  746. var h *hkex.HerraduraKEx
  747. switch hc.kex {
  748. case KEX_HERRADURA256:
  749. h = hkex.New(256, 64)
  750. case KEX_HERRADURA512:
  751. h = hkex.New(512, 128)
  752. case KEX_HERRADURA1024:
  753. h = hkex.New(1024, 256)
  754. case KEX_HERRADURA2048:
  755. h = hkex.New(2048, 512)
  756. default:
  757. h = hkex.New(256, 64)
  758. }
  759. // Read in xsnet.Conn parameters over raw Conn c
  760. // d is value for Herradura key exchange
  761. d := big.NewInt(0)
  762. _, err = fmt.Fscanln(*c, d)
  763. log.Printf("[Got d:%v]", d)
  764. if err != nil {
  765. return err
  766. }
  767. _, err = fmt.Fscanf(*c, "0x%x:0x%x\n",
  768. &hc.cipheropts, &hc.opts)
  769. log.Printf("[Got cipheropts, opts:%v, %v]", hc.cipheropts, hc.opts)
  770. if err != nil {
  771. return err
  772. }
  773. h.SetPeerD(d)
  774. log.Printf("** D:%s\n", h.D().Text(16))
  775. log.Printf("**(s)** peerD:%s\n", h.PeerD().Text(16))
  776. h.ComputeFA()
  777. log.Printf("**(s)** FA:%s\n", h.FA())
  778. // Send D and cipheropts/conn_opts to peer
  779. fmt.Fprintf(*c, "0x%s\n0x%x:0x%x\n", h.D().Text(16),
  780. hc.cipheropts, hc.opts)
  781. hc.r, hc.rm, err = hc.getStream(h.FA().Bytes())
  782. hc.w, hc.wm, err = hc.getStream(h.FA().Bytes())
  783. return
  784. }
  785. // Dial as net.Dial(), but with implicit key exchange to set up secure
  786. // channel on connect
  787. //
  788. // Can be called like net.Dial(), defaulting to C_AES_256/H_SHA256,
  789. // or additional extensions can be passed amongst the following:
  790. //
  791. // "C_AES_256" | "C_TWOFISH_128" | ...
  792. //
  793. // "H_SHA256" | "H_SHA512" | ...
  794. //
  795. // See go doc -u xsnet.applyConnExtensions
  796. func Dial(protocol string, ipport string, extensions ...string) (hc Conn, err error) {
  797. if Log == nil {
  798. Init(false, "client", logger.LOG_DAEMON|logger.LOG_DEBUG)
  799. }
  800. var c net.Conn
  801. if protocol == "kcp" {
  802. c, err = kcpDial(ipport, extensions)
  803. if err != nil {
  804. return Conn{}, err
  805. }
  806. } else {
  807. // Open raw Conn c
  808. c, err = net.Dial(protocol, ipport)
  809. if err != nil {
  810. return Conn{}, err
  811. }
  812. }
  813. // Init xsnet.Conn hc over net.Conn c
  814. ret, err := _new(getkexalgnum(extensions...), &c)
  815. if err != nil {
  816. return Conn{}, err
  817. }
  818. hc = *ret
  819. // Client has full control over Conn extensions. It's the server's
  820. // responsibility to accept or reject the proposed parameters.
  821. hc.applyConnExtensions(extensions...)
  822. // Perform Key Exchange according to client-request algorithm
  823. fmt.Fprintf(c, "%02x\n", hc.kex)
  824. switch hc.kex {
  825. case KEX_HERRADURA256:
  826. fallthrough
  827. case KEX_HERRADURA512:
  828. fallthrough
  829. case KEX_HERRADURA1024:
  830. fallthrough
  831. case KEX_HERRADURA2048:
  832. log.Printf("[Setting up for KEX_HERRADURA %d]\n", hc.kex)
  833. if HKExDialSetup(c, &hc) != nil {
  834. return Conn{}, nil
  835. }
  836. case KEX_KYBER512:
  837. fallthrough
  838. case KEX_KYBER768:
  839. fallthrough
  840. case KEX_KYBER1024:
  841. log.Printf("[Setting up for KEX_KYBER %d]\n", hc.kex)
  842. if KyberDialSetup(c, &hc) != nil {
  843. return Conn{}, nil
  844. }
  845. case KEX_NEWHOPE:
  846. log.Printf("[Setting up for KEX_NEWHOPE %d]\n", hc.kex)
  847. if NewHopeDialSetup(c, &hc) != nil {
  848. return Conn{}, nil
  849. }
  850. case KEX_NEWHOPE_SIMPLE:
  851. log.Printf("[Setting up for KEX_NEWHOPE_SIMPLE %d]\n", hc.kex)
  852. if NewHopeSimpleDialSetup(c, &hc) != nil {
  853. return Conn{}, nil
  854. }
  855. case KEX_FRODOKEM_1344AES:
  856. fallthrough
  857. case KEX_FRODOKEM_1344SHAKE:
  858. fallthrough
  859. case KEX_FRODOKEM_976AES:
  860. fallthrough
  861. case KEX_FRODOKEM_976SHAKE:
  862. log.Printf("[Setting up for KEX_FRODOKEM %d]\n", hc.kex)
  863. if FrodoKEMDialSetup(c, &hc) != nil {
  864. return Conn{}, nil
  865. }
  866. default:
  867. return Conn{}, err
  868. }
  869. return
  870. }
  871. // Close a hkex.Conn
  872. func (hc *Conn) Close() (err error) {
  873. hc.DisableChaff()
  874. s := make([]byte, 4)
  875. binary.BigEndian.PutUint32(s, uint32(*hc.closeStat))
  876. log.Printf("** Writing closeStat %d at Close()\n", *hc.closeStat)
  877. //(*hc.c).SetWriteDeadline(time.Now().Add(500 * time.Millisecond))
  878. hc.WritePacket(s, CSOExitStatus)
  879. err = (*hc.c).Close()
  880. logger.LogDebug(fmt.Sprintln("[Conn Closing]"))
  881. return
  882. }
  883. // LocalAddr returns the local network address.
  884. func (hc *Conn) LocalAddr() net.Addr {
  885. return (*hc.c).LocalAddr()
  886. }
  887. // RemoteAddr returns the remote network address.
  888. func (hc *Conn) RemoteAddr() net.Addr {
  889. return (*hc.c).RemoteAddr()
  890. }
  891. // SetDeadline sets the read and write deadlines associated
  892. // with the connection. It is equivalent to calling both
  893. // SetReadDeadline and SetWriteDeadline.
  894. //
  895. // A deadline is an absolute time after which I/O operations
  896. // fail with a timeout (see type Error) instead of
  897. // blocking. The deadline applies to all future and pending
  898. // I/O, not just the immediately following call to Read or
  899. // Write. After a deadline has been exceeded, the connection
  900. // can be refreshed by setting a deadline in the future.
  901. //
  902. // An idle timeout can be implemented by repeatedly extending
  903. // the deadline after successful Read or Write calls.
  904. //
  905. // A zero value for t means I/O operations will not time out.
  906. func (hc *Conn) SetDeadline(t time.Time) error {
  907. return (*hc.c).SetDeadline(t)
  908. }
  909. // SetWriteDeadline sets the deadline for future Write calls
  910. // and any currently-blocked Write call.
  911. // Even if write times out, it may return n > 0, indicating that
  912. // some of the data was successfully written.
  913. // A zero value for t means Write will not time out.
  914. func (hc *Conn) SetWriteDeadline(t time.Time) error {
  915. return (*hc.c).SetWriteDeadline(t)
  916. }
  917. // SetReadDeadline sets the deadline for future Read calls
  918. // and any currently-blocked Read call.
  919. // A zero value for t means Read will not time out.
  920. func (hc *Conn) SetReadDeadline(t time.Time) error {
  921. return (*hc.c).SetReadDeadline(t)
  922. }
  923. /*---------------------------------------------------------------------*/
  924. // HKExListener is a Listener conforming to net.Listener
  925. //
  926. // See go doc net.Listener
  927. type HKExListener struct {
  928. l net.Listener
  929. proto string
  930. }
  931. // Listen for a connection
  932. //
  933. // See go doc net.Listen
  934. func Listen(proto string, ipport string, extensions ...string) (hl HKExListener, e error) {
  935. if Log == nil {
  936. Init(false, "server", logger.LOG_DAEMON|logger.LOG_DEBUG)
  937. }
  938. var lErr error
  939. var l net.Listener
  940. if proto == "kcp" {
  941. l, lErr = kcpListen(ipport, extensions)
  942. } else {
  943. l, lErr = net.Listen(proto, ipport)
  944. }
  945. if lErr != nil {
  946. return HKExListener{nil, proto}, lErr
  947. }
  948. logger.LogDebug(fmt.Sprintf("[Listening (proto '%s') on %s]\n", proto, ipport))
  949. hl.l = l
  950. hl.proto = proto
  951. return
  952. }
  953. // Close a hkex Listener - closes the Listener.
  954. // Any blocked Accept operations will be unblocked and return errors.
  955. //
  956. // See go doc net.Listener.Close
  957. func (hl HKExListener) Close() error {
  958. logger.LogDebug(fmt.Sprintln("[Listener Closed]"))
  959. return hl.l.Close()
  960. }
  961. // Addr returns a the listener's network address.
  962. //
  963. // See go doc net.Listener.Addr
  964. func (hl HKExListener) Addr() net.Addr {
  965. return hl.l.Addr()
  966. }
  967. // Accept a client connection, conforming to net.Listener.Accept()
  968. //
  969. // See go doc net.Listener.Accept
  970. func (hl *HKExListener) Accept() (hc Conn, err error) {
  971. var c net.Conn
  972. if hl.proto == "kcp" {
  973. c, err = hl.AcceptKCP()
  974. if err != nil {
  975. return Conn{}, err
  976. }
  977. logger.LogDebug(fmt.Sprintln("[kcp.Listener Accepted]"))
  978. } else {
  979. // Open raw Conn c
  980. c, err = hl.l.Accept()
  981. if err != nil {
  982. return Conn{}, err
  983. }
  984. logger.LogDebug(fmt.Sprintln("[net.Listener Accepted]"))
  985. }
  986. // Read KEx alg proposed by client
  987. var kexAlg KEXAlg
  988. //! NB. Was using fmt.FScanln() here, but integers with a leading zero
  989. // were being mis-scanned? (is it an octal thing? Investigate.)
  990. _, err = fmt.Fscanf(c, "%02x\n", &kexAlg)
  991. if err != nil {
  992. return Conn{}, err
  993. }
  994. log.Printf("[Client proposed KEx alg: %v]\n", kexAlg)
  995. // --
  996. ret, err := _new(kexAlg, &c)
  997. if err != nil {
  998. return Conn{}, err
  999. }
  1000. hc = *ret
  1001. switch hc.kex {
  1002. case KEX_HERRADURA256:
  1003. fallthrough
  1004. case KEX_HERRADURA512:
  1005. fallthrough
  1006. case KEX_HERRADURA1024:
  1007. fallthrough
  1008. case KEX_HERRADURA2048:
  1009. log.Printf("[Setting up for KEX_HERRADURA %d]\n", hc.kex)
  1010. if HKExAcceptSetup(&c, &hc) != nil {
  1011. return Conn{}, err
  1012. }
  1013. case KEX_KYBER512:
  1014. fallthrough
  1015. case KEX_KYBER768:
  1016. fallthrough
  1017. case KEX_KYBER1024:
  1018. log.Printf("[Setting up for KEX_KYBER %d]\n", hc.kex)
  1019. if KyberAcceptSetup(&c, &hc) != nil {
  1020. return Conn{}, err
  1021. }
  1022. case KEX_NEWHOPE:
  1023. log.Printf("[Setting up for KEX_NEWHOPE %d]\n", hc.kex)
  1024. if NewHopeAcceptSetup(&c, &hc) != nil {
  1025. return Conn{}, err
  1026. }
  1027. case KEX_NEWHOPE_SIMPLE:
  1028. log.Printf("[Setting up for KEX_NEWHOPE_SIMPLE %d]\n", hc.kex)
  1029. if NewHopeSimpleAcceptSetup(&c, &hc) != nil {
  1030. return Conn{}, err
  1031. }
  1032. case KEX_FRODOKEM_1344AES:
  1033. log.Printf("[Setting up for KEX_FRODOKEM_1344AES %d]\n", hc.kex)
  1034. if FrodoKEMAcceptSetup(&c, &hc) != nil {
  1035. return Conn{}, err
  1036. }
  1037. case KEX_FRODOKEM_1344SHAKE:
  1038. log.Printf("[Setting up for KEX_FRODOKEM_1344SHAKE %d]\n", hc.kex)
  1039. if FrodoKEMAcceptSetup(&c, &hc) != nil {
  1040. return Conn{}, err
  1041. }
  1042. case KEX_FRODOKEM_976AES:
  1043. log.Printf("[Setting up for KEX_FRODOKEM_976AES %d]\n", hc.kex)
  1044. if FrodoKEMAcceptSetup(&c, &hc) != nil {
  1045. return Conn{}, err
  1046. }
  1047. case KEX_FRODOKEM_976SHAKE:
  1048. log.Printf("[Setting up for KEX_FRODOKEM_976SHAKE %d]\n", hc.kex)
  1049. if FrodoKEMAcceptSetup(&c, &hc) != nil {
  1050. return Conn{}, err
  1051. }
  1052. default:
  1053. return Conn{}, err
  1054. }
  1055. // Finally, ensure alg proposed by client is allowed by server config
  1056. //if hc.kex.String() {
  1057. log.Println("[hc.Accept successful]")
  1058. return
  1059. }
  1060. /*---------------------------------------------------------------------*/
  1061. // Read into a byte slice
  1062. //
  1063. // In addition to regular io.Reader behaviour this does demultiplexing of
  1064. // secured terminal comms and (if defined) tunnel traffic and session control
  1065. // packet processing.
  1066. //
  1067. // See go doc io.Reader
  1068. func (hc Conn) Read(b []byte) (n int, err error) {
  1069. for {
  1070. if hc.dBuf.Len() > 0 {
  1071. break
  1072. }
  1073. var ctrlStatOp uint8
  1074. var hmacIn [HMAC_CHK_SZ]uint8
  1075. var payloadLen uint32
  1076. // Read ctrl/status opcode (CSOHmacInvalid on hmac mismatch)
  1077. err = binary.Read(*hc.c, binary.BigEndian, &ctrlStatOp)
  1078. if err != nil {
  1079. if err.Error() == "EOF" {
  1080. return 0, io.EOF
  1081. }
  1082. if strings.HasSuffix(err.Error(), "use of closed network connection") {
  1083. logger.LogDebug(fmt.Sprintln("[Client hung up]"))
  1084. return 0, io.EOF
  1085. }
  1086. etxt := fmt.Sprintf("** Failed read:%s (%s) **", "ctrlStatOp", err)
  1087. logger.LogDebug(etxt)
  1088. return 0, errors.New(etxt)
  1089. }
  1090. log.Printf("[ctrlStatOp: %v]\n", ctrlStatOp)
  1091. if ctrlStatOp == CSOHmacInvalid {
  1092. // Other side indicated channel tampering, close channel
  1093. hc.Close()
  1094. return 0, errors.New("** ALERT - remote end detected HMAC mismatch - possible channel tampering **")
  1095. }
  1096. // Read the hmac and payload len first
  1097. err = binary.Read(*hc.c, binary.BigEndian, &hmacIn)
  1098. if err != nil {
  1099. if err.Error() == "EOF" {
  1100. return 0, io.EOF
  1101. }
  1102. if strings.HasSuffix(err.Error(), "use of closed network connection") {
  1103. logger.LogDebug(fmt.Sprintln("[Client hung up]"))
  1104. return 0, io.EOF
  1105. }
  1106. etxt := fmt.Sprintf("** Failed read:%s (%s) **", "HMAC", err)
  1107. logger.LogDebug(etxt)
  1108. return 0, errors.New(etxt)
  1109. }
  1110. err = binary.Read(*hc.c, binary.BigEndian, &payloadLen)
  1111. if err != nil {
  1112. if err.Error() == "EOF" {
  1113. return 0, io.EOF
  1114. }
  1115. if strings.HasSuffix(err.Error(), "use of closed network connection") {
  1116. logger.LogDebug(fmt.Sprintln("[Client hung up]"))
  1117. return 0, io.EOF
  1118. }
  1119. etxt := fmt.Sprintf("** Failed read:%s (%s) **", "payloadLen", err)
  1120. logger.LogDebug(etxt)
  1121. return 0, errors.New(etxt)
  1122. }
  1123. if payloadLen > MAX_PAYLOAD_LEN {
  1124. logger.LogDebug(fmt.Sprintf("[Insane payloadLen:%v]\n", payloadLen))
  1125. hc.Close()
  1126. return 1, errors.New("Insane payloadLen")
  1127. }
  1128. var payloadBytes = make([]byte, payloadLen)
  1129. n, err = io.ReadFull(*hc.c, payloadBytes)
  1130. if err != nil {
  1131. if err.Error() == "EOF" {
  1132. return 0, io.EOF
  1133. }
  1134. if strings.HasSuffix(err.Error(), "use of closed network connection") {
  1135. logger.LogDebug(fmt.Sprintln("[Client hung up]"))
  1136. return 0, io.EOF
  1137. }
  1138. etxt := fmt.Sprintf("** Failed read:%s (%s) **", "payloadBytes", err)
  1139. logger.LogDebug(etxt)
  1140. return 0, errors.New(etxt)
  1141. }
  1142. if hc.logCipherText {
  1143. log.Printf(" <:ctext:\r\n%s\r\n", hex.Dump(payloadBytes[:n]))
  1144. }
  1145. //fmt.Printf(" <:ctext:\r\n%s\r\n", hex.Dump(payloadBytes[:n]))
  1146. hc.rm.Write(payloadBytes) // Calc hmac on received data
  1147. hTmp := hc.rm.Sum(nil)[0:HMAC_CHK_SZ]
  1148. //log.Printf("<%04x) HMAC:(i)%s (c)%02x\r\n", decryptN, hex.EncodeToString([]byte(hmacIn[0:])), hTmp)
  1149. // Log alert if hmac didn't match, corrupted channel
  1150. if !bytes.Equal(hTmp, []byte(hmacIn[0:])) /*|| hmacIn[0] > 0xf8*/ {
  1151. logger.LogDebug(fmt.Sprintln("** ALERT - detected HMAC mismatch, possible channel tampering **"))
  1152. _, _ = (*hc.c).Write([]byte{CSOHmacInvalid})
  1153. }
  1154. db := bytes.NewBuffer(payloadBytes[:n]) //copying payloadBytes to db
  1155. // The StreamReader acts like a pipe, decrypting
  1156. // whatever is available and forwarding the result
  1157. // to the parameter of Read() as a normal io.Reader
  1158. rs := &cipher.StreamReader{S: hc.r, R: db}
  1159. // The caller isn't necessarily reading the full payload so we need
  1160. // to decrypt to an intermediate buffer, draining it on demand of caller
  1161. decryptN, err := rs.Read(payloadBytes)
  1162. if hc.logPlainText {
  1163. log.Printf(" <:ptext:\r\n%s\r\n", hex.Dump(payloadBytes[:n]))
  1164. }
  1165. if err != nil {
  1166. log.Println("xsnet.Read():", err)
  1167. //panic(err)
  1168. } else {
  1169. // Padding: Read padSide, padLen, (padding | d) or (d | padding)
  1170. padSide := payloadBytes[0]
  1171. padLen := payloadBytes[1]
  1172. payloadBytes = payloadBytes[2:]
  1173. if padSide == 0 {
  1174. payloadBytes = payloadBytes[padLen:]
  1175. } else {
  1176. payloadBytes = payloadBytes[0 : len(payloadBytes)-int(padLen)]
  1177. }
  1178. // Throw away pkt if it's chaff (ie., caller to Read() won't see this data)
  1179. if ctrlStatOp == CSOChaff {
  1180. log.Printf("[Chaff pkt, discarded (len %d)]\n", decryptN)
  1181. } else if ctrlStatOp == CSOTermSize {
  1182. fmt.Sscanf(string(payloadBytes), "%d %d", &hc.Rows, &hc.Cols)
  1183. log.Printf("[TermSize pkt: rows %v cols %v]\n", hc.Rows, hc.Cols)
  1184. hc.WinCh <- WinSize{hc.Rows, hc.Cols}
  1185. } else if ctrlStatOp == CSOExitStatus {
  1186. if len(payloadBytes) > 0 {
  1187. hc.SetStatus(CSOType(binary.BigEndian.Uint32(payloadBytes)))
  1188. } else {
  1189. logger.LogDebug(fmt.Sprintln("[truncated payload, cannot determine CSOExitStatus]"))
  1190. hc.SetStatus(CSETruncCSO)
  1191. }
  1192. hc.Close()
  1193. } else if ctrlStatOp == CSOTunSetup {
  1194. // server side tunnel setup in response to client
  1195. lport := binary.BigEndian.Uint16(payloadBytes[0:2])
  1196. rport := binary.BigEndian.Uint16(payloadBytes[2:4])
  1197. if _, ok := (*hc.tuns)[rport]; !ok {
  1198. // tunnel first-time open
  1199. logger.LogDebug(fmt.Sprintf("[Server] Got Initial CSOTunSetup [%d:%d]", lport, rport))
  1200. hc.StartServerTunnel(lport, rport)
  1201. } else {
  1202. logger.LogDebug(fmt.Sprintf("[Server] Got CSOTunSetup [%d:%d]", lport, rport))
  1203. }
  1204. (*hc.tuns)[rport].Ctl <- 'd' // Dial() rport
  1205. } else if ctrlStatOp == CSOTunSetupAck {
  1206. lport := binary.BigEndian.Uint16(payloadBytes[0:2])
  1207. rport := binary.BigEndian.Uint16(payloadBytes[2:4])
  1208. if _, ok := (*hc.tuns)[rport]; !ok {
  1209. // tunnel first-time open
  1210. logger.LogDebug(fmt.Sprintf("[Client] Got Initial CSOTunSetupAck [%d:%d]", lport, rport))
  1211. hc.StartClientTunnel(lport, rport)
  1212. } else {
  1213. logger.LogDebug(fmt.Sprintf("[Client] Got CSOTunSetupAck [%d:%d]", lport, rport))
  1214. }
  1215. (*hc.tuns)[rport].Ctl <- 'a' // Listen() for lport connection
  1216. } else if ctrlStatOp == CSOTunRefused {
  1217. // client side receiving CSOTunRefused means the remote side
  1218. // could not dial() rport. So we cannot yet listen()
  1219. // for client-side on lport.
  1220. lport := binary.BigEndian.Uint16(payloadBytes[0:2])
  1221. rport := binary.BigEndian.Uint16(payloadBytes[2:4])
  1222. logger.LogDebug(fmt.Sprintf("[Client] Got CSOTunRefused [%d:%d]", lport, rport))
  1223. if _, ok := (*hc.tuns)[rport]; ok {
  1224. hc.MarkTunDead(rport)
  1225. } else {
  1226. logger.LogDebug(fmt.Sprintf("[Client] CSOTunRefused on already-closed tun [%d:%d]", lport, rport))
  1227. }
  1228. } else if ctrlStatOp == CSOTunDisconn {
  1229. // server side's rport has disconnected (server lost)
  1230. lport := binary.BigEndian.Uint16(payloadBytes[0:2])
  1231. rport := binary.BigEndian.Uint16(payloadBytes[2:4])
  1232. logger.LogDebug(fmt.Sprintf("[Client] Got CSOTunDisconn [%d:%d]", lport, rport))
  1233. if _, ok := (*hc.tuns)[rport]; ok {
  1234. hc.MarkTunDead(rport)
  1235. } else {
  1236. logger.LogDebug(fmt.Sprintf("[Client] CSOTunDisconn on already-closed tun [%d:%d]", lport, rport))
  1237. }
  1238. } else if ctrlStatOp == CSOTunHangup {
  1239. // client side's lport has hung up
  1240. lport := binary.BigEndian.Uint16(payloadBytes[0:2])
  1241. rport := binary.BigEndian.Uint16(payloadBytes[2:4])
  1242. logger.LogDebug(fmt.Sprintf("[Server] Got CSOTunHangup [%d:%d]", lport, rport))
  1243. if _, ok := (*hc.tuns)[rport]; ok {
  1244. hc.MarkTunDead(rport)
  1245. } else {
  1246. logger.LogDebug(fmt.Sprintf("[Server] CSOTunHangup to already-closed tun [%d:%d]", lport, rport))
  1247. }
  1248. } else if ctrlStatOp == CSOTunData {
  1249. lport := binary.BigEndian.Uint16(payloadBytes[0:2])
  1250. rport := binary.BigEndian.Uint16(payloadBytes[2:4])
  1251. //fmt.Printf("[Got CSOTunData: [lport %d:rport %d] data:%v\n", lport, rport, payloadBytes[4:])
  1252. if _, ok := (*hc.tuns)[rport]; ok {
  1253. if hc.logTunActivity {
  1254. logger.LogDebug(fmt.Sprintf("[Writing data to rport [%d:%d]", lport, rport))
  1255. }
  1256. (*hc.tuns)[rport].Data <- payloadBytes[4:]
  1257. hc.ResetTunnelAge(rport)
  1258. } else {
  1259. logger.LogDebug(fmt.Sprintf("[Attempt to write data to closed tun [%d:%d]", lport, rport))
  1260. }
  1261. } else if ctrlStatOp == CSOTunKeepAlive {
  1262. // client side has sent keepalive for tunnels -- if client
  1263. // dies or exits unexpectedly the absence of this will
  1264. // let the server know to hang up on Dial()ed server rports.
  1265. _ = binary.BigEndian.Uint16(payloadBytes[0:2])
  1266. //logger.LogDebug(fmt.Sprintf("[Server] Got CSOTunKeepAlive"))
  1267. for _, t := range *hc.tuns {
  1268. hc.Lock()
  1269. t.KeepAlive = 0
  1270. hc.Unlock()
  1271. }
  1272. } else if ctrlStatOp == CSONone {
  1273. hc.dBuf.Write(payloadBytes)
  1274. } else {
  1275. logger.LogDebug(fmt.Sprintf("[Unknown CSOType:%d]", ctrlStatOp))
  1276. }
  1277. }
  1278. }
  1279. retN := hc.dBuf.Len()
  1280. if retN > len(b) {
  1281. retN = len(b)
  1282. }
  1283. log.Printf("Read() got %d bytes\n", retN)
  1284. copy(b, hc.dBuf.Next(retN))
  1285. return retN, nil
  1286. }
  1287. // Write a byte slice
  1288. //
  1289. // See go doc io.Writer
  1290. func (hc Conn) Write(b []byte) (n int, err error) {
  1291. n, err = hc.WritePacket(b, CSONone)
  1292. return n, err
  1293. }
  1294. // Write a byte slice with specified ctrlStatOp byte
  1295. func (hc *Conn) WritePacket(b []byte, ctrlStatOp byte) (n int, err error) {
  1296. //log.Printf("[Encrypting...]\r\n")
  1297. var hmacOut []uint8
  1298. var payloadLen uint32
  1299. if hc.m == nil || hc.wm == nil {
  1300. return 0, errors.New("Secure chan not ready for writing")
  1301. }
  1302. //Padding prior to encryption
  1303. padSz := rand.Intn(PAD_SZ-1) + 1 /*(rand.Intn(PAD_SZ) / 2) + (PAD_SZ / 2)*/
  1304. padLen := padSz - ((len(b) + padSz) % padSz)
  1305. if padLen == padSz {
  1306. // No padding required
  1307. padLen = 0
  1308. }
  1309. padBytes := make([]byte, padLen)
  1310. rand.Read(padBytes)
  1311. // For a little more confusion let's support padding either before
  1312. // or after the payload.
  1313. padSide := rand.Intn(2)
  1314. if padSide == 0 {
  1315. b = append([]byte{byte(padSide)}, append([]byte{byte(padLen)}, append(padBytes, b...)...)...)
  1316. } else {
  1317. b = append([]byte{byte(padSide)}, append([]byte{byte(padLen)}, append(b, padBytes...)...)...)
  1318. }
  1319. // N.B. Originally this Lock() surrounded only the
  1320. // calls to binary.Write(hc.c ..) however there appears
  1321. // to be some other unshareable state in the Conn
  1322. // struct that must be protected to serialize main and
  1323. // chaff data written to it.
  1324. //
  1325. // Would be nice to determine if the mutex scope
  1326. // could be tightened.
  1327. hc.Lock()
  1328. payloadLen = uint32(len(b))
  1329. if hc.logPlainText {
  1330. log.Printf(" >:ptext:\r\n%s\r\n", hex.Dump(b[0:payloadLen]))
  1331. }
  1332. // NOTE releases prior to v0.9 used Authenticate-then-Encrypt,
  1333. // which in block modes is insecure; however
  1334. // 1) we use exclusively XOR-stream modes with random padding,
  1335. // 2) are padding randomly either before or after the real payload, and
  1336. // 3) the padding side indicator value itself is part of the ciphertext
  1337. // ... thus are not subject to oracle attacks of the type used on SSL
  1338. // (described in (Krawczyk 2001/2014,
  1339. // https://link.springer.com/content/pdf/10.1007%2F3-540-44647-8_19.pdf)
  1340. //
  1341. // Nevertheless, to address any future concerns v0.9 onwards switches to
  1342. // Encrypt-then-Auth and breaks interop with earlier versions.
  1343. // -rlm 2020-12-15
  1344. var wb bytes.Buffer
  1345. // The StreamWriter acts like a pipe, forwarding whatever is
  1346. // written to it through the cipher, encrypting as it goes
  1347. ws := &cipher.StreamWriter{S: hc.w, W: &wb}
  1348. wN, err := ws.Write(b[0:payloadLen])
  1349. if err != nil {
  1350. panic(err)
  1351. }
  1352. if wN < int(payloadLen) {
  1353. panic("truncated Write to cipher *****")
  1354. }
  1355. if hc.logCipherText {
  1356. log.Printf(" >:ctext:\r\n%s\r\n", hex.Dump(wb.Bytes()))
  1357. }
  1358. //fmt.Printf(" >:ctext:\r\n%s\r\n", hex.Dump(wb.Bytes()))
  1359. // Calculate hmac on cipher payload
  1360. hc.wm.Write(wb.Bytes())
  1361. hmacOut = hc.wm.Sum(nil)[0:HMAC_CHK_SZ] //finalize
  1362. //log.Printf(" (%08x> HMAC(o):%s\r\n", payloadLen, hex.EncodeToString(hmacOut))
  1363. err = binary.Write(*hc.c, binary.BigEndian, &ctrlStatOp)
  1364. if err == nil {
  1365. // Write hmac LSB, payloadLen followed by payload
  1366. err = binary.Write(*hc.c, binary.BigEndian, hmacOut)
  1367. if err == nil {
  1368. err = binary.Write(*hc.c, binary.BigEndian, payloadLen)
  1369. if err == nil {
  1370. n, err = (*hc.c).Write(wb.Bytes())
  1371. } else {
  1372. //fmt.Println("[c]WriteError!")
  1373. }
  1374. } else {
  1375. //fmt.Println("[b]WriteError!")
  1376. }
  1377. } else {
  1378. //fmt.Println("[a]WriteError!")
  1379. }
  1380. hc.Unlock()
  1381. if err != nil {
  1382. log.Println(err)
  1383. }
  1384. // We must 'lie' to caller indicating the length of THEIR
  1385. // data written (ie., not including the padding and padding headers)
  1386. retN := n - 2 - int(padLen)
  1387. if retN <= 0 {
  1388. retN = 0
  1389. }
  1390. return retN, err
  1391. }
  1392. func (hc *Conn) EnableChaff() {
  1393. hc.chaff.shutdown = false
  1394. hc.chaff.enabled = true
  1395. log.Println("Chaffing ENABLED")
  1396. hc.chaffHelper()
  1397. }
  1398. func (hc *Conn) DisableChaff() {
  1399. hc.chaff.enabled = false
  1400. log.Println("Chaffing DISABLED")
  1401. }
  1402. func (hc *Conn) ShutdownChaff() {
  1403. hc.chaff.shutdown = true
  1404. log.Println("Chaffing SHUTDOWN")
  1405. }
  1406. func (hc *Conn) SetupChaff(msecsMin uint, msecsMax uint, szMax uint) {
  1407. hc.chaff.msecsMin = msecsMin //move these to params of chaffHelper() ?
  1408. hc.chaff.msecsMax = msecsMax
  1409. hc.chaff.szMax = szMax
  1410. }
  1411. // Helper routine to spawn a chaffing goroutine for each Conn
  1412. func (hc *Conn) chaffHelper() {
  1413. go func() {
  1414. for {
  1415. var nextDuration int
  1416. if hc.chaff.enabled {
  1417. var bufTmp []byte
  1418. bufTmp = make([]byte, rand.Intn(int(hc.chaff.szMax)))
  1419. min := int(hc.chaff.msecsMin)
  1420. nextDuration = rand.Intn(int(hc.chaff.msecsMax)-min) + min
  1421. _, _ = rand.Read(bufTmp)
  1422. _, err := hc.WritePacket(bufTmp, CSOChaff)
  1423. if err != nil {
  1424. log.Println("[ *** error - chaffHelper quitting *** ]")
  1425. hc.chaff.enabled = false
  1426. break
  1427. }
  1428. }
  1429. time.Sleep(time.Duration(nextDuration) * time.Millisecond)
  1430. if hc.chaff.shutdown {
  1431. log.Println("*** chaffHelper shutting down")
  1432. break
  1433. }
  1434. }
  1435. }()
  1436. }