|  | @@ -103,6 +103,8 @@ type Cipher interface {
 | 
											
												
													
														|  |  	NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error)
 |  |  	NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error)
 | 
											
												
													
														|  |  	NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error)
 |  |  	NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error)
 | 
											
												
													
														|  |  	IsAEAD() bool
 |  |  	IsAEAD() bool
 | 
											
												
													
														|  | 
 |  | +	EncodePacket(key []byte, b *buf.Buffer) error
 | 
											
												
													
														|  | 
 |  | +	DecodePacket(key []byte, b *buf.Buffer) error
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  type AesCfb struct {
 |  |  type AesCfb struct {
 | 
											
										
											
												
													
														|  | @@ -131,6 +133,21 @@ func (v *AesCfb) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (b
 | 
											
												
													
														|  |  	return buf.NewReader(crypto.NewCryptionReader(stream, reader)), nil
 |  |  	return buf.NewReader(crypto.NewCryptionReader(stream, reader)), nil
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +func (v *AesCfb) EncodePacket(key []byte, b *buf.Buffer) error {
 | 
											
												
													
														|  | 
 |  | +	iv := b.BytesTo(v.IVSize())
 | 
											
												
													
														|  | 
 |  | +	stream := crypto.NewAesEncryptionStream(key, iv)
 | 
											
												
													
														|  | 
 |  | +	stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize()))
 | 
											
												
													
														|  | 
 |  | +	return nil
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (v *AesCfb) DecodePacket(key []byte, b *buf.Buffer) error {
 | 
											
												
													
														|  | 
 |  | +	iv := b.BytesTo(v.IVSize())
 | 
											
												
													
														|  | 
 |  | +	stream := crypto.NewAesEncryptionStream(key, iv)
 | 
											
												
													
														|  | 
 |  | +	stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize()))
 | 
											
												
													
														|  | 
 |  | +	b.SliceFrom(v.IVSize())
 | 
											
												
													
														|  | 
 |  | +	return nil
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  type AEADCipher struct {
 |  |  type AEADCipher struct {
 | 
											
												
													
														|  |  	KeyBytes        int
 |  |  	KeyBytes        int
 | 
											
												
													
														|  |  	IVBytes         int
 |  |  	IVBytes         int
 | 
											
										
											
												
													
														|  | @@ -149,32 +166,60 @@ func (c *AEADCipher) IVSize() int {
 | 
											
												
													
														|  |  	return c.IVBytes
 |  |  	return c.IVBytes
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -func (c *AEADCipher) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) {
 |  | 
 | 
											
												
													
														|  | 
 |  | +func (c *AEADCipher) createAuthenticator(key []byte, iv []byte) *crypto.AEADAuthenticator {
 | 
											
												
													
														|  |  	nonce := crypto.NewIncreasingAEADNonceGenerator()
 |  |  	nonce := crypto.NewIncreasingAEADNonceGenerator()
 | 
											
												
													
														|  |  	subkey := make([]byte, c.KeyBytes)
 |  |  	subkey := make([]byte, c.KeyBytes)
 | 
											
												
													
														|  |  	hkdfSHA1(key, iv, subkey)
 |  |  	hkdfSHA1(key, iv, subkey)
 | 
											
												
													
														|  | -	auth := &crypto.AEADAuthenticator{
 |  | 
 | 
											
												
													
														|  | 
 |  | +	return &crypto.AEADAuthenticator{
 | 
											
												
													
														|  |  		AEAD:           c.AEADAuthCreator(subkey),
 |  |  		AEAD:           c.AEADAuthCreator(subkey),
 | 
											
												
													
														|  |  		NonceGenerator: nonce,
 |  |  		NonceGenerator: nonce,
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (c *AEADCipher) NewEncryptionWriter(key []byte, iv []byte, writer io.Writer) (buf.Writer, error) {
 | 
											
												
													
														|  | 
 |  | +	auth := c.createAuthenticator(key, iv)
 | 
											
												
													
														|  |  	return crypto.NewAuthenticationWriter(auth, &crypto.AEADChunkSizeParser{
 |  |  	return crypto.NewAuthenticationWriter(auth, &crypto.AEADChunkSizeParser{
 | 
											
												
													
														|  |  		Auth: auth,
 |  |  		Auth: auth,
 | 
											
												
													
														|  |  	}, writer, protocol.TransferTypeStream), nil
 |  |  	}, writer, protocol.TransferTypeStream), nil
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  func (c *AEADCipher) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) {
 |  |  func (c *AEADCipher) NewDecryptionReader(key []byte, iv []byte, reader io.Reader) (buf.Reader, error) {
 | 
											
												
													
														|  | -	nonce := crypto.NewIncreasingAEADNonceGenerator()
 |  | 
 | 
											
												
													
														|  | -	subkey := make([]byte, c.KeyBytes)
 |  | 
 | 
											
												
													
														|  | -	hkdfSHA1(key, iv, subkey)
 |  | 
 | 
											
												
													
														|  | -	auth := &crypto.AEADAuthenticator{
 |  | 
 | 
											
												
													
														|  | -		AEAD:           c.AEADAuthCreator(subkey),
 |  | 
 | 
											
												
													
														|  | -		NonceGenerator: nonce,
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | 
 |  | +	auth := c.createAuthenticator(key, iv)
 | 
											
												
													
														|  |  	return crypto.NewAuthenticationReader(auth, &crypto.AEADChunkSizeParser{
 |  |  	return crypto.NewAuthenticationReader(auth, &crypto.AEADChunkSizeParser{
 | 
											
												
													
														|  |  		Auth: auth,
 |  |  		Auth: auth,
 | 
											
												
													
														|  |  	}, reader, protocol.TransferTypeStream), nil
 |  |  	}, reader, protocol.TransferTypeStream), nil
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +func (c *AEADCipher) EncodePacket(key []byte, b *buf.Buffer) error {
 | 
											
												
													
														|  | 
 |  | +	ivLen := c.IVSize()
 | 
											
												
													
														|  | 
 |  | +	payloadLen := b.Len()
 | 
											
												
													
														|  | 
 |  | +	auth := c.createAuthenticator(key, b.BytesTo(ivLen))
 | 
											
												
													
														|  | 
 |  | +	return b.Reset(func(bb []byte) (int, error) {
 | 
											
												
													
														|  | 
 |  | +		bbb, err := auth.Seal(bb[:ivLen], bb[ivLen:payloadLen])
 | 
											
												
													
														|  | 
 |  | +		if err != nil {
 | 
											
												
													
														|  | 
 |  | +			return 0, err
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +		return len(bbb), nil
 | 
											
												
													
														|  | 
 |  | +	})
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (c *AEADCipher) DecodePacket(key []byte, b *buf.Buffer) error {
 | 
											
												
													
														|  | 
 |  | +	ivLen := c.IVSize()
 | 
											
												
													
														|  | 
 |  | +	payloadLen := b.Len()
 | 
											
												
													
														|  | 
 |  | +	auth := c.createAuthenticator(key, b.BytesTo(ivLen))
 | 
											
												
													
														|  | 
 |  | +	if err := b.Reset(func(bb []byte) (int, error) {
 | 
											
												
													
														|  | 
 |  | +		bbb, err := auth.Open(bb[:ivLen], bb[ivLen:payloadLen])
 | 
											
												
													
														|  | 
 |  | +		if err != nil {
 | 
											
												
													
														|  | 
 |  | +			return 0, err
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +		return len(bbb), nil
 | 
											
												
													
														|  | 
 |  | +	}); err != nil {
 | 
											
												
													
														|  | 
 |  | +		return err
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  | 
 |  | +	b.SliceFrom(ivLen)
 | 
											
												
													
														|  | 
 |  | +	return nil
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  type ChaCha20 struct {
 |  |  type ChaCha20 struct {
 | 
											
												
													
														|  |  	IVBytes int
 |  |  	IVBytes int
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
										
											
												
													
														|  | @@ -201,6 +246,21 @@ func (v *ChaCha20) NewDecryptionReader(key []byte, iv []byte, reader io.Reader)
 | 
											
												
													
														|  |  	return buf.NewReader(crypto.NewCryptionReader(stream, reader)), nil
 |  |  	return buf.NewReader(crypto.NewCryptionReader(stream, reader)), nil
 | 
											
												
													
														|  |  }
 |  |  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +func (v *ChaCha20) EncodePacket(key []byte, b *buf.Buffer) error {
 | 
											
												
													
														|  | 
 |  | +	iv := b.BytesTo(v.IVSize())
 | 
											
												
													
														|  | 
 |  | +	stream := crypto.NewChaCha20Stream(key, iv)
 | 
											
												
													
														|  | 
 |  | +	stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize()))
 | 
											
												
													
														|  | 
 |  | +	return nil
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (v *ChaCha20) DecodePacket(key []byte, b *buf.Buffer) error {
 | 
											
												
													
														|  | 
 |  | +	iv := b.BytesTo(v.IVSize())
 | 
											
												
													
														|  | 
 |  | +	stream := crypto.NewChaCha20Stream(key, iv)
 | 
											
												
													
														|  | 
 |  | +	stream.XORKeyStream(b.BytesFrom(v.IVSize()), b.BytesFrom(v.IVSize()))
 | 
											
												
													
														|  | 
 |  | +	b.SliceFrom(v.IVSize())
 | 
											
												
													
														|  | 
 |  | +	return nil
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  func PasswordToCipherKey(password string, keySize int) []byte {
 |  |  func PasswordToCipherKey(password string, keySize int) []byte {
 | 
											
												
													
														|  |  	pwdBytes := []byte(password)
 |  |  	pwdBytes := []byte(password)
 | 
											
												
													
														|  |  	key := make([]byte, 0, keySize)
 |  |  	key := make([]byte, 0, keySize)
 |