encryption.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package io
  2. import (
  3. "crypto/cipher"
  4. "io"
  5. )
  6. // CryptionReader is a general purpose reader that applies
  7. // block cipher on top of a regular reader.
  8. type CryptionReader struct {
  9. mode cipher.BlockMode
  10. reader io.Reader
  11. }
  12. func NewCryptionReader(mode cipher.BlockMode, reader io.Reader) *CryptionReader {
  13. this := new(CryptionReader)
  14. this.mode = mode
  15. this.reader = reader
  16. return this
  17. }
  18. // Read reads blocks from underlying reader, the length of blocks must be
  19. // a multiply of BlockSize()
  20. func (reader CryptionReader) Read(blocks []byte) (int, error) {
  21. nBytes, err := reader.reader.Read(blocks)
  22. if err != nil && err != io.EOF {
  23. return nBytes, err
  24. }
  25. if nBytes < len(blocks) {
  26. for i, _ := range blocks[nBytes:] {
  27. blocks[i] = 0
  28. }
  29. }
  30. reader.mode.CryptBlocks(blocks, blocks)
  31. return nBytes, err
  32. }
  33. func (reader CryptionReader) BlockSize() int {
  34. return reader.mode.BlockSize()
  35. }
  36. // Cryption writer is a general purpose of byte stream writer that applies
  37. // block cipher on top of a regular writer.
  38. type CryptionWriter struct {
  39. mode cipher.BlockMode
  40. writer io.Writer
  41. }
  42. func NewCryptionWriter(mode cipher.BlockMode, writer io.Writer) *CryptionWriter {
  43. this := new(CryptionWriter)
  44. this.mode = mode
  45. this.writer = writer
  46. return this
  47. }
  48. // Write writes the give blocks to underlying writer. The length of the blocks
  49. // must be a multiply of BlockSize()
  50. func (writer CryptionWriter) Write(blocks []byte) (int, error) {
  51. writer.mode.CryptBlocks(blocks, blocks)
  52. return writer.writer.Write(blocks)
  53. }
  54. func (writer CryptionWriter) BlockSize() int {
  55. return writer.mode.BlockSize()
  56. }