encrypt

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 19, 2019 License: AGPL-3.0 Imports: 10 Imported by: 6

Documentation

Overview

Package encrypt implements the encryption layer of brig. The file format used looks something like this:

[HEADER][[BLOCKHEADER][PAYLOAD]...]

HEADER is 20+16 bytes big and contains the following fields:

  • 8 Byte: Magic number (to identify non-brig files quickly)
  • 2 Byte: Format version
  • 2 Byte: Used cipher type (ChaCha20 or AES-GCM currently)
  • 4 Byte: Key length in bytes.
  • 4 Byte: Maximum size of each block (last may be less)
  • 16 Byte: MAC protecting the header from forgery

BLOCKHEADER contains the following fields:

  • 8 Byte: Nonce: Derived from the current block number. The block number is checked to be correct on decryption.

PAYLOAD contains the actual encrypted data, which includes a MAC at the end. The size of the MAC depends on the algorithm, for poly1305 it's 16 bytes.

All header metadata is encoded in little endian.

Reader/Writer are capable or reading/writing this format. Additionally, Reader supports efficient seeking into the encrypted data, provided the underlying datastream supports seeking. SEEK_END is only supported when the number of encrypted blocks is present in the header.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrBadBlockSize is returned when the data is damaged and has an invalid block size
	ErrBadBlockSize = errors.New("underlying reader failed to read full w.maxBlockSize")

	// ErrMixedMethods is returned when calling Write() with ReadFrom() together.
	ErrMixedMethods = errors.New("mixing Write() and ReadFrom() is not allowed")
)
View Source
var KeySize = chacha.KeySize

KeySize of the used cipher's key in bytes.

View Source
var (
	// MagicNumber contains the first 8 byte of every brig header.
	// For various reasons, it is the ascii string "moosecat".
	MagicNumber = []byte{
		0x6d, 0x6f, 0x6f, 0x73,
		0x65, 0x63, 0x61, 0x74,
	}
)

Functions

func Decrypt

func Decrypt(key []byte, source io.Reader, dest io.Writer) (int64, error)

Decrypt is a utility function which decrypts the data from source with key and writes the resulting encrypted data to dest.

func Encrypt

func Encrypt(key []byte, source io.Reader, dest io.Writer) (int64, error)

Encrypt is a utility function which encrypts the data from source with key and writes the resulting encrypted data to dest.

func GenerateHeader

func GenerateHeader(key []byte, maxBlockSize int64, cipher uint16) []byte

GenerateHeader creates a valid header for the format file

Types

type HeaderInfo

type HeaderInfo struct {
	// Version of the file format. Currently always 1.
	Version uint16
	// Cipher type used in the file.
	Cipher uint16
	// Keylen is the number of bytes in the encryption key.
	Keylen uint32
	// Blocklen is the max. number of bytes in a block.
	// The last block might be smaller.
	Blocklen uint32
}

HeaderInfo represents a parsed header.

func ParseHeader

func ParseHeader(header, key []byte) (*HeaderInfo, error)

ParseHeader parses the header of the format file. Returns the format version, cipher type, keylength and block length. If parsing fails, an error is returned.

type Reader

type Reader struct {
	// Underlying reader
	io.Reader
	// contains filtered or unexported fields
}

Reader decrypts and encrypted datastream from Reader.

func NewReader

func NewReader(r io.Reader, key []byte) (*Reader, error)

NewReader creates a new encrypted reader and validates the file header. The key is required to be KeySize bytes long.

func (*Reader) Read

func (r *Reader) Read(dest []byte) (int, error)

Read from source and decrypt.

This method always decrypts one block to optimize for continuous reads. If dest is too small to hold the block, the decrypted text is cached for the next read.

func (*Reader) Seek

func (r *Reader) Seek(offset int64, whence int) (int64, error)

Seek into the encrypted stream.

Note that the seek offset is relative to the decrypted data, not to the underlying, encrypted stream.

Mixing SEEK_CUR and SEEK_SET might not a good idea, since a seek might involve reading a whole encrypted block. Therefore relative seek offset

func (*Reader) WriteTo

func (r *Reader) WriteTo(w io.Writer) (int64, error)

WriteTo copies all data from `r` to `w`.

It is intended to avoid unneeded copying by choosing a suitable buffer size and by directly reading block after block. io.Copy will use it automatically.

It returns the number of written bytes and possible errors (but no io.EOF)

type Writer

type Writer struct {
	// Internal Writer we would write to.
	io.Writer
	// contains filtered or unexported fields
}

Writer encrypts the data stream before writing to Writer.

func NewWriter

func NewWriter(w io.Writer, key []byte) (*Writer, error)

NewWriter calls NewWriterWithTypeAndBlockSize with a sane default cipher type and a sane default max block size.

func NewWriterWithType

func NewWriterWithType(w io.Writer, key []byte, cipherType uint16) (*Writer, error)

NewWriterWithType calls NewWriterWithTypeAndBlockSize with a a sane default maxblocksize.

func NewWriterWithTypeAndBlockSize

func NewWriterWithTypeAndBlockSize(w io.Writer, key []byte, cipherType uint16, maxBlockSize int64) (*Writer, error)

NewWriterWithTypeAndBlockSize returns a new Writer which encrypts data with a certain key. If `compressionFlag` is true, the compression flag in the file header will also be true. Otherwise no compression is done.

func (*Writer) Close

func (w *Writer) Close() error

Close the Writer and write any left-over blocks This does not close the underlying data stream.

func (*Writer) GoodDecBufferSize

func (w *Writer) GoodDecBufferSize() int64

GoodDecBufferSize returns a buffer size that is suitable for decryption.

func (*Writer) GoodEncBufferSize

func (w *Writer) GoodEncBufferSize() int64

GoodEncBufferSize returns a buffer size that is suitable for encryption.

func (*Writer) ReadFrom

func (w *Writer) ReadFrom(r io.Reader) (int64, error)

ReadFrom writes all readable from `r` into `w`.

It is intentend as optimized way to copy the whole stream without unneeded copying in between. io.Copy() will use this function automatically.

It returns the number of read bytes and any encountered error (no io.EOF)

func (*Writer) Write

func (w *Writer) Write(p []byte) (int, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL