crypto

package
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Aug 23, 2018 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package crypto manages all the cryptography for fscrypt. This includes:

  • Key management (key.go)
  • Securely holding keys in memory
  • Making recovery keys
  • Randomness (rand.go)
  • Cryptographic algorithms (crypto.go)
  • encryption (AES256-CTR)
  • authentication (SHA256-based HMAC)
  • key stretching (SHA256-based HKDF)
  • key wrapping/unwrapping (Encrypt then MAC)
  • passphrase-based key derivation (Argon2id)
  • descriptor computation (double SHA512)

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrBadAuth        = errors.New("key authentication check failed")
	ErrNegitiveLength = errors.New("keys cannot have negative lengths")
	ErrRecoveryCode   = errors.New("invalid recovery code")
	ErrGetrandomFail  = util.SystemError("getrandom() failed")
	ErrKeyAlloc       = util.SystemError("could not allocate memory for key")
	ErrKeyFree        = util.SystemError("could not free memory of key")
	ErrKeyLock        = errors.New("could not lock key in memory")
)

Crypto error values

View Source
var (

	// RecoveryCodeLength is the number of bytes in every recovery code
	RecoveryCodeLength = (encodedLength/blockSize)*(blockSize+len(separator)) - len(separator)
)
View Source
var UseMlock = true

UseMlock determines whether we should use the mlock/munlock syscalls to prevent sensitive data like keys and passphrases from being paged to disk. UseMlock defaults to true, but can be set to false if the application calling into this library has insufficient privileges to lock memory. Code using this package could also bind this setting to a flag by using:

flag.BoolVar(&crypto.UseMlock, "lock-memory", true, "lock keys in memory")

Functions

func ComputeDescriptor

func ComputeDescriptor(key *Key) string

ComputeDescriptor computes the descriptor for a given cryptographic key. In keeping with the process used in e4crypt, this uses the initial bytes (formatted as hexadecimal) of the double application of SHA512 on the key.

func InsertPolicyKey

func InsertPolicyKey(key *Key, description string, target *user.User) error

InsertPolicyKey puts the provided policy key into the kernel keyring with the provided description, and type logon. The key must be a policy key.

func NewRandomBuffer

func NewRandomBuffer(length int) ([]byte, error)

NewRandomBuffer uses the Linux Getrandom() syscall to create random bytes. If the operating system has insufficient randomness, the buffer creation will fail. This is an improvement over Go's built-in crypto/rand which will still return bytes if the system has insufficiency entropy.

See: https://github.com/golang/go/issues/19274

While this syscall was only introduced in Kernel v3.17, it predates the introduction of filesystem encryption, so it introduces no additional compatibility issues.

func Wrap

func Wrap(wrappingKey, secretKey *Key) (*metadata.WrappedKeyData, error)

Wrap takes a wrapping Key of length InternalKeyLen, and uses it to wrap a secret Key of any length. This wrapping uses a random IV, the encrypted data, and an HMAC to verify the wrapping key was correct. All of this is included in the returned WrappedKeyData structure.

func WriteRecoveryCode

func WriteRecoveryCode(key *Key, writer io.Writer) error

WriteRecoveryCode outputs key's recovery code to the provided writer. WARNING: This recovery key is enough to derive the original key, so it must be given the same level of protection as a raw cryptographic key.

Types

type Key

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

Key protects some arbitrary buffer of cryptographic material. Its methods ensure that the Key's data is locked in memory before being used (if UseMlock is set to true), and is wiped and unlocked after use (via the Wipe() method). This data is never accessed outside of the fscrypt/crypto package (except for the UnsafeData method). If a key is successfully created, the Wipe() method should be called after it's use. For example:

func UseKeyFromStdin() error {
	key, err := NewKeyFromReader(os.Stdin)
	if err != nil {
		return err
	}
	defer key.Wipe()

	// Do stuff with key

	return nil
}

The Wipe() method will also be called when a key is garbage collected; however, it is best practice to clear the key as soon as possible, so it spends a minimal amount of time in memory.

Note that Key is not thread safe, as a key could be wiped while another thread is using it. Also, calling Wipe() from two threads could cause an error as memory could be freed twice.

func NewFixedLengthKeyFromReader

func NewFixedLengthKeyFromReader(reader io.Reader, length int) (*Key, error)

NewFixedLengthKeyFromReader constructs a key with a specified length by reading exactly length bytes from reader.

func NewKeyFromCString added in v0.2.0

func NewKeyFromCString(str unsafe.Pointer) (*Key, error)

NewKeyFromCString creates of a copy of some C string's data in a key. Note that the original C string is not modified at all, so steps must be taken to ensure that this original copy is secured.

func NewKeyFromReader

func NewKeyFromReader(reader io.Reader) (*Key, error)

NewKeyFromReader constructs a key of abritary length by reading from reader until hitting EOF.

func NewRandomKey

func NewRandomKey(length int) (*Key, error)

NewRandomKey creates a random key of the specified length. This function uses the same random number generation process a NewRandomBuffer.

func PassphraseHash

func PassphraseHash(passphrase *Key, salt []byte, costs *metadata.HashingCosts) (*Key, error)

PassphraseHash uses Argon2id to produce a Key given the passphrase, salt, and hashing costs. This method is designed to take a long time and consume considerable memory. For more information, see the documentation at https://godoc.org/golang.org/x/crypto/argon2.

func ReadRecoveryCode

func ReadRecoveryCode(reader io.Reader) (*Key, error)

ReadRecoveryCode gets the recovery code from the provided writer and returns the corresponding cryptographic key. WARNING: This recovery key is enough to derive the original key, so it must be given the same level of protection as a raw cryptographic key.

func Unwrap

func Unwrap(wrappingKey *Key, data *metadata.WrappedKeyData) (*Key, error)

Unwrap takes a wrapping Key of length KeyLen, and uses it to unwrap the WrappedKeyData to get the unwrapped secret Key. The Wrapped Key data includes an authentication check, so an error will be returned if that check fails.

func (*Key) Equals

func (key *Key) Equals(key2 *Key) bool

Equals compares the contents of two keys, returning true if they have the same key data. This function runs in constant time.

func (*Key) Len

func (key *Key) Len() int

Len is the underlying data buffer's length.

func (*Key) UnsafeToCString added in v0.2.0

func (key *Key) UnsafeToCString() unsafe.Pointer

UnsafeToCString makes a copy of the string's data into a null-terminated C string allocated by C. Note that this method is unsafe as this C copy has no locking or wiping functionality. The key shouldn't contain any `\0` bytes.

func (*Key) Wipe

func (key *Key) Wipe() error

Wipe destroys a Key by zeroing and freeing the memory. The data is zeroed even if Wipe returns an error, which occurs if we are unable to unlock or free the key memory. Wipe does nothing if the key is already wiped or is nil.

Jump to

Keyboard shortcuts

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