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 ¶
- Variables
- func ComputeDescriptor(key *Key) string
- func InsertPolicyKey(key *Key, description string, target *user.User) 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 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 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") 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
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 ComputeDescriptor ¶
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 ¶
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 ¶
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 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 abritary 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 a NewRandomBuffer.
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 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 ¶
Equals compares the contents of two keys, returning true if they have the same key data. This function runs in constant time.
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.