linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Eric Biggers <ebiggers3@gmail.com>
To: Gwendal Grignou <gwendal@chromium.org>
Cc: tytso@mit.edu, ebiggers@google.com, linux-ext4@vger.kernel.org,
	linux-fscrypt@vger.kernel.org, kinaba@chromium.org,
	hashimoto@chromium.org, linux-f2fs-devel@lists.sourceforge.net,
	linux-mtd@lists.infradead.org
Subject: Re: [PATCH] fscrypt: use 32 bytes of encrypted filename
Date: Tue, 18 Apr 2017 16:01:36 -0700	[thread overview]
Message-ID: <20170418230136.GA96152@gmail.com> (raw)
In-Reply-To: <20170418210642.6039-1-gwendal@chromium.org>

+Cc linux-f2fs-devel@lists.sourceforge.net
+Cc linux-mtd@lists.infradead.org (for ubifs)

Hi Gwendal,

On Tue, Apr 18, 2017 at 02:06:42PM -0700, Gwendal Grignou wrote:
> If we use only 16 bytes, due to how CBC works, if the names have the
> same beginning, their last ciphertext block (16 bytes) may be identical.
> 
> It happens when two file names share the first 16k bytes and both have
> length withn 16 * n + 13 and 16 * n + 16.
> 
> Instead use 32 bytes to build the filenames from encrypted data when
> directory is scrambled.

Just some background for people who may be unfamiliar with what's going on here
(and it may be useful to include some of this in the patch description):

When accessing files without access to the key, userspace needs to operate on a
filename derived from the ciphertext filename, which contains arbitrary bytes. 

But since it's supported to use filenames up to FILENAME_MAX (255 bytes) in
length when using encryption, we can't always base-64 encode the filename, since
that may make it too long.

The way this is solved currently is that for filenames with ciphertext length
greater than 32 bytes, the filesystem provides an 8-byte "cookie" (split into
'hash' and 'minor_hash'), which along with the last 16 bytes of the filename
ciphertext is base-64 encoded into a fixed-length name.  The filesystem returns
this on readdir.  Then, when a lookup is done, the filesystem translates this
info back into a specific directory entry.

Since ext4 directory entries do not contain a hash field, ext4 relies only on
the 16 bytes of ciphertext to distinguish collisions within a directory block.
Unfortunately, this is broken because with the encryption mode used for
filenames (CTS), the ciphertext of the last 16-byte block depends only on the
plaintext up to and including the *second to last* block, not up to the last
block.  This causes long filenames that differ just near the end to collide.

We could fix this by using the second to last block of ciphertext rather than
the last one.  However, using the last *two* blocks as you're proposing should
be fine too.

Of course we could also hash the filename's ciphertext with SHA-256 or
something, but it's nice to take advantage of the encryption mode, and not have
to do yet another hash.

I am not too worried about changing the way encrypted filenames are presented,
since applications are not supposed to rely on this.  (Though we probably should
be doing something to catch broken applications, like encoding the filenames
slightly differently after each reboot...)

Strangely, f2fs and ubifs do not use the bytes from the filename at all when
trying to find a specific directory entry in this case.  So this patch doesn't
really affect them.  This seems unreliable; perhaps we should introduce a
function like "fscrypt_name_matches()" which all the filesystems could call?
Can any of the f2fs and ubifs developers explain why they don't look at any
bytes from the filename?

Anyway, a couple nits on this patch:

> +	oname->len = 1 + digest_encode(
> +			buf,
> +			FS_FNAME_CRYPTO_DIGEST_SIZE + sizeof(u64),
> +			oname->name + 1);
>  	return 0;
>  }

Use 'sizeof(buf)'

>  
> diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
> index c4a389a6027b..14b2a2335a32 100644
> --- a/fs/ext4/namei.c
> +++ b/fs/ext4/namei.c
> @@ -1257,8 +1257,8 @@ static inline int ext4_match(struct ext4_filename *fname,
>  			int ret;

>  			if (de->name_len < 16)
>  				return 0;

de->name_len < 32

(or replace 32 with FS_FNAME_CRYPTO_DIGEST_SIZE, here and below)

- Eric

  reply	other threads:[~2017-04-18 23:01 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-18 21:06 [PATCH] fscrypt: use 32 bytes of encrypted filename Gwendal Grignou
2017-04-18 23:01 ` Eric Biggers [this message]
2017-04-19  0:10   ` Eric Biggers
2017-04-19  1:42     ` [f2fs-dev] " Jaegeuk Kim
2017-04-19  4:01       ` Eric Biggers
2017-04-19 20:44         ` Jaegeuk Kim
2017-04-21  7:44           ` Eric Biggers
2017-04-21 17:21             ` Gwendal Grignou
2017-04-21 18:53               ` [f2fs-dev] " Eric Biggers
2017-04-21 17:35             ` Jaegeuk Kim
2017-04-21 19:26               ` [f2fs-dev] " Eric Biggers
2017-04-19 20:31     ` Gwendal Grignou
2017-04-19 13:40   ` Richard Weinberger
2017-04-19 17:16     ` Eric Biggers
2017-04-19 17:21       ` Richard Weinberger
2017-04-24 21:19         ` Richard Weinberger
2017-04-18 23:37 ` Andreas Dilger
2017-04-19 13:37 ` Richard Weinberger
2017-04-19 13:41   ` Richard Weinberger
2017-04-19 17:09   ` Eric Biggers
2017-04-19 17:12     ` Richard Weinberger
2017-04-20 11:24       ` David Oberhollenzer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170418230136.GA96152@gmail.com \
    --to=ebiggers3@gmail.com \
    --cc=ebiggers@google.com \
    --cc=gwendal@chromium.org \
    --cc=hashimoto@chromium.org \
    --cc=kinaba@chromium.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-fscrypt@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).