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) - key descriptor computation (double SHA512, or HKDF-SHA512)
Index ¶
- Variables
- func ComputeKeyDescriptor(key *Key, policyVersion int64) (string, error)
- func NewRandomBuffer(length int) ([]byte, error)
- func Wrap(wrappingKey, secretKey *Key) (*metadata.WrappedKeyData, error)
- func WriteRecoveryCode(key *Key, writer io.Writer) error
- type Key
- func NewBlankKey(length int) (*Key, error)
- func NewFixedLengthKeyFromReader(reader io.Reader, length int) (*Key, error)
- func NewKeyFromCString(str unsafe.Pointer) (*Key, error)
- func NewKeyFromReader(reader io.Reader) (*Key, error)
- func NewRandomKey(length int) (*Key, error)
- func NewRandomPassphrase(length int) (*Key, error)
- func PassphraseHash(passphrase *Key, salt []byte, costs *metadata.HashingCosts) (*Key, error)
- func ReadRecoveryCode(reader io.Reader) (*Key, error)
- func Unwrap(wrappingKey *Key, data *metadata.WrappedKeyData) (*Key, error)
Constants ¶
This section is empty.
Variables ¶
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
var ( // RecoveryCodeLength is the number of bytes in every recovery code RecoveryCodeLength = (encodedLength/blockSize)*(blockSize+len(separator)) - len(separator) )
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
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 ¶
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.
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
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 ¶
NewFixedLengthKeyFromReader constructs a key with a specified length by reading exactly length bytes from reader.
func NewKeyFromCString ¶ added in v0.2.0
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 ¶
NewKeyFromReader constructs a key of arbitrary length by reading from reader until hitting EOF.
func NewRandomKey ¶
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
NewRandomPassphrase creates a random passphrase of the specified length containing random alphabetic characters.
func PassphraseHash ¶
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 ¶
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) Data ¶ added in v0.2.6
Data returns a slice of the key's underlying data. Note that this may become outdated if the key is resized.
func (*Key) Equals ¶
Equals compares the contents of two keys, returning true if they have the same key data. This function runs in constant time.
func (*Key) UnsafePtr ¶ added in v0.2.6
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
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.