Joe Richey [Fri, 3 Mar 2017 01:32:50 +0000 (17:32 -0800)]
crypto: passphrase hashing with Argon2
This commit adds in the PassphraseHash function which hashes the
provided passphrase (in key form) using Argon2id. This cost parameters
for Argon2id and that salt are both fed into the function. It also
includes tests and benchmarks for the passphrase hashing.
Joe Richey [Thu, 2 Mar 2017 22:01:20 +0000 (14:01 -0800)]
crypto: reading and writing recovery keys
This commit adds in the concept of recovery codes: human-readable
strings that contain the necessary information to rederive a
cryptographic key. These keys look like:
73PZBXVP-DKJX7SKV-NNTFIC7A-QEGRPZUX-4K5ORRH2-MTKMKP3B-HFCA====
They are input or output directly to a io.Reader or io.Writer
respectively. This prevents the data from passing through unsecured
memory before it gets to its destination. Of course, if the provided
io.Reader or io.Writer is insecure, there is nothing we can do. In most
cases the provided io.Reader or io.Writer will be stdin or stdout. In
some rare cases you might want to pipe the output to another key.
This commit also adds tests and benchmarks for encoding/decoding
recovery codes. It also tests that encoding/decoding will fail in the
correct situations. A benchmark is also added to measure the effect of
locking the keys in memory.
Joe Richey [Thu, 2 Mar 2017 19:58:07 +0000 (11:58 -0800)]
crypto: secure key wrapping/unwrapping
This commit adds in the ability to use the WrappedKeyData from the
metadata package to wrap and unwrap cryptographic keys of any length.
This makes use of several cryptographic primitives:
- Unsalted, SHA256-based HKDF for key stretching
- AES256 in CTR mode for encryption
- SHA256-based HMAC for authentication
Note that the key wrapping/unwrapping uses an "Encrypt then MAC" scheme
for doing authenticated unwrapping. This means we can detect if bogus
metadata has been given. This package also standardizes the length for
fscrypt's internal keys.
This CL is the first to add benchmarks, which can be run with:
go test -bench=. ./...
This commit adds in the golang.org/x/crypto/hkdf package which contains
the HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as
defined in RFC 5869.
This package will be used later in the crypto package to stretch a
single cryptographic key into multiple keys.
Joe Richey [Thu, 2 Mar 2017 19:58:07 +0000 (11:58 -0800)]
crypto: add secure random reader using getrandom
This commit adds in RandReader, a cryptographically secure io.Reader
that will fail when the os has insufficient randomness. This is done
using the getrandom() syscall in non-blocking mode.
see: http://man7.org/linux/man-pages/man2/getrandom.2.html
Any kernel new enough to have filesystem encryption will also have this
syscall.
This RandReader is preferable to the one provided by the standard
library in crypto/rand. See the bugs:
https://github.com/golang/go/issues/11833
https://github.com/golang/go/issues/19274
This will be removed when go updates the crypto/rand implementation.
Joe Richey [Thu, 2 Mar 2017 19:47:07 +0000 (11:47 -0800)]
crypto: insert key into keyring from go
This commit adds in the ability to insert Keys into the kernel keyring
from go code. This is done via a patched version of x/sys/unix. We
also expose the specific requirements for keys that will be placed in
the keyring, namely PolicyKeyLen. The legacy services are also exposed.
Joe Richey [Thu, 2 Mar 2017 19:22:43 +0000 (11:22 -0800)]
crypto: Key struct for secure buffers
This commit adds in the crypto package, which will hold all
of the security primitives for fscrypt. This first component deals with
securely handling keys in memory. To do this in a consistent way across
fscrypt, we introduce the Key struct.
Any sensitive memory (like keys, passwords, or recovery tokens) in
fscrypt will be held in a Key. No code outside of the crypto package
should access the Key's data directly. Convenience functions and methods
are provided to construct keys from io.Readers (either with fixed length
or with variable length) and to access information about the Keys.
The most important property of Keys is that the data is locked in memory
on construction, and the data is unlocked and wiped when Wipe is called.
This happens either by something like "defer key.Wipe()" or through the
finalizer.
Joe Richey [Thu, 2 Mar 2017 18:38:33 +0000 (10:38 -0800)]
metadata: get and set policies from go
This commit adds in the ability to get and set policy data from go using
the GetPolicy and SetPolicy functions. This is done via a patch of the
x/sys/unix package that exposes the filesystem encryption structures.
Note that not all the fields of the PolicyData protocol buffer are
needed to get and set policies. The wrapped_policy_keys are not used and
will be written and read by other components of fscrypt.
To run the policy tests, the environment variable BASE_TEST_DIR must be
set to a directory for testing on a filesystem that supports encryption.
This commit adds in the golang.org/x/sys/unix package. This package
provides a low-level interface to unix syscalls. We will uses this
package instead of the built-in "syscall" package because the syscall
package is locked down (https://golang.org/pkg/syscall) and is not
exposing any new kernel functionality.
In fact, this is actually a patched version of the x/sys/unix package
pending review (first part: https://go-review.googlesource.com/c/37943).
The version included in this commit exposes all of the filesystem
encryption kernel interfaces to Go code.
Joe Richey [Thu, 2 Mar 2017 18:15:23 +0000 (10:15 -0800)]
metadata: introduce protobuf structures
This commit adds in the metadata package. The primary purpose of this
package is to provide the on-disk metadata structures in the form of
protocol buffers. This includes:
- Policy metadata structure
- Protector metadata structure
- Config file structure
- All necessary sub-structures (wrapped keys, parameters, etc)
This commit also adds in an example usage of the Config structure, which
represents the structure of the global config file. All the package
does at this point is convert between the Config structure and a JSON
representation.
Here we introduce govendor, which is described more in the README. This
means we will have all of our Go dependencies in the vendor
subdirectory. This means we will have no Go source dependencies, only
dependencies on the build tools (Go and govendor). The README describes
this in detail.
Note that we commit the generated files.
see: https://blog.golang.org/generate
This commit adds in the two protocol buffer libraries for Go. The
github.com/golang/protobuf/proto package will let Go code read and write
protocol buffers. The github.com/golang/protobuf/jsonpb package lets Go
code output a JSON representation of protocol buffers.
These packages are stored in the vendor directory, meaning that they
will be imported instead of any installed system packages.
Joe Richey [Thu, 2 Mar 2017 00:57:27 +0000 (16:57 -0800)]
util: convenience utilities for fscrypt
This commit adds in the util package. This package provides
two functions for creating errors. These functions are:
- InvalidInputErrorF - bad input from user or caller
- SystemErrorF - low level failure
It also adds in a small function for converting Go byte slices into C
void pointers. This will be very useful for interoperating with C.
Joe Richey [Fri, 31 Mar 2017 17:14:20 +0000 (10:14 -0700)]
cmd/fscrypt: Initial stub program and docs
This commit adds in a stub fscrypt program. The binary just tells the
time and the tests do nothing, but the Makefile will build them! This
commit also adds documentation to the README that explains how to get,
build, run, test, format, lint, and install the code.
Also note that the executable is now in the cmd/fscrypt directory. The
library implementing the core functionality will be at the root. This
is essentially point 2 of https://medium.com/@benbjohnson/structuring-applications-in-go-3b04be4ff091
Joe Richey [Thu, 30 Mar 2017 21:39:09 +0000 (14:39 -0700)]
Initial Documentation for fscrypt
This commit includes the Apache 2.0 License and a README with
documentation on how to checkout the code, some context about Linux
filesystem encryption, and documentation stubs for fscrypt and
fscryptctl. Also adds in a simple .gitignore so we don't commit build
files.