diff --git a/internal/multiplex/crypto.go b/internal/multiplex/crypto.go index 0f9d0b5..8f4c9e3 100644 --- a/internal/multiplex/crypto.go +++ b/internal/multiplex/crypto.go @@ -45,9 +45,7 @@ func MakeAESGCMCipher(key []byte) (*AESGCM, error) { func (a *AESGCM) encrypt(plaintext []byte, nonce []byte) ([]byte, error) { ciphertext := a.cipher.Seal(nil, nonce, plaintext, nil) - ret := make([]byte, len(plaintext)+16) - copy(ret, ciphertext) - return ret, nil + return ciphertext, nil } func (a *AESGCM) decrypt(ciphertext []byte, nonce []byte) ([]byte, error) { @@ -75,9 +73,7 @@ func MakeCPCipher(key []byte) (*C20P1305, error) { func (c *C20P1305) encrypt(plaintext []byte, nonce []byte) ([]byte, error) { ciphertext := c.cipher.Seal(nil, nonce, plaintext, nil) - ret := make([]byte, len(plaintext)+16) - copy(ret, ciphertext) - return ret, nil + return ciphertext, nil } func (c *C20P1305) decrypt(ciphertext []byte, nonce []byte) ([]byte, error) { diff --git a/internal/multiplex/obfs.go b/internal/multiplex/obfs.go index 429fc58..9bc9789 100644 --- a/internal/multiplex/obfs.go +++ b/internal/multiplex/obfs.go @@ -13,7 +13,7 @@ type Deobfser func([]byte) (*Frame, error) var u32 = binary.BigEndian.Uint32 var putU32 = binary.BigEndian.PutUint32 -const headerLen = 12 +const HEADER_LEN = 12 func genXorKey(key, salt []byte) []byte { h := sha1.New() @@ -29,17 +29,22 @@ func xor(a []byte, b []byte) { func MakeObfs(key []byte, algo Crypto) Obfser { obfs := func(f *Frame) ([]byte, error) { + ret := make([]byte, 5+HEADER_LEN+len(f.Payload)+16) + recordLayer := ret[0:5] + header := ret[5 : 5+HEADER_LEN] + encryptedPayload := ret[5+HEADER_LEN:] + // header: [StreamID 4 bytes][Seq 4 bytes][Closing 1 byte][random 3 bytes] - header := make([]byte, headerLen) putU32(header[0:4], f.StreamID) putU32(header[4:8], f.Seq) header[8] = f.Closing rand.Read(header[9:12]) - encryptedPayload, err := algo.encrypt(f.Payload, header) + ciphertext, err := algo.encrypt(f.Payload, header) if err != nil { return nil, err } + copy(encryptedPayload, ciphertext) cKey := make([]byte, len(key)) copy(cKey, key) @@ -49,23 +54,18 @@ func MakeObfs(key []byte, algo Crypto) Obfser { // Composing final obfsed message // We don't use util.AddRecordLayer here to avoid unnecessary malloc - // TODO: allocate this in the beginning and do everything in place - obfsed := make([]byte, 5+headerLen+len(encryptedPayload)) - obfsed[0] = 0x17 - obfsed[1] = 0x03 - obfsed[2] = 0x03 - binary.BigEndian.PutUint16(obfsed[3:5], uint16(headerLen+len(encryptedPayload))) - copy(obfsed[5:5+headerLen], header) - copy(obfsed[5+headerLen:], encryptedPayload) - // obfsed: [record layer 5 bytes][obfsedheader 12 bytes][payload] - return obfsed, nil + recordLayer[0] = 0x17 + recordLayer[1] = 0x03 + recordLayer[2] = 0x03 + binary.BigEndian.PutUint16(recordLayer[3:5], uint16(HEADER_LEN+len(encryptedPayload))) + return ret, nil } return obfs } func MakeDeobfs(key []byte, algo Crypto) Deobfser { deobfs := func(in []byte) (*Frame, error) { - if len(in) < 5+headerLen+16 { + if len(in) < 5+HEADER_LEN+16 { return nil, errors.New("Input cannot be shorter than 33 bytes") } peeled := in[5:]