crypto

package
v0.3.5 Latest Latest
Warning

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

Go to latest
Published: Mar 19, 2024 License: Apache-2.0 Imports: 21 Imported by: 4

Documentation

Overview

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

  1. Key management (key.go) - Securely holding keys in memory - Making recovery keys
  2. Randomness (rand.go)
  3. 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) - key descriptor computation (double SHA512, or HKDF-SHA512)

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrBadAuth      = errors.New("key authentication check failed")
	ErrRecoveryCode = errors.New("invalid recovery code")
	ErrMlockUlimit  = 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 ComputeKeyDescriptor added in v0.2.6

func ComputeKeyDescriptor(key *Key, policyVersion int64) (string, error)

ComputeKeyDescriptor computes the descriptor for a given cryptographic key. If policyVersion=1, it uses the first 8 bytes of the double application of SHA512 on the key. Use this for protectors and v1 policy keys. If policyVersion=2, it uses HKDF-SHA512 to compute a key identifier that's compatible with the kernel's key identifiers for v2 policy keys. In both cases, the resulting bytes are formatted as hex.

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 NewBlankKey added in v0.2.6

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

NewBlankKey constructs a blank key of a specified length and returns an error if we are unable to allocate or lock the necessary memory.

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 arbitrary 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 as NewRandomBuffer.

func NewRandomPassphrase added in v0.2.6

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

NewRandomPassphrase creates a random passphrase of the specified length containing random alphabetic characters.

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 reader 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 InternalKeyLen, 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) Clone added in v0.2.6

func (key *Key) Clone() (*Key, error)

Clone creates a key as a copy of another one.

func (*Key) Data added in v0.2.6

func (key *Key) Data() []byte

Data returns a slice of the key's underlying data. Note that this may become outdated if the key is resized.

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) UnsafePtr added in v0.2.6

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

UnsafePtr returns an unsafe pointer to the key's underlying data. Note that this will only be valid as long as the key is not resized.

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