encryption.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package io
  2. import (
  3. "crypto/cipher"
  4. "io"
  5. )
  6. // CryptionReader is a general purpose reader that applies a stream cipher on top of a regular reader.
  7. type CryptionReader struct {
  8. stream cipher.Stream
  9. reader io.Reader
  10. }
  11. // NewCryptionReader creates a new CryptionReader instance from given stream cipher and reader.
  12. func NewCryptionReader(stream cipher.Stream, reader io.Reader) *CryptionReader {
  13. return &CryptionReader{
  14. stream: stream,
  15. reader: reader,
  16. }
  17. }
  18. // Read reads blocks from underlying reader, and crypt it. The content of blocks is modified in place.
  19. func (reader CryptionReader) Read(blocks []byte) (int, error) {
  20. nBytes, err := reader.reader.Read(blocks)
  21. if nBytes > 0 {
  22. reader.stream.XORKeyStream(blocks[:nBytes], blocks[:nBytes])
  23. }
  24. return nBytes, err
  25. }
  26. // Cryption writer is a general purpose of byte stream writer that applies a stream cipher on top of a regular writer.
  27. type CryptionWriter struct {
  28. stream cipher.Stream
  29. writer io.Writer
  30. }
  31. // NewCryptionWriter creates a new CryptionWriter from given stream cipher and writer.
  32. func NewCryptionWriter(stream cipher.Stream, writer io.Writer) *CryptionWriter {
  33. return &CryptionWriter{
  34. stream: stream,
  35. writer: writer,
  36. }
  37. }
  38. // Crypt crypts the content of blocks without writing them into the underlying writer.
  39. func (writer CryptionWriter) Crypt(blocks []byte) {
  40. writer.stream.XORKeyStream(blocks, blocks)
  41. }
  42. // Write crypts the content of blocks in place, and then writes the give blocks to underlying writer.
  43. func (writer CryptionWriter) Write(blocks []byte) (int, error) {
  44. writer.Crypt(blocks)
  45. return writer.writer.Write(blocks)
  46. }