linux/fs/crypto
Eric Biggers 23c688b540 fscrypt: allow unprivileged users to add/remove keys for v2 policies
Allow the FS_IOC_ADD_ENCRYPTION_KEY and FS_IOC_REMOVE_ENCRYPTION_KEY
ioctls to be used by non-root users to add and remove encryption keys
from the filesystem-level crypto keyrings, subject to limitations.

Motivation: while privileged fscrypt key management is sufficient for
some users (e.g. Android and Chromium OS, where a privileged process
manages all keys), the old API by design also allows non-root users to
set up and use encrypted directories, and we don't want to regress on
that.  Especially, we don't want to force users to continue using the
old API, running into the visibility mismatch between files and keyrings
and being unable to "lock" encrypted directories.

Intuitively, the ioctls have to be privileged since they manipulate
filesystem-level state.  However, it's actually safe to make them
unprivileged if we very carefully enforce some specific limitations.

First, each key must be identified by a cryptographic hash so that a
user can't add the wrong key for another user's files.  For v2
encryption policies, we use the key_identifier for this.  v1 policies
don't have this, so managing keys for them remains privileged.

Second, each key a user adds is charged to their quota for the keyrings
service.  Thus, a user can't exhaust memory by adding a huge number of
keys.  By default each non-root user is allowed up to 200 keys; this can
be changed using the existing sysctl 'kernel.keys.maxkeys'.

Third, if multiple users add the same key, we keep track of those users
of the key (of which there remains a single copy), and won't really
remove the key, i.e. "lock" the encrypted files, until all those users
have removed it.  This prevents denial of service attacks that would be
possible under simpler schemes, such allowing the first user who added a
key to remove it -- since that could be a malicious user who has
compromised the key.  Of course, encryption keys should be kept secret,
but the idea is that using encryption should never be *less* secure than
not using encryption, even if your key was compromised.

We tolerate that a user will be unable to really remove a key, i.e.
unable to "lock" their encrypted files, if another user has added the
same key.  But in a sense, this is actually a good thing because it will
avoid providing a false notion of security where a key appears to have
been removed when actually it's still in memory, available to any
attacker who compromises the operating system kernel.

Reviewed-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Eric Biggers <ebiggers@google.com>
2019-08-12 19:18:50 -07:00
..
bio.c fscrypt: decrypt only the needed blocks in __fscrypt_decrypt_bio() 2019-05-28 10:27:53 -07:00
crypto.c fscrypt: v2 encryption policy support 2019-08-12 19:18:50 -07:00
fname.c fscrypt: v2 encryption policy support 2019-08-12 19:18:50 -07:00
fscrypt_private.h fscrypt: allow unprivileged users to add/remove keys for v2 policies 2019-08-12 19:18:50 -07:00
hkdf.c fscrypt: add an HKDF-SHA512 implementation 2019-08-12 19:18:50 -07:00
hooks.c fscrypt: make fscrypt_msg() take inode instead of super_block 2019-08-12 19:04:44 -07:00
Kconfig fscrypt: add an HKDF-SHA512 implementation 2019-08-12 19:18:50 -07:00
keyring.c fscrypt: allow unprivileged users to add/remove keys for v2 policies 2019-08-12 19:18:50 -07:00
keysetup_v1.c fscrypt: v2 encryption policy support 2019-08-12 19:18:50 -07:00
keysetup.c fscrypt: allow unprivileged users to add/remove keys for v2 policies 2019-08-12 19:18:50 -07:00
Makefile fscrypt: add an HKDF-SHA512 implementation 2019-08-12 19:18:50 -07:00
policy.c fscrypt: v2 encryption policy support 2019-08-12 19:18:50 -07:00