linux/fs/crypto
Daniel Rosenberg edc440e3d2 fscrypt: improve format of no-key names
When an encrypted directory is listed without the key, the filesystem
must show "no-key names" that uniquely identify directory entries, are
at most 255 (NAME_MAX) bytes long, and don't contain '/' or '\0'.
Currently, for short names the no-key name is the base64 encoding of the
ciphertext filename, while for long names it's the base64 encoding of
the ciphertext filename's dirhash and second-to-last 16-byte block.

This format has the following problems:

- Since it doesn't always include the dirhash, it's incompatible with
  directories that will use a secret-keyed dirhash over the plaintext
  filenames.  In this case, the dirhash won't be computable from the
  ciphertext name without the key, so it instead must be retrieved from
  the directory entry and always included in the no-key name.
  Casefolded encrypted directories will use this type of dirhash.

- It's ambiguous: it's possible to craft two filenames that map to the
  same no-key name, since the method used to abbreviate long filenames
  doesn't use a proper cryptographic hash function.

Solve both these problems by switching to a new no-key name format that
is the base64 encoding of a variable-length structure that contains the
dirhash, up to 149 bytes of the ciphertext filename, and (if any bytes
remain) the SHA-256 of the remaining bytes of the ciphertext filename.

This ensures that each no-key name contains everything needed to find
the directory entry again, contains only legal characters, doesn't
exceed NAME_MAX, is unambiguous unless there's a SHA-256 collision, and
that we only take the performance hit of SHA-256 on very long filenames.

Note: this change does *not* address the existing issue where users can
modify the 'dirhash' part of a no-key name and the filesystem may still
accept the name.

Signed-off-by: Daniel Rosenberg <drosen@google.com>
[EB: improved comments and commit message, fixed checking return value
 of base64_decode(), check for SHA-256 error, continue to set disk_name
 for short names to keep matching simpler, and many other cleanups]
Link: https://lore.kernel.org/r/20200120223201.241390-7-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>
2020-01-22 14:50:03 -08:00
..
Kconfig fscrypt: improve format of no-key names 2020-01-22 14:50:03 -08:00
Makefile fscrypt: add an HKDF-SHA512 implementation 2019-08-12 19:18:50 -07:00
bio.c fscrypt: optimize fscrypt_zeroout_range() 2020-01-14 12:50:33 -08:00
crypto.c fscrypt: document gfp_flags for bounce page allocation 2020-01-14 12:51:12 -08:00
fname.c fscrypt: improve format of no-key names 2020-01-22 14:50:03 -08:00
fscrypt_private.h fscrypt: clarify what is meant by a per-file key 2020-01-22 14:49:56 -08:00
hkdf.c fscrypt: constify struct fscrypt_hkdf parameter to fscrypt_hkdf_expand() 2019-12-31 10:33:50 -06:00
hooks.c fscrypt: derive dirhash key for casefolded directories 2020-01-22 14:49:55 -08:00
keyring.c fscrypt: don't print name of busy file when removing key 2020-01-22 14:45:08 -08:00
keysetup.c fscrypt: clarify what is meant by a per-file key 2020-01-22 14:49:56 -08:00
keysetup_v1.c fscrypt: clarify what is meant by a per-file key 2020-01-22 14:49:56 -08:00
policy.c fscrypt: don't allow v1 policies with casefolding 2020-01-22 14:47:15 -08:00