encryption.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package io
  2. import (
  3. "crypto/cipher"
  4. "io"
  5. "github.com/v2ray/v2ray-core/log"
  6. )
  7. // CryptionReader is a general purpose reader that applies
  8. // block cipher on top of a regular reader.
  9. type CryptionReader struct {
  10. stream cipher.Stream
  11. reader io.Reader
  12. }
  13. func NewCryptionReader(stream cipher.Stream, reader io.Reader) *CryptionReader {
  14. return &CryptionReader{
  15. stream: stream,
  16. reader: reader,
  17. }
  18. }
  19. // Read reads blocks from underlying reader, the length of blocks must be
  20. // a multiply of BlockSize()
  21. func (reader CryptionReader) Read(blocks []byte) (int, error) {
  22. nBytes, err := reader.reader.Read(blocks)
  23. if nBytes > 0 {
  24. reader.stream.XORKeyStream(blocks[:nBytes], blocks[:nBytes])
  25. }
  26. if err != nil && err != io.EOF {
  27. log.Error("Error reading blocks: %v", err)
  28. }
  29. return nBytes, err
  30. }
  31. // Cryption writer is a general purpose of byte stream writer that applies
  32. // block cipher on top of a regular writer.
  33. type CryptionWriter struct {
  34. stream cipher.Stream
  35. writer io.Writer
  36. }
  37. func NewCryptionWriter(stream cipher.Stream, writer io.Writer) *CryptionWriter {
  38. return &CryptionWriter{
  39. stream: stream,
  40. writer: writer,
  41. }
  42. }
  43. func (writer CryptionWriter) Crypt(blocks []byte) {
  44. writer.stream.XORKeyStream(blocks, blocks)
  45. }
  46. // Write writes the give blocks to underlying writer. The length of the blocks
  47. // must be a multiply of BlockSize()
  48. func (writer CryptionWriter) Write(blocks []byte) (int, error) {
  49. writer.Crypt(blocks)
  50. return writer.writer.Write(blocks)
  51. }