enigma

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Jan 21, 2023 License: Apache-2.0 Imports: 24 Imported by: 0

README

Enigma: a simple encrypted filesystem

Enigma is a simple encrypted filesystem that adds a thin layer of encryption over native filesystem and keeps your most sensitive secrets.

Roadmap

Methods of Encryption

Both the file names and data will be encrypted by an AES-256 key in CTR mode, which takes trillions of years for the attackers to crack, owing to the miracles of cryptology.

Encrypting in CTR mode enables the filesystem to random access the stored content, without bloating the file size. Many CPUs support hardware accelerating computation of AES-256 block. This is crucial for implementing a fast, efficient and low overhead file system.

The nonce, which is required by CTR mode to encrypt file names and data, is generated regarding the path relative to root in filesystem. Walking down the path to the final component of file name, we compute the SHA256 hash of its parent's hash concatenating current visited component. The hash of / is the SHA256 digest of the key.

Since all information to calculate the nonce is contained inside the file or directory's path we are going to visit naturally, we don't need to spend any extra space to store the nonce.

Under the same directory, encrypting file names with the same nonce directly is prone to chosen-plaintext attack. To mitigate, we generate a short extra nonce for each file name, which is computed from the cryptological digest. Then the nonce for the file name is computed from the digest of the directory it is in, plus the short extra nonce and the file's length. After being encrypted, the file name is encoded in Base64 as it is usually in invalid ASCII or Unicode.

For resisting birthday attack, the default extra nonce size is 3 bytes, which yields a birthday bound of about Q(H) = 46819.7 files and low possibility bound of about n(H;0.25%) = 2813.6 files [^2], and is considered providing enough security under most circumstances.

The AES-256 key for encrypting the file system, is randomly generated through a cryptologically secure random process, then encrypted and authenticated by a root key supports AEAD. This extra indirection enables us to check whether proper key is specified, and enables online decryption to protect the root key, without sacrificing the performance.

License

The project is licensed under Apache-2.0. Anyone is free to modify and redistribute the code, however they must swear the oath of keeping users' data and secrets sacred and depicts what they have modified for users' judgement.

[^1]: Storing your key as regular files on the disk directly can be a security issue if your physical machine has been invaded. It's not so risky if the key is transfered over TTY, pipe, socket, etc. [^2]: Assume native file system supports file name of maximum 128 bytes, there're (128-1) * 6 / 8 - 1 = 94.25 cases of file names' length. The number of outputs for file names' nonces is H = 94.25 * (2^24) = 1581252608.0.

Documentation

Overview

Package enigma implements the simple encrypted filesystem.

The filesystem is specified a block cipher which is used to encrypt the subcipher of the filesystem. The subcipher is then used to encrypt the file names and data. The path of each file is taken into consideration while generating nonce.

Thanks to the CTR mode, the size of each files is the same size as their plain text one, and supports random access.

For nonce generation, a crypto random nonce will be generated for encrypting the cipher, while file names will have their corresponding nonce generated in a deterministic process. The file will be encrypted by their file names, which means each file must be re-encrypted when it is renamed.

Index

Constants

View Source
const (
	// CurrentVersion is the version of filesystem config.
	//
	// This field should be increment by one every time we
	// modify the layout of protobuf. The field is also used
	// to detect whether we support the specified filesystem.
	CurrentVersion = 1
)

Variables

This section is empty.

Functions

func Init

func Init(
	inner afero.Fs, rootKey cipher.AEAD, path string,
	userConfig Config,
) error

Init initializes the root filesystem under the path, marking current directory as the root.

The specified directory must exist, and there's no current pre-existing subcipher under the path.

Types

type Config

type Config = proto.Config

Config is the backward compatible filesystem config.

type Fs

type Fs struct {
	// contains filtered or unexported fields
}

Fs implements the filesystem of enigma.

func New

func New(
	inner afero.Fs, rootKey cipher.AEAD, path string,
	options ...Option,
) (*Fs, error)

New the filesystem at specified path.

The specified filesystem must have been initialized by the Init function above, and generated with the same key as the specified one.

The root key is just used for decrypting the subcipher and no longer required after the filesystem is initialized.

func (*Fs) Chmod

func (efs *Fs) Chmod(name string, mode os.FileMode) error

func (*Fs) Chown

func (efs *Fs) Chown(name string, uid, gid int) error

func (*Fs) Chtimes

func (efs *Fs) Chtimes(name string, atime, mtime time.Time) error

func (*Fs) Close

func (efs *Fs) Close()

Close the file system, removing locks and temporary files.

func (*Fs) Create

func (efs *Fs) Create(name string) (afero.File, error)

func (*Fs) Merge

func (efs *Fs) Merge(src, dst string) error

func (*Fs) Mkdir

func (efs *Fs) Mkdir(name string, perm os.FileMode) error

func (*Fs) MkdirAll

func (efs *Fs) MkdirAll(name string, perm os.FileMode) error

func (*Fs) Name

func (*Fs) Name() string

func (*Fs) Open

func (efs *Fs) Open(name string) (afero.File, error)

func (*Fs) OpenFile

func (efs *Fs) OpenFile(
	name string, flag int, perm os.FileMode,
) (afero.File, error)

func (*Fs) Remove

func (efs *Fs) Remove(name string) error

func (*Fs) RemoveAll

func (efs *Fs) RemoveAll(name string) error

func (*Fs) Rename

func (efs *Fs) Rename(src, dst string) error

func (*Fs) Stat

func (efs *Fs) Stat(name string) (os.FileInfo, error)

type Option

type Option func(*option)

Option specified extra parameters for creating filesystem.

func WithCacheSize

func WithCacheSize(size int) Option

WithCacheSize sets the cache size of the internal LRU cache.

func WithOptions

func WithOptions(options ...Option) Option

WithOptions specifies a set of options as a single option.

func WithReadWrite

func WithReadWrite(rw bool) Option

WithReadWrite implies the file system is read write mode.

The file system fails to initialize when there's another process on the same machine or remote file system has already claimed it.

The user can find out who is claiming it and restore it to normal state if they are sure this is unexpected.

func WithWriterName

func WithWriterName(name string) Option

WithWriterName sets the instance name of the writer when it will be run in writer mode.

Adding this flag will replace the original writer name and is more semantic when the process is managed by us.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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