diff options
author | Jakob Unterwurzacher | 2015-11-01 01:32:33 +0100 |
---|---|---|
committer | Jakob Unterwurzacher | 2015-11-01 01:38:27 +0100 |
commit | 76311b60f2e208dbd93e1e7b6e9794770c14fede (patch) | |
tree | fa71d48744fd1ad6de26aaadd03f2440e4d4103d /cryptfs/file_header.go | |
parent | 73fa8efdb27172210b9751eb86689287db0b1170 (diff) |
Add file header (on-disk-format change)
Format: [ "Version" uint16 big endian ] [ "Id" 16 random bytes ]
Quoting SECURITY.md:
* Every file has a header that contains a 16-byte random *file id*
* Each block uses the file id and its block number as GCM *authentication data*
* This means the position of the blocks is protected as well. The blocks
can not be reordered or copied between different files without
causing an decryption error.
Diffstat (limited to 'cryptfs/file_header.go')
-rw-r--r-- | cryptfs/file_header.go | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/cryptfs/file_header.go b/cryptfs/file_header.go new file mode 100644 index 0000000..3fd7266 --- /dev/null +++ b/cryptfs/file_header.go @@ -0,0 +1,56 @@ +package cryptfs + +// Per-file header +// +// Format: [ "Version" uint16 big endian ] [ "Id" 16 random bytes ] + +import ( + "encoding/binary" + "fmt" +) + +const ( + HEADER_CURRENT_VERSION = 1 // Current on-disk-format version + HEADER_VERSION_LEN = 2 // uint16 + HEADER_ID_LEN = 16 // 128 bit random file id + HEADER_LEN = HEADER_VERSION_LEN + HEADER_ID_LEN // Total header length +) + +type FileHeader struct { + Version uint16 + Id []byte +} + +// Pack - serialize fileHeader object +func (h *FileHeader) Pack() []byte { + if len(h.Id) != HEADER_ID_LEN || h.Version != HEADER_CURRENT_VERSION { + panic("FileHeader object not properly initialized") + } + buf := make([]byte, HEADER_LEN) + binary.BigEndian.PutUint16(buf[0:HEADER_VERSION_LEN], h.Version) + copy(buf[HEADER_VERSION_LEN:], h.Id) + return buf + +} + +// ParseHeader - parse "buf" into fileHeader object +func ParseHeader(buf []byte) (*FileHeader, error) { + if len(buf) != HEADER_LEN { + return nil, fmt.Errorf("ParseHeader: invalid length: got %d, want %d", len(buf), HEADER_LEN) + } + var h FileHeader + h.Version = binary.BigEndian.Uint16(buf[0:HEADER_VERSION_LEN]) + if h.Version != HEADER_CURRENT_VERSION { + return nil, fmt.Errorf("ParseHeader: invalid version: got %d, want %d", h.Version, HEADER_CURRENT_VERSION) + } + h.Id = buf[HEADER_VERSION_LEN:] + return &h, nil +} + +// RandomHeader - create new fileHeader object with random Id +func RandomHeader() *FileHeader { + var h FileHeader + h.Version = HEADER_CURRENT_VERSION + h.Id = RandBytes(HEADER_ID_LEN) + return &h +} |